summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format24
-rw-r--r--.cmake.conf5
-rw-r--r--CHROMIUM_VERSION4
-rw-r--r--CMakeLists.txt21
-rw-r--r--LICENSE.GPL3-EXCEPT704
-rw-r--r--LICENSE.GPLv3686
-rw-r--r--LICENSE.LGPLv3174
-rw-r--r--LICENSES/BSD-3-Clause.txt9
-rw-r--r--LICENSES/GFDL-1.3-no-invariants-only.txt (renamed from LICENSE.FDL)5
-rw-r--r--LICENSES/GPL-2.0-only.txt (renamed from LICENSE.GPL2)0
-rw-r--r--LICENSES/GPL-3.0-only.txt (renamed from LICENSE.GPL3)0
-rw-r--r--LICENSES/LGPL-3.0-only.txt (renamed from LICENSE.LGPL3)12
-rw-r--r--LICENSES/LicenseRef-Qt-Commercial.txt8
-rw-r--r--LICENSES/Qt-GPL-exception-1.0.txt22
-rw-r--r--cmake/FindGPerf.cmake3
-rw-r--r--cmake/FindGn.cmake11
-rw-r--r--cmake/FindNinja.cmake3
-rw-r--r--cmake/FindNodejs.cmake8
-rw-r--r--cmake/FindPkgConfigHost.cmake3
-rw-r--r--cmake/FindSnappy.cmake3
-rw-r--r--cmake/Functions.cmake755
-rw-r--r--cmake/Gn.cmake27
-rw-r--r--cmake/License.cmake51
-rw-r--r--cmake/SubmoduleUpdate.cmake70
-rw-r--r--coin/module_config.yaml13
-rw-r--r--coin/qt-installer-package-config.json21
-rw-r--r--conanfile.py69
-rw-r--r--config.tests/hostcompiler/hostcompiler.pro9
-rw-r--r--config.tests/hostcompiler/main.cpp34
-rw-r--r--configure.cmake287
-rw-r--r--dependencies.yaml8
-rw-r--r--examples/CMakeLists.txt5
-rw-r--r--examples/pdf/CMakeLists.txt7
-rw-r--r--examples/pdf/multipage/CMakeLists.txt29
-rw-r--r--examples/pdf/multipage/doc/src/multipage.qdoc59
-rw-r--r--examples/pdf/multipage/main.cpp67
-rw-r--r--examples/pdf/multipage/multipage.pro4
-rw-r--r--examples/pdf/multipage/pdfapplication.cpp16
-rw-r--r--examples/pdf/multipage/pdfapplication.h24
-rw-r--r--examples/pdf/multipage/resources/macos/Info.plist29
-rw-r--r--examples/pdf/multipage/resources/multipage.icnsbin0 -> 117648 bytes
-rw-r--r--examples/pdf/multipage/resources/sidebar-collapse-left.svg13
-rw-r--r--examples/pdf/multipage/resources/sidebar-expand-left.svg13
-rw-r--r--examples/pdf/multipage/resources/test.pdfbin80045 -> 76633 bytes
-rw-r--r--examples/pdf/multipage/viewer.qml362
-rw-r--r--examples/pdf/multipage/viewer.qrc4
-rw-r--r--examples/pdf/pdf.pro2
-rw-r--r--examples/pdf/pdfviewer/main.cpp71
-rw-r--r--examples/pdf/singlepage/CMakeLists.txt (renamed from examples/pdf/pdfviewer/CMakeLists.txt)20
-rw-r--r--examples/pdf/singlepage/doc/src/singlepage.qdoc62
-rw-r--r--examples/pdf/singlepage/main.cpp37
-rw-r--r--examples/pdf/singlepage/resources/document-open.svg (renamed from examples/pdf/pdfviewer/resources/document-open.svg)0
-rw-r--r--examples/pdf/singlepage/resources/edit-clear.svg (renamed from examples/pdf/pdfviewer/resources/edit-clear.svg)0
-rw-r--r--examples/pdf/singlepage/resources/edit-copy.svg (renamed from examples/pdf/pdfviewer/resources/edit-copy.svg)0
-rw-r--r--examples/pdf/singlepage/resources/edit-select-all.svg (renamed from examples/pdf/pdfviewer/resources/edit-select-all.svg)0
-rw-r--r--examples/pdf/singlepage/resources/go-down-search.svg (renamed from examples/pdf/pdfviewer/resources/go-down-search.svg)0
-rw-r--r--examples/pdf/singlepage/resources/go-next-view-page.svg (renamed from examples/pdf/pdfviewer/resources/go-next-view-page.svg)0
-rw-r--r--examples/pdf/singlepage/resources/go-previous-view-page.svg (renamed from examples/pdf/pdfviewer/resources/go-previous-view-page.svg)0
-rw-r--r--examples/pdf/singlepage/resources/go-up-search.svg (renamed from examples/pdf/pdfviewer/resources/go-up-search.svg)0
-rw-r--r--examples/pdf/singlepage/resources/rotate-left.svg (renamed from examples/pdf/pdfviewer/resources/rotate-left.svg)0
-rw-r--r--examples/pdf/singlepage/resources/rotate-right.svg (renamed from examples/pdf/pdfviewer/resources/rotate-right.svg)0
-rw-r--r--examples/pdf/singlepage/resources/test.pdf (renamed from examples/pdf/pdfviewer/resources/test.pdf)bin80045 -> 76633 bytes
-rw-r--r--examples/pdf/singlepage/resources/zoom-fit-best.svg (renamed from examples/pdf/pdfviewer/resources/zoom-fit-best.svg)0
-rw-r--r--examples/pdf/singlepage/resources/zoom-fit-width.svg (renamed from examples/pdf/pdfviewer/resources/zoom-fit-width.svg)0
-rw-r--r--examples/pdf/singlepage/resources/zoom-in.svg (renamed from examples/pdf/pdfviewer/resources/zoom-in.svg)0
-rw-r--r--examples/pdf/singlepage/resources/zoom-original.svg (renamed from examples/pdf/pdfviewer/resources/zoom-original.svg)0
-rw-r--r--examples/pdf/singlepage/resources/zoom-out.svg (renamed from examples/pdf/pdfviewer/resources/zoom-out.svg)0
-rw-r--r--examples/pdf/singlepage/singlepage.pro (renamed from examples/pdf/pdfviewer/pdfviewer.pro)2
-rw-r--r--examples/pdf/singlepage/viewer.qml (renamed from examples/pdf/pdfviewer/viewer.qml)145
-rw-r--r--examples/pdf/singlepage/viewer.qrc (renamed from examples/pdf/pdfviewer/viewer.qrc)2
-rw-r--r--examples/pdfwidgets/CMakeLists.txt2
-rw-r--r--examples/pdfwidgets/pdfviewer/CMakeLists.txt38
-rw-r--r--examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc59
-rw-r--r--examples/pdfwidgets/pdfviewer/images/busy.pngbin172 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/document-open.svgzbin0 -> 4276 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/fileopen.pngbin1771 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-down-search.svgzbin0 -> 330 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-next-24.pngbin782 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-next-view-page.svgzbin0 -> 12615 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-next-view.svgzbin0 -> 6360 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-previous-24.pngbin797 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-previous-view-page.svgzbin0 -> 12602 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-previous-view.svgzbin0 -> 6545 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/go-up-search.svgzbin0 -> 241 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-fit-best.svgzbin0 -> 6121 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-fit-width.svgzbin0 -> 6109 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-in-24.pngbin1302 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-in-32.pngbin1873 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-in.svgzbin0 -> 6033 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-original.svgzbin0 -> 5541 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-out-24.pngbin1247 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-out-32.pngbin1749 -> 0 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-out.svgzbin0 -> 5420 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/images/zoom-previous.svgzbin0 -> 5665 bytes
-rw-r--r--examples/pdfwidgets/pdfviewer/main.cpp54
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.cpp177
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.h55
-rw-r--r--examples/pdfwidgets/pdfviewer/mainwindow.ui171
-rw-r--r--examples/pdfwidgets/pdfviewer/pageselector.cpp111
-rw-r--r--examples/pdfwidgets/pdfviewer/pageselector.h72
-rw-r--r--examples/pdfwidgets/pdfviewer/pdfviewer.pro4
-rw-r--r--examples/pdfwidgets/pdfviewer/resources.qrc17
-rw-r--r--examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp46
-rw-r--r--examples/pdfwidgets/pdfviewer/searchresultdelegate.h20
-rw-r--r--examples/pdfwidgets/pdfviewer/zoomselector.cpp43
-rw-r--r--examples/pdfwidgets/pdfviewer/zoomselector.h37
-rw-r--r--examples/webenginequick/CMakeLists.txt13
-rw-r--r--examples/webenginequick/customdialogs/MessageRectangle.qml65
-rw-r--r--examples/webenginequick/customdialogs/SwitchButton.qml70
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.pngbin18549 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.pngbin5064 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-color1.pngbin9729 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-color2.pngbin3952 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-file1.pngbin18540 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-file2.pngbin6773 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-menu.pngbin5484 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.pngbin14845 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.pngbin4764 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.pngbin1617 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/images/customdialogs.pngbin9093 -> 0 bytes
-rw-r--r--examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc333
-rw-r--r--examples/webenginequick/customdialogs/forms/Authentication.qml78
-rw-r--r--examples/webenginequick/customdialogs/forms/ColorCell.qml63
-rw-r--r--examples/webenginequick/customdialogs/forms/ColorPicker.qml78
-rw-r--r--examples/webenginequick/customdialogs/forms/CustomButton.qml108
-rw-r--r--examples/webenginequick/customdialogs/forms/FilePicker.qml91
-rw-r--r--examples/webenginequick/customdialogs/forms/FileRow.qml91
-rw-r--r--examples/webenginequick/customdialogs/forms/JavaScript.qml91
-rw-r--r--examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml156
-rw-r--r--examples/webenginequick/customdialogs/forms/Menu.qml69
-rw-r--r--examples/webenginequick/customdialogs/forms/MenuForm.ui.qml112
-rw-r--r--examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml61
-rw-r--r--examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml86
-rw-r--r--examples/webenginequick/customdialogs/main.cpp79
-rw-r--r--examples/webenginequick/customdialogs/main.qml103
-rw-r--r--examples/webenginequick/customdialogs/server.cpp94
-rw-r--r--examples/webenginequick/customdialogs/server.h76
-rw-r--r--examples/webenginequick/lifecycle/CMakeLists.txt18
-rw-r--r--examples/webenginequick/lifecycle/WebBrowser.qml51
-rw-r--r--examples/webenginequick/lifecycle/WebTab.qml53
-rw-r--r--examples/webenginequick/lifecycle/WebTabBar.qml51
-rw-r--r--examples/webenginequick/lifecycle/WebTabButton.qml51
-rw-r--r--examples/webenginequick/lifecycle/WebTabStack.qml51
-rw-r--r--examples/webenginequick/lifecycle/WebToolButton.qml51
-rw-r--r--examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc32
-rw-r--r--examples/webenginequick/lifecycle/lifecycle.pro1
-rw-r--r--examples/webenginequick/lifecycle/main.cpp55
-rw-r--r--examples/webenginequick/lifecycle/utils.h25
-rw-r--r--examples/webenginequick/minimal/CMakeLists.txt50
-rw-r--r--examples/webenginequick/minimal/doc/src/minimal.qdoc87
-rw-r--r--examples/webenginequick/minimal/main.cpp67
-rw-r--r--examples/webenginequick/minimal/main.qml63
-rw-r--r--examples/webenginequick/quicknanobrowser/ApplicationRoot.qml51
-rw-r--r--examples/webenginequick/quicknanobrowser/BrowserDialog.qml53
-rw-r--r--examples/webenginequick/quicknanobrowser/BrowserWindow.qml206
-rw-r--r--examples/webenginequick/quicknanobrowser/CMakeLists.txt50
-rw-r--r--examples/webenginequick/quicknanobrowser/DownloadView.qml53
-rw-r--r--examples/webenginequick/quicknanobrowser/FindBar.qml67
-rw-r--r--examples/webenginequick/quicknanobrowser/FullScreenNotification.qml51
-rw-r--r--examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist36
-rw-r--r--examples/webenginequick/quicknanobrowser/WebAuthDialog.qml281
-rw-r--r--examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc86
-rw-r--r--examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json18
-rw-r--r--examples/webenginequick/quicknanobrowser/main.cpp99
-rw-r--r--examples/webenginequick/quicknanobrowser/quicknanobrowser.exe.manifest17
-rw-r--r--examples/webenginequick/quicknanobrowser/quicknanobrowser.pro14
-rw-r--r--examples/webenginequick/quicknanobrowser/resources.qrc1
-rw-r--r--examples/webenginequick/quicknanobrowser/utils.h63
-rw-r--r--examples/webenginequick/recipebrowser/CMakeLists.txt143
-rw-r--r--examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpgbin33398 -> 0 bytes
-rw-r--r--examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc233
-rw-r--r--examples/webenginequick/recipebrowser/main.cpp77
-rw-r--r--examples/webenginequick/recipebrowser/recipebrowser.pro21
-rw-r--r--examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json34
-rw-r--r--examples/webenginequick/recipebrowser/resources/pages/assets/custom.css75
-rw-r--r--examples/webenginequick/recipebrowser/resources/pages/assets/custom.js67
-rw-r--r--examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml172
-rw-r--r--examples/webenginequick/recipebrowser/resources/qml/main.qml168
-rw-r--r--examples/webenginequick/recipebrowser/resources/resources.qrc27
-rw-r--r--examples/webenginequick/webengineaction/CMakeLists.txt50
-rw-r--r--examples/webenginequick/webengineaction/doc/images/webengineaction-example.pngbin100266 -> 0 bytes
-rw-r--r--examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc68
-rw-r--r--examples/webenginequick/webengineaction/main.cpp66
-rw-r--r--examples/webenginequick/webenginequick.pro8
-rw-r--r--examples/webenginewidgets/CMakeLists.txt30
-rw-r--r--examples/webenginewidgets/clientcertificate/CMakeLists.txt60
-rw-r--r--examples/webenginewidgets/clientcertificate/client.cpp67
-rw-r--r--examples/webenginewidgets/clientcertificate/client.pro10
-rw-r--r--examples/webenginewidgets/clientcertificate/clientcertificate.pro7
-rw-r--r--examples/webenginewidgets/clientcertificate/doc/images/granted.pngbin0 -> 5031 bytes
-rw-r--r--examples/webenginewidgets/clientcertificate/doc/images/selection.pngbin0 -> 6300 bytes
-rw-r--r--examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc160
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/ca.pem24
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/client.key27
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/client.pem22
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/client.qrc6
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/server.key27
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/server.pem22
-rw-r--r--examples/webenginewidgets/clientcertificate/resources/server.qrc7
-rw-r--r--examples/webenginewidgets/clientcertificate/server.cpp99
-rw-r--r--examples/webenginewidgets/clientcertificate/server.pro11
-rw-r--r--examples/webenginewidgets/contentmanipulation/CMakeLists.txt16
-rw-r--r--examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc29
-rw-r--r--examples/webenginewidgets/contentmanipulation/main.cpp51
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.cpp51
-rw-r--r--examples/webenginewidgets/contentmanipulation/mainwindow.h51
-rw-r--r--examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json18
-rw-r--r--examples/webenginewidgets/cookiebrowser/CMakeLists.txt15
-rw-r--r--examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc29
-rw-r--r--examples/webenginewidgets/cookiebrowser/main.cpp51
-rw-r--r--examples/webenginewidgets/cookiebrowser/mainwindow.cpp67
-rw-r--r--examples/webenginewidgets/cookiebrowser/mainwindow.h55
-rw-r--r--examples/webenginewidgets/html2pdf/CMakeLists.txt15
-rw-r--r--examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc29
-rw-r--r--examples/webenginewidgets/html2pdf/html2pdf.cpp59
-rw-r--r--examples/webenginewidgets/maps/CMakeLists.txt34
-rw-r--r--examples/webenginewidgets/maps/Info.cmake.macos.plist33
-rw-r--r--examples/webenginewidgets/maps/doc/src/maps.qdoc37
-rw-r--r--examples/webenginewidgets/maps/main.cpp51
-rw-r--r--examples/webenginewidgets/maps/mainwindow.cpp51
-rw-r--r--examples/webenginewidgets/maps/mainwindow.h51
-rw-r--r--examples/webenginewidgets/markdowneditor/CMakeLists.txt60
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.pngbin41883 -> 0 bytes
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc183
-rw-r--r--examples/webenginewidgets/markdowneditor/document.cpp59
-rw-r--r--examples/webenginewidgets/markdowneditor/document.h73
-rw-r--r--examples/webenginewidgets/markdowneditor/main.cpp66
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp194
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.h92
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.ui115
-rw-r--r--examples/webenginewidgets/markdowneditor/markdowneditor.pro32
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.cpp64
-rw-r--r--examples/webenginewidgets/markdowneditor/previewpage.h66
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt16
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt19
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css260
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js1514
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json34
-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/markdowneditor.qrc8
-rw-r--r--examples/webenginewidgets/minimal/CMakeLists.txt37
-rw-r--r--examples/webenginewidgets/minimal/doc/images/minimal-example.pngbin89294 -> 0 bytes
-rw-r--r--examples/webenginewidgets/minimal/doc/src/minimal.qdoc79
-rw-r--r--examples/webenginewidgets/minimal/main.cpp75
-rw-r--r--examples/webenginewidgets/notifications/CMakeLists.txt16
-rw-r--r--examples/webenginewidgets/notifications/doc/src/notifications.qdoc29
-rw-r--r--examples/webenginewidgets/notifications/main.cpp51
-rw-r--r--examples/webenginewidgets/notifications/notificationpopup.h51
-rw-r--r--examples/webenginewidgets/printme/CMakeLists.txt18
-rw-r--r--examples/webenginewidgets/printme/data/data.qrc1
-rw-r--r--examples/webenginewidgets/printme/data/icon.svg24
-rw-r--r--examples/webenginewidgets/printme/data/index.html2
-rw-r--r--examples/webenginewidgets/printme/data/style.css104
-rw-r--r--examples/webenginewidgets/printme/doc/images/printme-example.pngbin42074 -> 29055 bytes
-rw-r--r--examples/webenginewidgets/printme/doc/src/printme.qdoc42
-rw-r--r--examples/webenginewidgets/printme/main.cpp51
-rw-r--r--examples/webenginewidgets/printme/printhandler.cpp55
-rw-r--r--examples/webenginewidgets/printme/printhandler.h51
-rw-r--r--examples/webenginewidgets/push-notifications/CMakeLists.txt46
-rw-r--r--examples/webenginewidgets/push-notifications/content/index.html26
-rw-r--r--examples/webenginewidgets/push-notifications/content/ping.js84
-rw-r--r--examples/webenginewidgets/push-notifications/content/style.css29
-rw-r--r--examples/webenginewidgets/push-notifications/content/worker.js7
-rw-r--r--examples/webenginewidgets/push-notifications/data/data.qrc (renamed from examples/webenginewidgets/webui/webui.qrc)2
-rw-r--r--examples/webenginewidgets/push-notifications/data/icon.pngbin0 -> 2252 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/notification.pngbin0 -> 1279 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/permissions.pngbin0 -> 4749 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/push-notifications.pngbin0 -> 10573 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/images/website.pngbin0 -> 7539 bytes
-rw-r--r--examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc203
-rw-r--r--examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel837
-rw-r--r--examples/webenginewidgets/push-notifications/main.cpp41
-rw-r--r--examples/webenginewidgets/push-notifications/notificationpopup.h91
-rw-r--r--examples/webenginewidgets/push-notifications/push-notifications.pro10
-rw-r--r--examples/webenginewidgets/push-notifications/server.js65
-rw-r--r--examples/webenginewidgets/recipebrowser/CMakeLists.txt76
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKDOWN-LICENSE.txt (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKED-LICENSE.txt (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/markdown.css (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/markdown.css)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/marked.js (renamed from examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/marked.js)0
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json34
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/custom.css28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/custom.js13
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/icons/add.svg4
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/icons/edit.svg4
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/icons/remove.svg4
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/icons/stylesheets.svg4
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/icons/view.svg4
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/burger.html (renamed from examples/webenginequick/recipebrowser/resources/pages/burger.html)27
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/cupcakes.html (renamed from examples/webenginequick/recipebrowser/resources/pages/cupcakes.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/burger.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/burger.jpg)bin48882 -> 48882 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/cupcakes.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/cupcakes.jpg)bin38653 -> 38653 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/pasta.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/pasta.jpg)bin42411 -> 42411 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/pizza.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/pizza.jpg)bin49068 -> 49068 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/skewers.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/skewers.jpg)bin49246 -> 49246 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/soup.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/soup.jpg)bin49028 -> 49028 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/images/steak.jpg (renamed from examples/webenginequick/recipebrowser/resources/pages/images/steak.jpg)bin49202 -> 49202 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/pasta.html (renamed from examples/webenginequick/recipebrowser/resources/pages/pasta.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/pizza.html (renamed from examples/webenginequick/recipebrowser/resources/pages/pizza.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/skewers.html (renamed from examples/webenginequick/recipebrowser/resources/pages/skewers.html)27
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/soup.html (renamed from examples/webenginequick/recipebrowser/resources/pages/soup.html)28
-rw-r--r--examples/webenginewidgets/recipebrowser/assets/pages/steak.html (renamed from examples/webenginequick/recipebrowser/resources/pages/steak.html)27
-rw-r--r--examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webpbin0 -> 31140 bytes
-rw-r--r--examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc197
-rw-r--r--examples/webenginewidgets/recipebrowser/document.cpp48
-rw-r--r--examples/webenginewidgets/recipebrowser/document.h36
-rw-r--r--examples/webenginewidgets/recipebrowser/main.cpp18
-rw-r--r--examples/webenginewidgets/recipebrowser/mainwindow.cpp154
-rw-r--r--examples/webenginewidgets/recipebrowser/mainwindow.h44
-rw-r--r--examples/webenginewidgets/recipebrowser/mainwindow.ui116
-rw-r--r--examples/webenginewidgets/recipebrowser/recipebrowser.pro (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.pro)12
-rw-r--r--examples/webenginewidgets/recipebrowser/recipebrowser.qrc27
-rw-r--r--examples/webenginewidgets/recipebrowser/stylesheetdialog.cpp (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.cpp)72
-rw-r--r--examples/webenginewidgets/recipebrowser/stylesheetdialog.h39
-rw-r--r--examples/webenginewidgets/recipebrowser/stylesheetdialog.ui (renamed from examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.ui)12
-rw-r--r--examples/webenginewidgets/simplebrowser/CMakeLists.txt43
-rw-r--r--examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist36
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.cpp68
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.h52
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp131
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.h70
-rw-r--r--examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json18
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc67
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp52
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h53
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadwidget.cpp80
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadwidget.h51
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp67
-rw-r--r--examples/webenginewidgets/simplebrowser/simplebrowser.exe.manifest17
-rw-r--r--examples/webenginewidgets/simplebrowser/simplebrowser.pro14
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.cpp61
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.h53
-rw-r--r--examples/webenginewidgets/simplebrowser/webauthdialog.cpp294
-rw-r--r--examples/webenginewidgets/simplebrowser/webauthdialog.h41
-rw-r--r--examples/webenginewidgets/simplebrowser/webauthdialog.ui151
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.cpp82
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.h55
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.cpp51
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.h53
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.cpp209
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.h71
-rw-r--r--examples/webenginewidgets/spellchecker/CMakeLists.txt18
-rw-r--r--examples/webenginewidgets/spellchecker/data/icon.svg24
-rw-r--r--examples/webenginewidgets/spellchecker/data/index.html47
-rw-r--r--examples/webenginewidgets/spellchecker/data/spellchecker.qrc1
-rw-r--r--examples/webenginewidgets/spellchecker/data/style.css145
-rw-r--r--examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.pngbin15978 -> 28507 bytes
-rw-r--r--examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc29
-rw-r--r--examples/webenginewidgets/spellchecker/main.cpp53
-rw-r--r--examples/webenginewidgets/spellchecker/spellchecker.pro5
-rw-r--r--examples/webenginewidgets/spellchecker/webview.cpp51
-rw-r--r--examples/webenginewidgets/spellchecker/webview.h51
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING1
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json24
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.pngbin1364 -> 0 bytes
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt54
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.pngbin45161 -> 0 bytes
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc68
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/main.cpp65
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp169
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/mainwindow.h87
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/mainwindow.ui133
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc5
-rw-r--r--examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h86
-rw-r--r--examples/webenginewidgets/videoplayer/CMakeLists.txt16
-rw-r--r--examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc29
-rw-r--r--examples/webenginewidgets/videoplayer/fullscreennotification.cpp51
-rw-r--r--examples/webenginewidgets/videoplayer/fullscreennotification.h51
-rw-r--r--examples/webenginewidgets/videoplayer/fullscreenwindow.cpp51
-rw-r--r--examples/webenginewidgets/videoplayer/fullscreenwindow.h51
-rw-r--r--examples/webenginewidgets/videoplayer/main.cpp51
-rw-r--r--examples/webenginewidgets/videoplayer/mainwindow.cpp51
-rw-r--r--examples/webenginewidgets/videoplayer/mainwindow.h51
-rw-r--r--examples/webenginewidgets/webenginewidgets.pro21
-rw-r--r--examples/webenginewidgets/webui/CMakeLists.txt51
-rw-r--r--examples/webenginewidgets/webui/about.html129
-rw-r--r--examples/webenginewidgets/webui/doc/images/webui-example.pngbin28862 -> 0 bytes
-rw-r--r--examples/webenginewidgets/webui/doc/src/webui.qdoc165
-rw-r--r--examples/webenginewidgets/webui/main.cpp81
-rw-r--r--examples/webenginewidgets/webui/webui.pro16
-rw-r--r--examples/webenginewidgets/webui/webuihandler.cpp98
-rw-r--r--examples/webenginewidgets/webui/webuihandler.h70
-rw-r--r--qt_cmdline.cmake3
m---------src/3rdparty0
-rw-r--r--src/CMakeLists.txt67
-rw-r--r--src/core/CMakeLists.txt268
-rw-r--r--src/core/accessibility_activation_observer.cpp53
-rw-r--r--src/core/accessibility_activation_observer.h46
-rw-r--r--src/core/accessibility_tree_formatter_qt.cpp215
-rw-r--r--src/core/api/CMakeLists.txt102
-rw-r--r--src/core/api/Qt6WebEngineCoreDeploySupport.cmake173
-rw-r--r--src/core/api/Qt6WebEngineCoreMacros.cmake25
-rw-r--r--src/core/api/configure.cmake120
-rw-r--r--src/core/api/qt_cmdline.cmake3
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp192
-rw-r--r--src/core/api/qtwebenginecoreglobal.h45
-rw-r--r--src/core/api/qtwebenginecoreglobal_p.h48
-rw-r--r--src/core/api/qwebenginecertificateerror.cpp46
-rw-r--r--src/core/api/qwebenginecertificateerror.h40
-rw-r--r--src/core/api/qwebengineclientcertificateselection.cpp40
-rw-r--r--src/core/api/qwebengineclientcertificateselection.h40
-rw-r--r--src/core/api/qwebengineclientcertificatestore.cpp58
-rw-r--r--src/core/api/qwebengineclientcertificatestore.h40
-rw-r--r--src/core/api/qwebengineclienthints.cpp211
-rw-r--r--src/core/api/qwebengineclienthints.h72
-rw-r--r--src/core/api/qwebenginecontextmenurequest.cpp42
-rw-r--r--src/core/api/qwebenginecontextmenurequest.h40
-rw-r--r--src/core/api/qwebenginecontextmenurequest_p.h40
-rw-r--r--src/core/api/qwebenginecookiestore.cpp44
-rw-r--r--src/core/api/qwebenginecookiestore.h40
-rw-r--r--src/core/api/qwebenginecookiestore_p.h42
-rw-r--r--src/core/api/qwebenginedesktopmediarequest.cpp206
-rw-r--r--src/core/api/qwebenginedesktopmediarequest.h59
-rw-r--r--src/core/api/qwebenginedesktopmediarequest_p.h49
-rw-r--r--src/core/api/qwebenginedownloadrequest.cpp81
-rw-r--r--src/core/api/qwebenginedownloadrequest.h40
-rw-r--r--src/core/api/qwebenginedownloadrequest_p.h71
-rw-r--r--src/core/api/qwebenginefilesystemaccessrequest.cpp126
-rw-r--r--src/core/api/qwebenginefilesystemaccessrequest.h70
-rw-r--r--src/core/api/qwebenginefindtextresult.cpp40
-rw-r--r--src/core/api/qwebenginefindtextresult.h40
-rw-r--r--src/core/api/qwebenginefullscreenrequest.cpp42
-rw-r--r--src/core/api/qwebenginefullscreenrequest.h40
-rw-r--r--src/core/api/qwebengineglobalsettings.cpp125
-rw-r--r--src/core/api/qwebengineglobalsettings.h30
-rw-r--r--src/core/api/qwebengineglobalsettings_p.h44
-rw-r--r--src/core/api/qwebenginehistory.cpp49
-rw-r--r--src/core/api/qwebenginehistory.h42
-rw-r--r--src/core/api/qwebenginehistory_p.h42
-rw-r--r--src/core/api/qwebenginehttprequest.cpp50
-rw-r--r--src/core/api/qwebenginehttprequest.h42
-rw-r--r--src/core/api/qwebengineloadinginfo.cpp69
-rw-r--r--src/core/api/qwebengineloadinginfo.h50
-rw-r--r--src/core/api/qwebenginemessagepumpscheduler.cpp51
-rw-r--r--src/core/api/qwebenginemessagepumpscheduler_p.h45
-rw-r--r--src/core/api/qwebenginenavigationrequest.cpp45
-rw-r--r--src/core/api/qwebenginenavigationrequest.h40
-rw-r--r--src/core/api/qwebenginenewwindowrequest.cpp44
-rw-r--r--src/core/api/qwebenginenewwindowrequest.h40
-rw-r--r--src/core/api/qwebenginenewwindowrequest_p.h40
-rw-r--r--src/core/api/qwebenginenotification.cpp40
-rw-r--r--src/core/api/qwebenginenotification.h40
-rw-r--r--src/core/api/qwebenginepage.cpp588
-rw-r--r--src/core/api/qwebenginepage.h80
-rw-r--r--src/core/api/qwebenginepage_p.h81
-rw-r--r--src/core/api/qwebengineprofile.cpp130
-rw-r--r--src/core/api/qwebengineprofile.h46
-rw-r--r--src/core/api/qwebengineprofile_p.h47
-rw-r--r--src/core/api/qwebenginequotarequest.cpp83
-rw-r--r--src/core/api/qwebenginequotarequest.h58
-rw-r--r--src/core/api/qwebengineregisterprotocolhandlerrequest.cpp44
-rw-r--r--src/core/api/qwebengineregisterprotocolhandlerrequest.h40
-rw-r--r--src/core/api/qwebenginescript.cpp49
-rw-r--r--src/core/api/qwebenginescript.h42
-rw-r--r--src/core/api/qwebenginescriptcollection.cpp46
-rw-r--r--src/core/api/qwebenginescriptcollection.h41
-rw-r--r--src/core/api/qwebenginescriptcollection_p.h42
-rw-r--r--src/core/api/qwebenginesettings.cpp55
-rw-r--r--src/core/api/qwebenginesettings.h54
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp111
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h54
-rw-r--r--src/core/api/qwebengineurlrequestinfo_p.h56
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.cpp11
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.h43
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp73
-rw-r--r--src/core/api/qwebengineurlrequestjob.h43
-rw-r--r--src/core/api/qwebengineurlscheme.cpp61
-rw-r--r--src/core/api/qwebengineurlscheme.h41
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp75
-rw-r--r--src/core/api/qwebengineurlschemehandler.h40
-rw-r--r--src/core/api/qwebenginewebauthuxrequest.cpp427
-rw-r--r--src/core/api/qwebenginewebauthuxrequest.h117
-rw-r--r--src/core/api/qwebenginewebauthuxrequest_p.h43
-rw-r--r--src/core/authentication_dialog_controller.cpp43
-rw-r--r--src/core/authentication_dialog_controller.h42
-rw-r--r--src/core/authentication_dialog_controller_p.h40
-rw-r--r--src/core/authenticator_request_client_delegate_qt.cpp247
-rw-r--r--src/core/authenticator_request_client_delegate_qt.h96
-rw-r--r--src/core/authenticator_request_dialog_controller.cpp302
-rw-r--r--src/core/authenticator_request_dialog_controller.h53
-rw-r--r--src/core/authenticator_request_dialog_controller_p.h78
-rw-r--r--src/core/autofill_client_qt.cpp147
-rw-r--r--src/core/autofill_client_qt.h76
-rw-r--r--src/core/autofill_popup_controller.cpp113
-rw-r--r--src/core/autofill_popup_controller.h62
-rw-r--r--src/core/autofill_popup_controller_p.h40
-rw-r--r--src/core/browser_accessibility_manager_qt.cpp120
-rw-r--r--src/core/browser_accessibility_manager_qt.h64
-rw-r--r--src/core/browser_accessibility_qt.cpp653
-rw-r--r--src/core/browser_accessibility_qt.h150
-rw-r--r--src/core/browser_main_parts_qt.cpp214
-rw-r--r--src/core/browser_main_parts_qt.h64
-rw-r--r--src/core/browser_message_filter_qt.cpp53
-rw-r--r--src/core/browser_message_filter_qt.h44
-rw-r--r--src/core/browsing_data_remover_delegate_qt.cpp47
-rw-r--r--src/core/browsing_data_remover_delegate_qt.h58
-rw-r--r--src/core/build_config_qt.h40
-rw-r--r--src/core/certificate_error_controller.cpp50
-rw-r--r--src/core/certificate_error_controller.h46
-rw-r--r--src/core/chromium_overrides.cpp157
-rw-r--r--src/core/client_cert_select_controller.cpp54
-rw-r--r--src/core/client_cert_select_controller.h42
-rw-r--r--src/core/client_hints.cpp177
-rw-r--r--src/core/client_hints.h102
-rw-r--r--src/core/clipboard_change_observer.h49
-rw-r--r--src/core/clipboard_qt.cpp251
-rw-r--r--src/core/clipboard_qt.h84
-rw-r--r--src/core/clipboard_util_win.cpp29
-rw-r--r--src/core/color_chooser_controller.cpp43
-rw-r--r--src/core/color_chooser_controller.h44
-rw-r--r--src/core/color_chooser_controller_p.h44
-rw-r--r--src/core/color_chooser_qt.cpp46
-rw-r--r--src/core/color_chooser_qt.h48
-rw-r--r--src/core/common/extensions/api/qtwebengine_extensions_features.gni27
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.cpp40
-rw-r--r--src/core/common/extensions/extensions_api_provider_qt.h44
-rw-r--r--src/core/common/extensions/extensions_client_qt.cpp48
-rw-r--r--src/core/common/extensions/extensions_client_qt.h47
-rw-r--r--src/core/common/qt_messages.cpp3
-rw-r--r--src/core/common/qt_messages.h4
-rw-r--r--src/core/compositor/compositor.cpp67
-rw-r--r--src/core/compositor/compositor.h90
-rw-r--r--src/core/compositor/compositor_resource_fence.cpp40
-rw-r--r--src/core/compositor/compositor_resource_fence.h40
-rw-r--r--src/core/compositor/content_gpu_client_qt.cpp49
-rw-r--r--src/core/compositor/content_gpu_client_qt.h50
-rw-r--r--src/core/compositor/display_gl_output_surface.cpp341
-rw-r--r--src/core/compositor/display_gl_output_surface.h149
-rw-r--r--src/core/compositor/display_overrides.cpp152
-rw-r--r--src/core/compositor/display_skia_output_device.cpp148
-rw-r--r--src/core/compositor/display_skia_output_device.h78
-rw-r--r--src/core/compositor/display_software_output_surface.cpp85
-rw-r--r--src/core/compositor/display_software_output_surface.h42
-rw-r--r--src/core/compositor/native_skia_output_device.cpp418
-rw-r--r--src/core/compositor/native_skia_output_device.h183
-rw-r--r--src/core/compositor/native_skia_output_device_direct3d11.cpp88
-rw-r--r--src/core/compositor/native_skia_output_device_direct3d11.h28
-rw-r--r--src/core/compositor/native_skia_output_device_mac.mm90
-rw-r--r--src/core/compositor/native_skia_output_device_metal.cpp47
-rw-r--r--src/core/compositor/native_skia_output_device_metal.h28
-rw-r--r--src/core/compositor/native_skia_output_device_opengl.cpp86
-rw-r--r--src/core/compositor/native_skia_output_device_opengl.h28
-rw-r--r--src/core/compositor/native_skia_output_device_vulkan.cpp306
-rw-r--r--src/core/compositor/native_skia_output_device_vulkan.h28
-rw-r--r--src/core/compositor/vulkan_implementation_qt.cpp162
-rw-r--r--src/core/compositor/vulkan_implementation_qt.h46
-rw-r--r--src/core/configure.json303
-rw-r--r--src/core/configure/BUILD.root.gn.in310
-rw-r--r--src/core/content_browser_client_qt.cpp620
-rw-r--r--src/core/content_browser_client_qt.h128
-rw-r--r--src/core/content_client_qt.cpp246
-rw-r--r--src/core/content_client_qt.h57
-rw-r--r--src/core/content_main_delegate_qt.cpp128
-rw-r--r--src/core/content_main_delegate_qt.h43
-rw-r--r--src/core/content_utility_client_qt.cpp58
-rw-r--r--src/core/content_utility_client_qt.h40
-rw-r--r--src/core/custom_handlers/protocol_handler_registry_delegate_qt.cpp36
-rw-r--r--src/core/custom_handlers/protocol_handler_registry_delegate_qt.h35
-rw-r--r--src/core/custom_handlers/protocol_handler_registry_factory.cpp75
-rw-r--r--src/core/custom_handlers/protocol_handler_registry_factory.h57
-rw-r--r--src/core/custom_handlers/register_protocol_handler_request_controller.h26
-rw-r--r--src/core/custom_handlers/register_protocol_handler_request_controller_impl.cpp49
-rw-r--r--src/core/custom_handlers/register_protocol_handler_request_controller_impl.h38
-rw-r--r--src/core/delegated_frame_host_client_qt.cpp42
-rw-r--r--src/core/delegated_frame_host_client_qt.h42
-rw-r--r--src/core/desktop_media_controller.cpp244
-rw-r--r--src/core/desktop_media_controller.h65
-rw-r--r--src/core/desktop_media_controller_p.h28
-rw-r--r--src/core/desktop_screen_qt.cpp96
-rw-r--r--src/core/desktop_screen_qt.h44
-rw-r--r--src/core/devtools_frontend_qt.cpp596
-rw-r--r--src/core/devtools_frontend_qt.h139
-rw-r--r--src/core/devtools_manager_delegate_qt.cpp57
-rw-r--r--src/core/devtools_manager_delegate_qt.h40
-rw-r--r--src/core/doc/about_credits_entry.tmpl3
-rw-r--r--src/core/doc/qtwebengine.qdocconf6
-rw-r--r--src/core/doc/snippets/qtwebengine_qwebenginepage_snippet.cpp32
-rw-r--r--src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc37
-rw-r--r--src/core/doc/src/external-resources.qdoc28
-rw-r--r--src/core/doc/src/qt6-changes.qdoc28
-rw-r--r--src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc47
-rw-r--r--src/core/doc/src/qtwebengine-debugging.qdoc53
-rw-r--r--src/core/doc/src/qtwebengine-deploying.qdoc93
-rw-r--r--src/core/doc/src/qtwebengine-features.qdoc369
-rw-r--r--src/core/doc/src/qtwebengine-global.qdoc56
-rw-r--r--src/core/doc/src/qtwebengine-index.qdoc28
-rw-r--r--src/core/doc/src/qtwebengine-modules.qdoc37
-rw-r--r--src/core/doc/src/qtwebengine-overview.qdoc52
-rw-r--r--src/core/doc/src/qtwebengine-platform-notes.qdoc97
-rw-r--r--src/core/doc/src/qtwebenginecore-index.qdoc38
-rw-r--r--src/core/doc/src/qtwebenginecore-module.qdoc37
-rw-r--r--src/core/doc/src/qwebengine-licensing.qdoc35
-rw-r--r--src/core/doc/src/qwebenginehistory_lgpl.qdoc22
-rw-r--r--src/core/doc/src/qwebenginepage_lgpl.qdoc186
-rw-r--r--src/core/doc/src/qwebenginesettings_lgpl.qdoc99
-rw-r--r--src/core/download_manager_delegate_qt.cpp137
-rw-r--r--src/core/download_manager_delegate_qt.h49
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.cpp48
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.h43
-rw-r--r--src/core/extensions/extension_host_delegate_qt.cpp85
-rw-r--r--src/core/extensions/extension_host_delegate_qt.h46
-rw-r--r--src/core/extensions/extension_system_factory_qt.cpp40
-rw-r--r--src/core/extensions/extension_system_factory_qt.h43
-rw-r--r--src/core/extensions/extension_system_qt.cpp189
-rw-r--r--src/core/extensions/extension_system_qt.h75
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.cpp62
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.h42
-rw-r--r--src/core/extensions/extensions_api_client_qt.cpp61
-rw-r--r--src/core/extensions/extensions_api_client_qt.h45
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp114
-rw-r--r--src/core/extensions/extensions_browser_client_qt.h59
-rw-r--r--src/core/extensions/file_system_delegate_qt.cpp146
-rw-r--r--src/core/extensions/file_system_delegate_qt.h89
-rw-r--r--src/core/extensions/messaging_delegate_qt.cpp44
-rw-r--r--src/core/extensions/messaging_delegate_qt.h42
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.cpp43
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.h43
-rw-r--r--src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp95
-rw-r--r--src/core/extensions/pdf_iframe_navigation_throttle_qt.h40
-rw-r--r--src/core/extensions/pdf_web_contents_helper_client_qt.h30
-rw-r--r--src/core/extensions/plugin_service_filter_qt.cpp56
-rw-r--r--src/core/extensions/plugin_service_filter_qt.h48
-rw-r--r--src/core/favicon_driver_qt.cpp201
-rw-r--r--src/core/favicon_driver_qt.h89
-rw-r--r--src/core/favicon_service_factory_qt.cpp53
-rw-r--r--src/core/favicon_service_factory_qt.h43
-rw-r--r--src/core/file_picker_controller.cpp79
-rw-r--r--src/core/file_picker_controller.h42
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_factory_qt.cpp61
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_factory_qt.h37
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_qt.cpp479
-rw-r--r--src/core/file_system_access/file_system_access_permission_context_qt.h86
-rw-r--r--src/core/file_system_access/file_system_access_permission_grant_qt.cpp146
-rw-r--r--src/core/file_system_access/file_system_access_permission_grant_qt.h59
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_controller.h39
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_controller_impl.cpp48
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_controller_impl.h32
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp195
-rw-r--r--src/core/file_system_access/file_system_access_permission_request_manager_qt.h79
-rw-r--r--src/core/find_text_helper.cpp42
-rw-r--r--src/core/find_text_helper.h42
-rw-r--r--src/core/global_descriptors_qt.h40
-rw-r--r--src/core/javascript_dialog_controller.cpp42
-rw-r--r--src/core/javascript_dialog_controller.h42
-rw-r--r--src/core/javascript_dialog_controller_p.h45
-rw-r--r--src/core/javascript_dialog_manager_qt.cpp48
-rw-r--r--src/core/javascript_dialog_manager_qt.h45
-rw-r--r--src/core/location_provider_qt.cpp127
-rw-r--r--src/core/location_provider_qt.h51
-rw-r--r--src/core/login_delegate_qt.cpp60
-rw-r--r--src/core/login_delegate_qt.h40
-rw-r--r--src/core/macos_context_type_helper.h43
-rw-r--r--src/core/macos_context_type_helper.mm54
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp400
-rw-r--r--src/core/media_capture_devices_dispatcher.h77
-rw-r--r--src/core/native_web_keyboard_event_qt.cpp107
-rw-r--r--src/core/native_web_keyboard_event_qt.h20
-rw-r--r--src/core/native_web_keyboard_event_qt_mac.mm155
-rw-r--r--src/core/net/client_cert_override.cpp172
-rw-r--r--src/core/net/client_cert_override.h73
-rw-r--r--src/core/net/client_cert_qt.cpp148
-rw-r--r--src/core/net/client_cert_qt.h37
-rw-r--r--src/core/net/client_cert_store_data.cpp60
-rw-r--r--src/core/net/client_cert_store_data.h44
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp59
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h52
-rw-r--r--src/core/net/custom_url_loader_factory.cpp139
-rw-r--r--src/core/net/custom_url_loader_factory.h40
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp119
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.h47
-rw-r--r--src/core/net/proxy_config_monitor.cpp51
-rw-r--r--src/core/net/proxy_config_monitor.h50
-rw-r--r--src/core/net/proxy_config_service_qt.cpp57
-rw-r--r--src/core/net/proxy_config_service_qt.h48
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp93
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.h65
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp276
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.h55
-rw-r--r--src/core/net/qrc_url_scheme_handler.cpp49
-rw-r--r--src/core/net/qrc_url_scheme_handler.h40
-rw-r--r--src/core/net/resource_request_body_qt.cpp181
-rw-r--r--src/core/net/resource_request_body_qt.h70
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.cpp81
-rw-r--r--src/core/net/ssl_host_state_delegate_qt.h55
-rw-r--r--src/core/net/system_network_context_manager.cpp214
-rw-r--r--src/core/net/system_network_context_manager.h50
-rw-r--r--src/core/net/url_request_custom_job_delegate.cpp77
-rw-r--r--src/core/net/url_request_custom_job_delegate.h61
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp80
-rw-r--r--src/core/net/url_request_custom_job_proxy.h59
-rw-r--r--src/core/net/version_ui_qt.cpp56
-rw-r--r--src/core/net/version_ui_qt.h32
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp67
-rw-r--r--src/core/net/webui_controller_factory_qt.h43
-rw-r--r--src/core/ozone/BUILD.gn8
-rw-r--r--src/core/ozone/gl_context_qt.cpp283
-rw-r--r--src/core/ozone/gl_context_qt.h87
-rw-r--r--src/core/ozone/gl_ozone_egl_qt.cpp139
-rw-r--r--src/core/ozone/gl_ozone_egl_qt.h61
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.cpp77
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.h66
-rw-r--r--src/core/ozone/gl_share_context_qt.cpp71
-rw-r--r--src/core/ozone/gl_share_context_qt.h42
-rw-r--r--src/core/ozone/gl_surface_egl_qt.cpp236
-rw-r--r--src/core/ozone/gl_surface_egl_qt.h53
-rw-r--r--src/core/ozone/gl_surface_glx_qt.cpp115
-rw-r--r--src/core/ozone/gl_surface_glx_qt.h43
-rw-r--r--src/core/ozone/gl_surface_qt.cpp183
-rw-r--r--src/core/ozone/gl_surface_qt.h60
-rw-r--r--src/core/ozone/gl_surface_wgl_qt.cpp56
-rw-r--r--src/core/ozone/gl_surface_wgl_qt.h49
-rw-r--r--src/core/ozone/ozone_extra.gni14
-rw-r--r--src/core/ozone/ozone_platform_qt.cpp179
-rw-r--r--src/core/ozone/ozone_platform_qt.h48
-rw-r--r--src/core/ozone/platform_window_qt.cpp70
-rw-r--r--src/core/ozone/platform_window_qt.h61
-rw-r--r--src/core/ozone/surface_factory_qt.cpp272
-rw-r--r--src/core/ozone/surface_factory_qt.h72
-rw-r--r--src/core/pdf_util_qt.cpp92
-rw-r--r--src/core/pdf_util_qt.h34
-rw-r--r--src/core/permission_manager_qt.cpp282
-rw-r--r--src/core/permission_manager_qt.h89
-rw-r--r--src/core/platform_notification_service_qt.cpp45
-rw-r--r--src/core/platform_notification_service_qt.h41
-rw-r--r--src/core/pointer_device_qt.cpp102
-rw-r--r--src/core/pref_service_adapter.cpp110
-rw-r--r--src/core/pref_service_adapter.h41
-rw-r--r--src/core/printing/pdf_document_helper_client_qt.cpp33
-rw-r--r--src/core/printing/pdf_document_helper_client_qt.h27
-rw-r--r--src/core/printing/pdf_stream_delegate_qt.cpp99
-rw-r--r--src/core/printing/pdf_stream_delegate_qt.h23
-rw-r--r--src/core/printing/pdfium_document_wrapper_qt.cpp40
-rw-r--r--src/core/printing/pdfium_document_wrapper_qt.h42
-rw-r--r--src/core/printing/print_view_manager_base_qt.cpp420
-rw-r--r--src/core/printing/print_view_manager_base_qt.h92
-rw-r--r--src/core/printing/print_view_manager_qt.cpp241
-rw-r--r--src/core/printing/print_view_manager_qt.h60
-rw-r--r--src/core/printing/printer_worker.cpp82
-rw-r--r--src/core/printing/printer_worker.h45
-rw-r--r--src/core/process_main.cpp58
-rw-r--r--src/core/profile_adapter.cpp255
-rw-r--r--src/core/profile_adapter.h76
-rw-r--r--src/core/profile_adapter_client.cpp40
-rw-r--r--src/core/profile_adapter_client.h46
-rw-r--r--src/core/profile_io_data_qt.cpp156
-rw-r--r--src/core/profile_io_data_qt.h70
-rw-r--r--src/core/profile_qt.cpp183
-rw-r--r--src/core/profile_qt.h78
-rw-r--r--src/core/quota_permission_context_qt.cpp120
-rw-r--r--src/core/quota_permission_context_qt.h59
-rw-r--r--src/core/quota_request_controller.h62
-rw-r--r--src/core/quota_request_controller_impl.cpp72
-rw-r--r--src/core/quota_request_controller_impl.h68
-rw-r--r--src/core/register_protocol_handler_request_controller.h62
-rw-r--r--src/core/register_protocol_handler_request_controller_impl.cpp83
-rw-r--r--src/core/register_protocol_handler_request_controller_impl.h73
-rw-r--r--src/core/render_view_context_menu_qt.cpp40
-rw-r--r--src/core/render_view_context_menu_qt.h42
-rw-r--r--src/core/render_widget_host_view_qt.cpp281
-rw-r--r--src/core/render_widget_host_view_qt.h109
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h45
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.cpp88
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.h43
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.cpp455
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.h125
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp540
-rw-r--r--src/core/renderer/content_renderer_client_qt.h68
-rw-r--r--src/core/renderer/content_settings_observer_qt.cpp45
-rw-r--r--src/core/renderer/content_settings_observer_qt.h48
-rw-r--r--src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp40
-rw-r--r--src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h43
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.cpp52
-rw-r--r--src/core/renderer/extensions/extensions_renderer_client_qt.h50
-rw-r--r--src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp40
-rw-r--r--src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h44
-rw-r--r--src/core/renderer/extensions/resource_request_policy_qt.cpp55
-rw-r--r--src/core/renderer/extensions/resource_request_policy_qt.h47
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp73
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.h42
-rw-r--r--src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp50
-rw-r--r--src/core/renderer/plugins/loadable_plugin_placeholder_qt.h47
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.cpp67
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.h49
-rw-r--r--src/core/renderer/render_configuration.cpp47
-rw-r--r--src/core/renderer/render_configuration.h42
-rw-r--r--src/core/renderer/render_frame_observer_qt.cpp48
-rw-r--r--src/core/renderer/render_frame_observer_qt.h44
-rw-r--r--src/core/renderer/user_resource_controller.cpp90
-rw-r--r--src/core/renderer/user_resource_controller.h51
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp88
-rw-r--r--src/core/renderer/web_channel_ipc_transport.h44
-rw-r--r--src/core/renderer/web_engine_page_render_frame.cpp72
-rw-r--r--src/core/renderer/web_engine_page_render_frame.h44
-rw-r--r--src/core/renderer_host/pepper/pepper_host_factory_qt.cpp98
-rw-r--r--src/core/renderer_host/pepper/pepper_host_factory_qt.h73
-rw-r--r--src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp135
-rw-r--r--src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.h89
-rw-r--r--src/core/renderer_host/user_resource_controller_host.cpp50
-rw-r--r--src/core/renderer_host/user_resource_controller_host.h42
-rw-r--r--src/core/renderer_host/web_channel_ipc_transport_host.cpp75
-rw-r--r--src/core/renderer_host/web_channel_ipc_transport_host.h48
-rw-r--r--src/core/renderer_host/web_engine_page_host.cpp46
-rw-r--r--src/core/renderer_host/web_engine_page_host.h40
-rw-r--r--src/core/request_controller.h40
-rw-r--r--src/core/resource_bundle_qt.cpp62
-rw-r--r--src/core/resource_context_qt.cpp49
-rw-r--r--src/core/resource_context_qt.h61
-rw-r--r--src/core/sandbox_win.cpp44
-rw-r--r--src/core/select_file_dialog_factory_qt.cpp54
-rw-r--r--src/core/select_file_dialog_factory_qt.h45
-rw-r--r--src/core/tools/qwebengine_convert_dict/CMakeLists.txt (renamed from src/core/tools/CMakeLists.txt)17
-rw-r--r--src/core/tools/qwebengine_convert_dict/main.cpp (renamed from src/core/tools/main.cpp)21
-rw-r--r--src/core/tools/webenginedriver/CMakeLists.txt57
-rw-r--r--src/core/touch_handle_drawable_client.h44
-rw-r--r--src/core/touch_handle_drawable_qt.cpp123
-rw-r--r--src/core/touch_handle_drawable_qt.h51
-rw-r--r--src/core/touch_selection_controller_client_qt.cpp61
-rw-r--r--src/core/touch_selection_controller_client_qt.h48
-rw-r--r--src/core/touch_selection_menu_controller.cpp40
-rw-r--r--src/core/touch_selection_menu_controller.h44
-rw-r--r--src/core/type_conversion.cpp61
-rw-r--r--src/core/type_conversion.h118
-rw-r--r--src/core/user_notification_controller.cpp42
-rw-r--r--src/core/user_notification_controller.h40
-rw-r--r--src/core/user_script.cpp44
-rw-r--r--src/core/user_script.h40
-rw-r--r--src/core/visited_links_manager_qt.cpp43
-rw-r--r--src/core/visited_links_manager_qt.h42
-rw-r--r--src/core/web_contents_adapter.cpp392
-rw-r--r--src/core/web_contents_adapter.h47
-rw-r--r--src/core/web_contents_adapter_client.h59
-rw-r--r--src/core/web_contents_delegate_qt.cpp303
-rw-r--r--src/core/web_contents_delegate_qt.h91
-rw-r--r--src/core/web_contents_view_qt.cpp45
-rw-r--r--src/core/web_contents_view_qt.h52
-rw-r--r--src/core/web_engine_context.cpp689
-rw-r--r--src/core/web_engine_context.h53
-rw-r--r--src/core/web_engine_context_threads.cpp138
-rw-r--r--src/core/web_engine_error.cpp65
-rw-r--r--src/core/web_engine_error.h47
-rw-r--r--src/core/web_engine_library_info.cpp267
-rw-r--r--src/core/web_engine_library_info.h50
-rw-r--r--src/core/web_engine_settings.cpp105
-rw-r--r--src/core/web_engine_settings.h44
-rw-r--r--src/core/web_event_factory.cpp100
-rw-r--r--src/core/web_event_factory.h56
-rw-r--r--src/core/web_usb_detector_qt.cpp65
-rw-r--r--src/core/web_usb_detector_qt.h45
-rw-r--r--src/gn/CMakeLists.txt38
-rw-r--r--src/host/BUILD.toolchain.gn.in1
-rw-r--r--src/host/CMakeLists.txt29
-rw-r--r--src/host/config.tests/hostcompiler/CMakeLists.txt11
-rw-r--r--src/host/config.tests/hostcompiler/main.cpp9
-rw-r--r--src/ninja/CMakeLists.txt7
-rw-r--r--src/pdf/CMakeLists.txt134
-rw-r--r--src/pdf/configure.cmake17
-rw-r--r--src/pdf/configure/BUILD.root.gn.in53
-rw-r--r--src/pdf/doc/about_credits.tmpl1
-rw-r--r--src/pdf/doc/about_credits_entry.tmpl13
-rw-r--r--src/pdf/doc/images/multipageviewer.pngbin0 -> 39637 bytes
-rw-r--r--src/pdf/doc/images/pdfviewer.pngbin0 -> 264348 bytes
-rw-r--r--src/pdf/doc/images/search-results.pngbin0 -> 19718 bytes
-rw-r--r--src/pdf/doc/images/singlepageviewer.webpbin0 -> 57680 bytes
-rw-r--r--src/pdf/doc/images/wrapping-search-result.pngbin0 -> 39106 bytes
-rw-r--r--src/pdf/doc/qtpdf.qdocconf16
-rw-r--r--src/pdf/doc/snippets/multipageview.qml11
-rw-r--r--src/pdf/doc/snippets/qtpdf-build.cmake4
-rw-r--r--src/pdf/doc/snippets/qtpdf_build_snippet.qdoc33
-rw-r--r--src/pdf/doc/src/qtpdf-examples.qdoc29
-rw-r--r--src/pdf/doc/src/qtpdf-index.qdoc76
-rw-r--r--src/pdf/doc/src/qtpdf-licensing.qdoc18
-rw-r--r--src/pdf/doc/src/qtpdf-module.qdoc33
-rw-r--r--src/pdf/doc/src/qtpdf-platformnotes.qdoc11
-rw-r--r--src/pdf/plugins/imageformats/pdf/CMakeLists.txt5
-rw-r--r--src/pdf/plugins/imageformats/pdf/main.cpp37
-rw-r--r--src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp84
-rw-r--r--src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h41
-rw-r--r--src/pdf/qpdfbookmarkmodel.cpp228
-rw-r--r--src/pdf/qpdfbookmarkmodel.h72
-rw-r--r--src/pdf/qpdfdestination.cpp145
-rw-r--r--src/pdf/qpdfdestination.h85
-rw-r--r--src/pdf/qpdfdestination_p.h71
-rw-r--r--src/pdf/qpdfdocument.cpp515
-rw-r--r--src/pdf/qpdfdocument.h91
-rw-r--r--src/pdf/qpdfdocument_p.h79
-rw-r--r--src/pdf/qpdfdocumentrenderoptions.h93
-rw-r--r--src/pdf/qpdfdocumentrenderoptions.qdoc74
-rw-r--r--src/pdf/qpdffile.cpp28
-rw-r--r--src/pdf/qpdffile_p.h37
-rw-r--r--src/pdf/qpdflink.cpp189
-rw-r--r--src/pdf/qpdflink.h78
-rw-r--r--src/pdf/qpdflink_p.h53
-rw-r--r--src/pdf/qpdflinkmodel.cpp208
-rw-r--r--src/pdf/qpdflinkmodel.h67
-rw-r--r--src/pdf/qpdflinkmodel_p.h92
-rw-r--r--src/pdf/qpdflinkmodel_p_p.h91
-rw-r--r--src/pdf/qpdfnamespace.h73
-rw-r--r--src/pdf/qpdfnamespace.qdoc74
-rw-r--r--src/pdf/qpdfpagenavigation.cpp290
-rw-r--r--src/pdf/qpdfpagenavigation.h92
-rw-r--r--src/pdf/qpdfpagenavigator.cpp362
-rw-r--r--src/pdf/qpdfpagenavigator.h62
-rw-r--r--src/pdf/qpdfpagerenderer.cpp44
-rw-r--r--src/pdf/qpdfpagerenderer.h44
-rw-r--r--src/pdf/qpdfsearchmodel.cpp177
-rw-r--r--src/pdf/qpdfsearchmodel.h56
-rw-r--r--src/pdf/qpdfsearchmodel_p.h42
-rw-r--r--src/pdf/qpdfsearchresult.cpp80
-rw-r--r--src/pdf/qpdfsearchresult.h76
-rw-r--r--src/pdf/qpdfsearchresult_p.h72
-rw-r--r--src/pdf/qpdfselection.cpp60
-rw-r--r--src/pdf/qpdfselection.h69
-rw-r--r--src/pdf/qpdfselection_p.h39
-rw-r--r--src/pdf/qtpdfglobal.h56
-rw-r--r--src/pdfquick/+Material/PdfStyle.qml15
-rw-r--r--src/pdfquick/+Universal/PdfStyle.qml15
-rw-r--r--src/pdfquick/CMakeLists.txt41
-rw-r--r--src/pdfquick/PdfLinkDelegate.qml74
-rw-r--r--src/pdfquick/PdfMultiPageView.qml623
-rw-r--r--src/pdfquick/PdfPageView.qml439
-rw-r--r--src/pdfquick/PdfScrollablePageView.qml487
-rw-r--r--src/pdfquick/PdfStyle.qml71
-rw-r--r--src/pdfquick/doc/src/qtquickpdf-module.qdoc18
-rw-r--r--src/pdfquick/plugin.cpp99
-rw-r--r--src/pdfquick/plugins.qmltypes52
-rw-r--r--src/pdfquick/qml/+material/PdfStyle.qml54
-rw-r--r--src/pdfquick/qml/+universal/PdfStyle.qml55
-rw-r--r--src/pdfquick/qml/PdfMultiPageView.qml434
-rw-r--r--src/pdfquick/qml/PdfPageView.qml276
-rw-r--r--src/pdfquick/qml/PdfScrollablePageView.qml307
-rw-r--r--src/pdfquick/qml/PdfStyle.qml54
-rw-r--r--src/pdfquick/qquickpdfbookmarkmodel.cpp55
-rw-r--r--src/pdfquick/qquickpdfbookmarkmodel_p.h53
-rw-r--r--src/pdfquick/qquickpdfdocument.cpp168
-rw-r--r--src/pdfquick/qquickpdfdocument_p.h131
-rw-r--r--src/pdfquick/qquickpdflinkmodel.cpp60
-rw-r--r--src/pdfquick/qquickpdflinkmodel_p.h51
-rw-r--r--src/pdfquick/qquickpdfnavigationstack.cpp288
-rw-r--r--src/pdfquick/qquickpdfnavigationstack_p.h103
-rw-r--r--src/pdfquick/qquickpdfpageimage.cpp141
-rw-r--r--src/pdfquick/qquickpdfpageimage_p.h52
-rw-r--r--src/pdfquick/qquickpdfpagenavigator.cpp130
-rw-r--r--src/pdfquick/qquickpdfpagenavigator_p.h55
-rw-r--r--src/pdfquick/qquickpdfsearchmodel.cpp168
-rw-r--r--src/pdfquick/qquickpdfsearchmodel_p.h49
-rw-r--r--src/pdfquick/qquickpdfselection.cpp172
-rw-r--r--src/pdfquick/qquickpdfselection_p.h71
-rw-r--r--src/pdfquick/qquicktableviewextra.cpp78
-rw-r--r--src/pdfquick/qquicktableviewextra_p.h93
-rw-r--r--src/pdfquick/qtpdfquickglobal_p.h40
-rw-r--r--src/pdfwidgets/CMakeLists.txt5
-rw-r--r--src/pdfwidgets/qpdfpageselector.cpp171
-rw-r--r--src/pdfwidgets/qpdfpageselector.h51
-rw-r--r--src/pdfwidgets/qpdfpageselector_p.h60
-rw-r--r--src/pdfwidgets/qpdfview.cpp397
-rw-r--r--src/pdfwidgets/qpdfview.h74
-rw-r--r--src/pdfwidgets/qpdfview_p.h49
-rw-r--r--src/pdfwidgets/qtpdfwidgetsglobal.h37
-rw-r--r--src/process/CMakeLists.txt40
-rw-r--r--src/process/Info_mac.plist.in44
-rw-r--r--src/process/QtWebEngineProcess.entitlements2
-rw-r--r--src/process/main.cpp42
-rw-r--r--src/process/support_win.cpp40
-rw-r--r--src/webenginequick/CMakeLists.txt21
-rw-r--r--src/webenginequick/api/qquickwebengineaction.cpp51
-rw-r--r--src/webenginequick/api/qquickwebengineaction_p.h42
-rw-r--r--src/webenginequick/api/qquickwebengineaction_p_p.h40
-rw-r--r--src/webenginequick/api/qquickwebengineclientcertificateselection.cpp44
-rw-r--r--src/webenginequick/api/qquickwebengineclientcertificateselection_p.h44
-rw-r--r--src/webenginequick/api/qquickwebenginedialogrequests.cpp71
-rw-r--r--src/webenginequick/api/qquickwebenginedialogrequests_p.h51
-rw-r--r--src/webenginequick/api/qquickwebenginedownloadrequest.cpp42
-rw-r--r--src/webenginequick/api/qquickwebenginedownloadrequest_p.h42
-rw-r--r--src/webenginequick/api/qquickwebenginefaviconprovider.cpp46
-rw-r--r--src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h42
-rw-r--r--src/webenginequick/api/qquickwebengineforeigntypes_p.h95
-rw-r--r--src/webenginequick/api/qquickwebenginenewwindowrequest.cpp42
-rw-r--r--src/webenginequick/api/qquickwebenginenewwindowrequest_p.h42
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.cpp198
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.h49
-rw-r--r--src/webenginequick/api/qquickwebengineprofile_p.h47
-rw-r--r--src/webenginequick/api/qquickwebenginescriptcollection.cpp177
-rw-r--r--src/webenginequick/api/qquickwebenginescriptcollection_p.h51
-rw-r--r--src/webenginequick/api/qquickwebenginescriptcollection_p_p.h38
-rw-r--r--src/webenginequick/api/qquickwebenginesettings.cpp176
-rw-r--r--src/webenginequick/api/qquickwebenginesettings_p.h70
-rw-r--r--src/webenginequick/api/qquickwebenginesingleton.cpp67
-rw-r--r--src/webenginequick/api/qquickwebenginesingleton_p.h42
-rw-r--r--src/webenginequick/api/qquickwebenginetouchhandle.cpp45
-rw-r--r--src/webenginequick/api/qquickwebenginetouchhandle_p.h47
-rw-r--r--src/webenginequick/api/qquickwebenginetouchhandleprovider.cpp40
-rw-r--r--src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h42
-rw-r--r--src/webenginequick/api/qquickwebenginetouchselectionmenurequest.cpp46
-rw-r--r--src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p.h44
-rw-r--r--src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p_p.h40
-rw-r--r--src/webenginequick/api/qquickwebengineview.cpp675
-rw-r--r--src/webenginequick/api/qquickwebengineview_p.h112
-rw-r--r--src/webenginequick/api/qquickwebengineview_p_p.h105
-rw-r--r--src/webenginequick/api/qtwebenginequickglobal.cpp53
-rw-r--r--src/webenginequick/api/qtwebenginequickglobal.h40
-rw-r--r--src/webenginequick/api/qtwebenginequickglobal_p.h46
-rw-r--r--src/webenginequick/configure.cmake3
-rw-r--r--src/webenginequick/doc/snippets/minimal/main.cpp18
-rw-r--r--src/webenginequick/doc/snippets/minimal/main.qml18
-rw-r--r--src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc37
-rw-r--r--src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml123
-rw-r--r--src/webenginequick/doc/snippets/qtwebengine_webengineview_newviewrequested.qml51
-rw-r--r--src/webenginequick/doc/src/context_menu_request.qdoc28
-rw-r--r--src/webenginequick/doc/src/fullscreen_request.qdoc28
-rw-r--r--src/webenginequick/doc/src/loading_info.qdoc30
-rw-r--r--src/webenginequick/doc/src/navigation_history.qdoc28
-rw-r--r--src/webenginequick/doc/src/qtwebengine-examples.qdoc29
-rw-r--r--src/webenginequick/doc/src/qtwebengine-module.qdoc35
-rw-r--r--src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc42
-rw-r--r--src/webenginequick/doc/src/quota_request.qdoc52
-rw-r--r--src/webenginequick/doc/src/register_protocol_handler_request.qdoc28
-rw-r--r--src/webenginequick/doc/src/touch_selection_menu_request.qdoc28
-rw-r--r--src/webenginequick/doc/src/webengine_certificate_error.qdoc32
-rw-r--r--src/webenginequick/doc/src/webengine_download_request.qdoc28
-rw-r--r--src/webenginequick/doc/src/webenginescript.qdoc98
-rw-r--r--src/webenginequick/doc/src/webengineview_lgpl.qdoc190
-rw-r--r--src/webenginequick/plugin.cpp48
-rw-r--r--src/webenginequick/qquickwebengine_accessible.cpp147
-rw-r--r--src/webenginequick/qquickwebengine_accessible.h56
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp446
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quick.h147
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp106
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h82
-rw-r--r--src/webenginequick/ui/AlertDialog.qml41
-rw-r--r--src/webenginequick/ui/AuthenticationDialog.qml41
-rw-r--r--src/webenginequick/ui/AutofillPopup.qml41
-rw-r--r--src/webenginequick/ui/CMakeLists.txt14
-rw-r--r--src/webenginequick/ui/ColorDialog.qml318
-rw-r--r--src/webenginequick/ui/ConfirmDialog.qml41
-rw-r--r--src/webenginequick/ui/DirectoryPicker.qml15
-rw-r--r--src/webenginequick/ui/FilePicker.qml40
-rw-r--r--src/webenginequick/ui/Menu.qml44
-rw-r--r--src/webenginequick/ui/MenuItem.qml45
-rw-r--r--src/webenginequick/ui/MenuSeparator.qml40
-rw-r--r--src/webenginequick/ui/PromptDialog.qml41
-rw-r--r--src/webenginequick/ui/ToolTip.qml44
-rw-r--r--src/webenginequick/ui/TouchHandle.qml40
-rw-r--r--src/webenginequick/ui/TouchSelectionMenu.qml40
-rw-r--r--src/webenginequick/ui/custom/ColorDialog.qml285
-rw-r--r--src/webenginequick/ui_delegates_manager.cpp265
-rw-r--r--src/webenginequick/ui_delegates_manager.h75
-rw-r--r--src/webenginewidgets/CMakeLists.txt14
-rw-r--r--src/webenginewidgets/api/qtwebenginewidgetsglobal.h40
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter.cpp48
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter_p.h40
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp704
-rw-r--r--src/webenginewidgets/api/qwebengineview.h51
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h96
-rw-r--r--src/webenginewidgets/doc/snippets/push-notifications/commands19
-rw-r--r--src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp28
-rw-r--r--src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc37
-rw-r--r--src/webenginewidgets/doc/snippets/simple/main.cpp62
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc29
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc37
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc40
-rw-r--r--src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc28
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc36
-rw-r--r--src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt3
-rw-r--r--src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp41
-rw-r--r--src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.h40
-rw-r--r--src/webenginewidgets/qwebengine_accessible.cpp102
-rw-r--r--src/webenginewidgets/qwebengine_accessible.h49
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp521
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h138
-rw-r--r--src/webenginewidgets/ui/autofillpopupwidget.cpp201
-rw-r--r--src/webenginewidgets/ui/autofillpopupwidget_p.h58
-rw-r--r--src/webenginewidgets/ui/touchhandlewidget.cpp59
-rw-r--r--src/webenginewidgets/ui/touchhandlewidget_p.h50
-rw-r--r--src/webenginewidgets/ui/touchselectionmenuwidget.cpp117
-rw-r--r--src/webenginewidgets/ui/touchselectionmenuwidget_p.h52
-rw-r--r--sync.profile14
-rw-r--r--tests/auto/CMakeLists.txt6
-rw-r--r--tests/auto/cmake/CMakeLists.txt28
-rw-r--r--tests/auto/core/CMakeLists.txt15
-rw-r--r--tests/auto/core/certificateerror/CMakeLists.txt3
-rw-r--r--tests/auto/core/certificateerror/tst_certificateerror.cpp38
-rw-r--r--tests/auto/core/devtools/CMakeLists.txt3
-rw-r--r--tests/auto/core/devtools/tst_devtools.cpp40
-rw-r--r--tests/auto/core/getdomainandregistry/CMakeLists.txt12
-rw-r--r--tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp30
-rw-r--r--tests/auto/core/origins/CMakeLists.txt6
-rw-r--r--tests/auto/core/origins/resources/fetchApi.html14
-rw-r--r--tests/auto/core/origins/resources/link.html13
-rw-r--r--tests/auto/core/origins/resources/media.html15
-rw-r--r--tests/auto/core/origins/resources/mixedSchemes.html29
-rw-r--r--tests/auto/core/origins/resources/mixedSchemes_frame.html8
-rw-r--r--tests/auto/core/origins/resources/red.pngbin0 -> 146 bytes
-rw-r--r--tests/auto/core/origins/resources/redirect.css7
-rw-r--r--tests/auto/core/origins/resources/redirect.html9
-rw-r--r--tests/auto/core/origins/tst_origins.cpp1077
-rw-r--r--tests/auto/core/qtversion/CMakeLists.txt10
-rw-r--r--tests/auto/core/qtversion/tst_qtversion.cpp34
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt59
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/ca.pem24
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/client.key27
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/client.pem22
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/client2.key27
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/client2.p12bin0 -> 2710 bytes
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/client2.pem22
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/server.key27
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/resources/server.pem22
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp131
-rw-r--r--tests/auto/core/qwebenginecookiestore/CMakeLists.txt3
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp159
-rw-r--r--tests/auto/core/qwebengineglobalsettings/CMakeLists.txt29
-rw-r--r--tests/auto/core/qwebengineglobalsettings/cert/RootCA.pem20
-rw-r--r--tests/auto/core/qwebengineglobalsettings/cert/localhost.crt22
-rw-r--r--tests/auto/core/qwebengineglobalsettings/cert/localhost.key28
-rw-r--r--tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp121
-rw-r--r--tests/auto/core/qwebengineloadinginfo/CMakeLists.txt10
-rw-r--r--tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp93
-rw-r--r--tests/auto/core/qwebenginesettings/CMakeLists.txt4
-rw-r--r--tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp111
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt8
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html6
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/postBodyFile.txt3
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html39
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js15
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp375
-rw-r--r--tests/auto/core/qwebengineurlrequestjob/CMakeLists.txt22
-rw-r--r--tests/auto/core/qwebengineurlrequestjob/additionalResponseHeadersScript.html12
-rw-r--r--tests/auto/core/qwebengineurlrequestjob/requestBodyScript.html12
-rw-r--r--tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp187
-rw-r--r--tests/auto/core/webenginedriver/CMakeLists.txt15
-rw-r--r--tests/auto/core/webenginedriver/browser/CMakeLists.txt13
-rw-r--r--tests/auto/core/webenginedriver/browser/main.cpp21
-rw-r--r--tests/auto/core/webenginedriver/resources/input.html5
-rw-r--r--tests/auto/core/webenginedriver/test/CMakeLists.txt26
-rw-r--r--tests/auto/core/webenginedriver/tst_webenginedriver.cpp631
-rw-r--r--tests/auto/httpserver/CMakeLists.txt3
-rw-r--r--tests/auto/httpserver/httpreqrep.cpp36
-rw-r--r--tests/auto/httpserver/httpreqrep.h30
-rw-r--r--tests/auto/httpserver/httpserver.cmake3
-rw-r--r--tests/auto/httpserver/httpserver.cpp37
-rw-r--r--tests/auto/httpserver/httpserver.h31
-rw-r--r--tests/auto/httpserver/httpsserver.h108
-rw-r--r--tests/auto/httpserver/proxy_server.cpp31
-rw-r--r--tests/auto/httpserver/proxy_server.h29
-rw-r--r--tests/auto/pdf/CMakeLists.txt8
-rw-r--r--tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt8
-rw-r--r--tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp168
-rw-r--r--tests/auto/pdf/qpdfdocument/BLACKLIST6
-rw-r--r--tests/auto/pdf/qpdfdocument/CMakeLists.txt11
-rw-r--r--tests/auto/pdf/qpdfdocument/rotated_text.pdf70
-rw-r--r--tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf136
-rw-r--r--tests/auto/pdf/qpdfdocument/test.pdfbin0 -> 76633 bytes
-rw-r--r--tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp342
-rw-r--r--tests/auto/pdf/qpdfpagenavigation/CMakeLists.txt8
-rw-r--r--tests/auto/pdf/qpdfpagenavigation/tst_qpdfpagenavigation.cpp200
-rw-r--r--tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt14
-rw-r--r--tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf (renamed from tests/auto/pdf/qpdfpagenavigation/pdf-sample.pagenavigation.pdf)bin27523 -> 27523 bytes
-rw-r--r--tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp70
-rw-r--r--tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt7
-rw-r--r--tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp53
-rw-r--r--tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt9
-rw-r--r--tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf70
-rw-r--r--tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf136
-rw-r--r--tests/auto/pdf/qpdfsearchmodel/test.pdfbin80045 -> 76633 bytes
-rw-r--r--tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp78
-rw-r--r--tests/auto/pdfquick/CMakeLists.txt2
-rw-r--r--tests/auto/pdfquick/multipageview/BLACKLIST7
-rw-r--r--tests/auto/pdfquick/multipageview/CMakeLists.txt30
-rw-r--r--tests/auto/pdfquick/multipageview/data/bookmarksAndLinks.pdf317
-rw-r--r--tests/auto/pdfquick/multipageview/data/jumpOnDocumentReady.qml18
-rw-r--r--tests/auto/pdfquick/multipageview/data/multiPageView.qml8
-rw-r--r--tests/auto/pdfquick/multipageview/data/multiPageViewWithFeedback.qml18
-rw-r--r--tests/auto/pdfquick/multipageview/data/pdf-sample.protected.pdfbin0 -> 9138 bytes
-rw-r--r--tests/auto/pdfquick/multipageview/data/qpdfwriter.pdfbin0 -> 33645 bytes
-rw-r--r--tests/auto/pdfquick/multipageview/tst_multipageview.cpp446
-rw-r--r--tests/auto/pdfquick/pdfpageimage/CMakeLists.txt30
-rw-r--r--tests/auto/pdfquick/pdfpageimage/data/bookmarksAndLinks.pdf317
-rw-r--r--tests/auto/pdfquick/pdfpageimage/data/pdfPageImage.qml16
-rw-r--r--tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp131
-rw-r--r--tests/auto/pdfquick/shared/util.cpp110
-rw-r--r--tests/auto/pdfquick/shared/util.h58
-rw-r--r--tests/auto/quick/CMakeLists.txt8
-rw-r--r--tests/auto/quick/dialogs/CMakeLists.txt3
-rw-r--r--tests/auto/quick/dialogs/WebView.qml29
-rw-r--r--tests/auto/quick/dialogs/testhandler.cpp29
-rw-r--r--tests/auto/quick/dialogs/testhandler.h29
-rw-r--r--tests/auto/quick/dialogs/tst_dialogs.cpp37
-rw-r--r--tests/auto/quick/inspectorserver/CMakeLists.txt3
-rw-r--r--tests/auto/quick/inspectorserver/tst_inspectorserver.cpp59
-rw-r--r--tests/auto/quick/publicapi/CMakeLists.txt3
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp160
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST4
-rw-r--r--tests/auto/quick/qmltests/CMakeLists.txt15
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml46
-rw-r--r--tests/auto/quick/qmltests/data/filesystemapi.html66
-rw-r--r--tests/auto/quick/qmltests/data/test4.html1
-rw-r--r--tests/auto/quick/qmltests/data/titleupdate.js29
-rw-r--r--tests/auto/quick/qmltests/data/tst_action.qml33
-rw-r--r--tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_audioMuted.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_basicProfiles.qml90
-rw-r--r--tests/auto/quick/qmltests/data/tst_certificateError.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_contextMenu.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_datalist.qml180
-rw-r--r--tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml67
-rw-r--r--tests/auto/quick/qmltests/data/tst_favicon.qml61
-rw-r--r--tests/auto/quick/qmltests/data/tst_faviconDatabase.qml35
-rw-r--r--tests/auto/quick/qmltests/data/tst_filePicker.qml47
-rw-r--r--tests/auto/quick/qmltests/data/tst_filesystem.qml124
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml32
-rw-r--r--tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_geopermission.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_getUserMedia.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_inputMethod.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_inputTextDirection.qml43
-rw-r--r--tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardEvents.qml43
-rw-r--r--tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_linkHovered.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadFail.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadHtml.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadProgress.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_loadUrl.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_mouseClick.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_mouseMove.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationHistory.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_navigationRequested.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_newViewRequest.qml34
-rw-r--r--tests/auto/quick/qmltests/data/tst_notification.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_properties.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_runJavaScript.qml32
-rw-r--r--tests/auto/quick/qmltests/data/tst_save.qml185
-rw-r--r--tests/auto/quick/qmltests/data/tst_scrollPosition.qml36
-rw-r--r--tests/auto/quick/qmltests/data/tst_settings.qml91
-rw-r--r--tests/auto/quick/qmltests/data/tst_titleChanged.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml29
-rw-r--r--tests/auto/quick/qmltests/data/tst_userScriptCollection.qml127
-rw-r--r--tests/auto/quick/qmltests/data/tst_userScripts.qml71
-rw-r--r--tests/auto/quick/qmltests/data/tst_viewSource.qml31
-rw-r--r--tests/auto/quick/qmltests/data/tst_webchannel.qml34
-rw-r--r--tests/auto/quick/qmltests/data/webchannel-test.html1
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml29
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml29
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml18
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml29
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml40
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml40
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml29
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml30
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml29
-rw-r--r--tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml29
-rw-r--r--tests/auto/quick/qmltests/tst_qmltests.cpp64
-rw-r--r--tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp29
-rw-r--r--tests/auto/quick/qquickwebengineview/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp261
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp38
-rw-r--r--tests/auto/quick/qtbug-70248/CMakeLists.txt3
-rw-r--r--tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp29
-rw-r--r--tests/auto/quick/uidelegates/CMakeLists.txt3
-rw-r--r--tests/auto/quick/uidelegates/tst_uidelegates.cpp29
-rw-r--r--tests/auto/util/CMakeLists.txt3
-rw-r--r--tests/auto/util/qt_webengine_quicktest.h29
-rw-r--r--tests/auto/util/quickutil.h34
-rw-r--r--tests/auto/util/testwindow.h29
-rw-r--r--tests/auto/util/util.cmake3
-rw-r--r--tests/auto/util/util.h61
-rw-r--r--tests/auto/util/widgetutil.h31
-rw-r--r--tests/auto/widgets/CMakeLists.txt4
-rw-r--r--tests/auto/widgets/accessibility/BLACKLIST3
-rw-r--r--tests/auto/widgets/accessibility/CMakeLists.txt4
-rw-r--r--tests/auto/widgets/accessibility/tst_accessibility.cpp129
-rw-r--r--tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp29
-rw-r--r--tests/auto/widgets/favicon/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/favicon/tst_favicon.cpp256
-rw-r--r--tests/auto/widgets/loadsignals/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.cpp123
-rw-r--r--tests/auto/widgets/offscreen/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/offscreen/tst_offscreen.cpp31
-rw-r--r--tests/auto/widgets/printing/CMakeLists.txt10
-rw-r--r--tests/auto/widgets/printing/tst_printing.cpp114
-rw-r--r--tests/auto/widgets/proxy/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/proxy/tst_proxy.cpp49
-rw-r--r--tests/auto/widgets/proxypac/CMakeLists.txt25
-rw-r--r--tests/auto/widgets/proxypac/proxy.pac2
-rw-r--r--tests/auto/widgets/proxypac/proxyserver.cpp29
-rw-r--r--tests/auto/widgets/proxypac/proxyserver.h29
-rw-r--r--tests/auto/widgets/proxypac/tst_proxypac.cpp45
-rw-r--r--tests/auto/widgets/qtbug_110287/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp41
-rw-r--r--tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp80
-rw-r--r--tests/auto/widgets/qwebenginehistory/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp44
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST10
-rw-r--r--tests/auto/widgets/qwebenginepage/CMakeLists.txt7
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/fontaccess.html14
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/reload.html2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp1562
-rw-r--r--tests/auto/widgets/qwebengineprofile/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp173
-rw-r--r--tests/auto/widgets/qwebenginescript/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebenginescript/resources/test_window_open.html2
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp63
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST18
-rw-r--r--tests/auto/widgets/qwebengineview/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/qwebengineview/resources/dummy.html2
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp876
-rw-r--r--tests/auto/widgets/schemes/CMakeLists.txt6
-rw-r--r--tests/auto/widgets/schemes/tst_schemes.cpp215
-rw-r--r--tests/auto/widgets/shutdown/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/shutdown/tst_shutdown.cpp40
-rw-r--r--tests/auto/widgets/spellchecking/CMakeLists.txt4
-rw-r--r--tests/auto/widgets/spellchecking/tst_spellchecking.cpp34
-rw-r--r--tests/auto/widgets/touchinput/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/touchinput/tst_touchinput.cpp101
-rw-r--r--tests/manual/CMakeLists.txt7
-rw-r--r--tests/manual/examples/CMakeLists.txt6
-rw-r--r--tests/manual/examples/quick/CMakeLists.txt4
-rw-r--r--tests/manual/examples/quick/customdialogs/CMakeLists.txt (renamed from examples/webenginequick/customdialogs/CMakeLists.txt)40
-rw-r--r--tests/manual/examples/quick/customdialogs/MessageRectangle.qml18
-rw-r--r--tests/manual/examples/quick/customdialogs/SwitchButton.qml23
-rw-r--r--tests/manual/examples/quick/customdialogs/WebView.qml (renamed from examples/webenginequick/customdialogs/WebView.qml)51
-rw-r--r--tests/manual/examples/quick/customdialogs/customdialogs.pro (renamed from examples/webenginequick/customdialogs/customdialogs.pro)0
-rw-r--r--tests/manual/examples/quick/customdialogs/customdialogs.qrc (renamed from examples/webenginequick/customdialogs/customdialogs.qrc)0
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/Authentication.qml31
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/AuthenticationForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/AuthenticationForm.ui.qml)67
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/ColorCell.qml16
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml31
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/ColorPickerForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/ColorPickerForm.ui.qml)52
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/CustomButton.qml61
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/FilePicker.qml44
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/FilePickerForm.ui.qml (renamed from examples/webenginequick/customdialogs/forms/FilePickerForm.ui.qml)52
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/FileRow.qml44
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/JavaScript.qml44
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml117
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/Menu.qml22
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml65
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml14
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml39
-rw-r--r--tests/manual/examples/quick/customdialogs/forms/forms.qmlproject (renamed from examples/webenginequick/customdialogs/forms/forms.qmlproject)0
-rw-r--r--tests/manual/examples/quick/customdialogs/icon.svg (renamed from examples/webenginequick/customdialogs/icon.svg)0
-rw-r--r--tests/manual/examples/quick/customdialogs/index.html (renamed from examples/webenginequick/customdialogs/index.html)0
-rw-r--r--tests/manual/examples/quick/customdialogs/main.cpp32
-rw-r--r--tests/manual/examples/quick/customdialogs/main.qml56
-rw-r--r--tests/manual/examples/quick/customdialogs/server.cpp47
-rw-r--r--tests/manual/examples/quick/customdialogs/server.h29
-rw-r--r--tests/manual/examples/quick/customdialogs/style.css (renamed from examples/webenginequick/customdialogs/style.css)0
-rw-r--r--tests/manual/examples/quick/customtouchhandle/CMakeLists.txt36
-rw-r--r--tests/manual/examples/quick/customtouchhandle/customtouchhandle.pro (renamed from examples/webenginequick/webengineaction/webengineaction.pro)2
-rw-r--r--tests/manual/examples/quick/customtouchhandle/main.cpp19
-rw-r--r--tests/manual/examples/quick/customtouchhandle/main.qml96
-rw-r--r--tests/manual/examples/quick/customtouchhandle/qml.qrc (renamed from examples/webenginequick/webengineaction/qml.qrc)0
-rw-r--r--tests/manual/examples/quick/minimal/CMakeLists.txt36
-rw-r--r--tests/manual/examples/quick/minimal/main.cpp19
-rw-r--r--tests/manual/examples/quick/minimal/main.qml16
-rw-r--r--tests/manual/examples/quick/minimal/minimal.pro (renamed from examples/webenginequick/minimal/minimal.pro)0
-rw-r--r--tests/manual/examples/quick/minimal/qml.qrc (renamed from examples/webenginequick/minimal/qml.qrc)0
-rw-r--r--tests/manual/examples/quick/webengineaction/CMakeLists.txt37
-rw-r--r--tests/manual/examples/quick/webengineaction/main.cpp25
-rw-r--r--tests/manual/examples/quick/webengineaction/main.qml (renamed from examples/webenginequick/webengineaction/main.qml)53
-rw-r--r--tests/manual/examples/quick/webengineaction/qml.qrc (renamed from tests/manual/quick/touchbrowser/qml.qrc)1
-rw-r--r--tests/manual/examples/quick/webengineaction/utils.h25
-rw-r--r--tests/manual/examples/quick/webengineaction/webengineaction.pro8
-rw-r--r--tests/manual/examples/widgets/CMakeLists.txt1
-rw-r--r--tests/manual/examples/widgets/minimal/CMakeLists.txt24
-rw-r--r--tests/manual/examples/widgets/minimal/main.cpp28
-rw-r--r--tests/manual/examples/widgets/minimal/minimal.pro (renamed from examples/webenginewidgets/minimal/minimal.pro)0
-rw-r--r--tests/manual/manual.pro7
-rw-r--r--tests/manual/quick/CMakeLists.txt2
-rw-r--r--tests/manual/quick/geopermission/CMakeLists.txt63
-rw-r--r--tests/manual/quick/geopermission/Info.plist32
-rw-r--r--tests/manual/quick/geopermission/geolocation.html32
-rw-r--r--tests/manual/quick/geopermission/main.cpp39
-rw-r--r--tests/manual/quick/geopermission/tst_geopermission.qml28
-rw-r--r--tests/manual/quick/pdf/bookmarks-list.qml136
-rw-r--r--tests/manual/quick/pdf/bookmarks.qml147
-rw-r--r--tests/manual/quick/pdf/gridview.qml62
-rw-r--r--tests/manual/quick/pdf/listview.qml58
-rw-r--r--tests/manual/quick/pdf/multipleDocuments.qml182
-rw-r--r--tests/manual/quick/pdf/pdfPageView.qml316
-rw-r--r--tests/manual/quick/pdf/pessimizedListView.qml69
-rw-r--r--tests/manual/quick/pdf/simplest.qml53
-rw-r--r--tests/manual/quick/pdf/test.pdfbin80045 -> 76633 bytes
-rw-r--r--tests/manual/quick/pdf/underscoredLinks.qml146
-rw-r--r--tests/manual/quick/pdf/withdoc.qml99
-rw-r--r--tests/manual/quick/quick.pro5
-rw-r--r--tests/manual/quick/touchbrowser/AddressBar.qml55
-rw-r--r--tests/manual/quick/touchbrowser/CMakeLists.txt31
-rw-r--r--tests/manual/quick/touchbrowser/MockTouchPoint.qml26
-rw-r--r--tests/manual/quick/touchbrowser/main.cpp68
-rw-r--r--tests/manual/quick/touchbrowser/main.qml35
-rw-r--r--tests/manual/quick/touchbrowser/resources.qrc7
-rw-r--r--tests/manual/quick/touchbrowser/touchbrowser.pro22
-rw-r--r--tests/manual/quick/touchbrowser/touchmockingapplication.cpp287
-rw-r--r--tests/manual/quick/touchbrowser/touchmockingapplication.h72
-rw-r--r--tests/manual/quick/touchbrowser/utils.h49
-rw-r--r--tests/manual/touchmocking/touchmockingapplication.cpp78
-rw-r--r--tests/manual/touchmocking/touchmockingapplication.h35
-rw-r--r--tests/manual/touchmocking/touchpoint.pngbin0 -> 1331 bytes
-rw-r--r--tests/manual/touchmocking/utils.h25
-rw-r--r--tests/manual/widgets/CMakeLists.txt9
-rw-r--r--tests/manual/widgets/geolocation/CMakeLists.txt55
-rw-r--r--tests/manual/widgets/geolocation/Info.plist32
-rw-r--r--tests/manual/widgets/geolocation/geolocation.html32
-rw-r--r--tests/manual/widgets/geolocation/main.cpp51
-rw-r--r--tests/manual/widgets/inputmethods/CMakeLists.txt37
-rw-r--r--tests/manual/widgets/inputmethods/colorpicker.cpp29
-rw-r--r--tests/manual/widgets/inputmethods/colorpicker.h31
-rw-r--r--tests/manual/widgets/inputmethods/controlview.cpp41
-rw-r--r--tests/manual/widgets/inputmethods/controlview.h41
-rw-r--r--tests/manual/widgets/inputmethods/main.cpp83
-rw-r--r--tests/manual/widgets/inputmethods/referenceview.cpp29
-rw-r--r--tests/manual/widgets/inputmethods/referenceview.h29
-rw-r--r--tests/manual/widgets/inputmethods/testview.cpp46
-rw-r--r--tests/manual/widgets/inputmethods/testview.h33
-rw-r--r--tests/manual/widgets/inputmethods/webview.cpp29
-rw-r--r--tests/manual/widgets/inputmethods/webview.h29
-rw-r--r--tests/manual/widgets/touchbrowser/CMakeLists.txt30
-rw-r--r--tests/manual/widgets/touchbrowser/main.cpp62
-rw-r--r--tests/manual/widgets/touchbrowser/resources.qrc5
-rw-r--r--tests/manual/widgets/touchbrowser/touchbrowser.pro15
-rw-r--r--tests/manual/widgets/webgl/CMakeLists.txt20
-rw-r--r--tests/manual/widgets/webgl/main.cpp29
-rw-r--r--tests/manual/widgets/webrtc/CMakeLists.txt24
-rw-r--r--tests/manual/widgets/webrtc/index.html86
-rw-r--r--tests/manual/widgets/webrtc/main.cpp112
-rw-r--r--tests/manual/widgets/webrtc/mediaPicker.ui118
-rw-r--r--tests/manual/widgets/webrtc/qrc.qrc5
-rw-r--r--tests/manual/widgets/widgets.pro5
-rw-r--r--tests/quicktestbrowser/ApplicationRoot.qml68
-rw-r--r--tests/quicktestbrowser/BrowserDialog.qml44
-rw-r--r--tests/quicktestbrowser/BrowserWindow.qml532
-rw-r--r--tests/quicktestbrowser/ButtonWithMenu.qml58
-rw-r--r--tests/quicktestbrowser/DownloadView.qml153
-rw-r--r--tests/quicktestbrowser/FeaturePermissionBar.qml92
-rw-r--r--tests/quicktestbrowser/FullScreenNotification.qml87
-rw-r--r--tests/quicktestbrowser/ZoomController.qml90
-rw-r--r--tests/quicktestbrowser/main.cpp96
-rw-r--r--tests/quicktestbrowser/quicktestbrowser.pro26
-rw-r--r--tests/quicktestbrowser/resources.qrc19
-rw-r--r--tests/quicktestbrowser/utils.h54
-rwxr-xr-xtools/buildscripts/qtwebengine_utils.py32
-rwxr-xr-xtools/buildscripts/repack_locales.py33
-rwxr-xr-xtools/scripts/check_patches.py30
-rw-r--r--tools/scripts/cipd_package.py103
-rwxr-xr-xtools/scripts/get_version.py30
-rw-r--r--tools/scripts/git_submodule.py104
-rw-r--r--tools/scripts/gn_find_mocables.py31
-rw-r--r--tools/scripts/gn_run_binary.py29
-rwxr-xr-xtools/scripts/init-repository.py64
-rwxr-xr-xtools/scripts/make_archive.sh30
-rwxr-xr-xtools/scripts/patch_upstream.py30
-rwxr-xr-xtools/scripts/take_snapshot.py216
-rwxr-xr-xtools/scripts/update_change_ids.py30
-rw-r--r--tools/scripts/version_resolver.py105
-rwxr-xr-xtools/scripts/windeploy-examples.py30
1462 files changed, 50023 insertions, 54085 deletions
diff --git a/.clang-format b/.clang-format
index 3399f428c..e7f5352cc 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,7 +1,5 @@
# Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
-#
-# You may use this file under the terms of the 3-clause BSD license.
-# See the file LICENSE from this package for details.
+# SPDX-License-Identifier: BSD-3-Clause
# This is the clang-format configuration style to be used by Qt,
# based on the rules from https://wiki.qt.io/Qt_Coding_Style and
@@ -11,7 +9,7 @@
# Webkit style was loosely based on the Qt style
BasedOnStyle: WebKit
-Standard: Cpp11
+Standard: c++17
# Column width is limited to 100 in accordance with Qt Coding Style.
# https://wiki.qt.io/Qt_Coding_Style
@@ -20,9 +18,10 @@ ColumnLimit: 100
# How much weight do extra characters after the line length limit have.
# PenaltyExcessCharacter: 4
-# Disable reflow of qdoc comments: indentation rules are different.
-# Translation comments are also excluded.
-CommentPragmas: "^!|^:"
+# Disable reflow of some specific comments
+# qdoc comments: indentation rules are different.
+# Translation comments and SPDX license identifiers are also excluded.
+CommentPragmas: "^!|^:|^ SPDX-License-Identifier:"
# We want a space between the type and the star for pointer types.
PointerBindsToType: false
@@ -60,7 +59,7 @@ ContinuationIndentWidth: 8
NamespaceIndentation: None
# Allow indentation for preprocessing directives (if/ifdef/endif). https://reviews.llvm.org/rL312125
-IndentPPDirectives: AfterHash
+# IndentPPDirectives: AfterHash - Redefined for QtWebEngine Qt Style
# Horizontally align arguments after an open bracket.
# The coding style does not specify the following, but this is what gives
@@ -82,7 +81,11 @@ SortIncludes: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
# Break constructor initializers before the colon and after the commas.
-BreakConstructorInitializers: BeforeColon
+# BreakConstructorInitializers: BeforeColon - Redefined for QtWebEngine Qt Style
+
+# Avoids the addition of a space between an identifier and the
+# initializer list in list-initialization.
+SpaceBeforeCpp11BracedList: false
################################################################################
# QtWebEngine specific changes to Qt style
@@ -90,6 +93,9 @@ BreakConstructorInitializers: BeforeColon
# We are using BeforeComma consistently so don't change it
BreakConstructorInitializers: BeforeComma
+# Disable indentation for preprocessing directives. Looks confusing at includes.
+IndentPPDirectives: None
+
# Chromium macros
MacroBlockBegin: "^\
IPC_BEGIN_MESSAGE_MAP|\
diff --git a/.cmake.conf b/.cmake.conf
index 75aec0703..8c2e0e672 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -1,2 +1,5 @@
-set(QT_REPO_MODULE_VERSION "6.3.0")
+set(QT_REPO_MODULE_VERSION "6.8.0")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
+set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19")
+set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")
+list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1")
diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION
index fbc223089..8bdc0df63 100644
--- a/CHROMIUM_VERSION
+++ b/CHROMIUM_VERSION
@@ -1,3 +1,3 @@
-Based on Chromium version: 90.0.4430.228
-Patched with security patches up to Chromium version: 94.0.4606.61
+Based on Chromium version: 118.0.5993.220
+Patched with security patches up to Chromium version: 122.0.6261.128
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0a0c7ffb..7d4638139 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,21 +1,32 @@
-cmake_minimum_required(VERSION 3.19)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Require the Qt (not WebEngine) minimum supported CMake version.
+# Another WebEngine-specific version check will be done in configure.cmake
+# and reported in the configure summary.
+cmake_minimum_required(VERSION 3.16)
include(.cmake.conf)
include(ExternalProject)
include(cmake/Functions.cmake)
-include(src/core/api/Qt6WebEngineCoreMacros.cmake)
+
+project(QtWebEngineDummy)
+find_package(Qt6 6.5 CONFIG REQUIRED COMPONENTS BuildInternals Core)
project(QtWebEngine
- VERSION "${QT_REPO_MODULE_VERSION}"
+ VERSION ${Qt6Core_VERSION}
DESCRIPTION "QtWebEngine and QtPdf modules"
HOMEPAGE_URL "https://qt.io/"
LANGUAGES CXX C
)
+qt_internal_project_setup()
-find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core)
find_package(Qt6 ${PROJECT_VERSION} CONFIG QUIET OPTIONAL_COMPONENTS
Gui Widgets Network OpenGL Quick Qml PrintSupport
- WebChannel Positioning QuickControls2 Test QuickWidgets QuickTest WebSockets Designer
+ WebChannel WebChannelQuick Positioning QuickControls2
+ Test QuickWidgets QuickTest WebSockets Designer
+ JpegPrivate PngPrivate HarfbuzzPrivate FreetypePrivate ZlibPrivate
+ HttpServer
)
if(MATRIX_BUILD AND NOT MATRIX_SUBBUILD AND NOT QT_SUPERBUILD)
diff --git a/LICENSE.GPL3-EXCEPT b/LICENSE.GPL3-EXCEPT
deleted file mode 100644
index b1cb1bec7..000000000
--- a/LICENSE.GPL3-EXCEPT
+++ /dev/null
@@ -1,704 +0,0 @@
-This is the GNU General Public License version 3, annotated with The
-Qt Company GPL Exception 1.0:
-
--------------------------------------------------------------------------
-
-The Qt Company GPL Exception 1.0
-
-Exception 1:
-
-As a special exception you may create a larger work which contains the
-output of this application and distribute that work under terms of your
-choice, so long as the work is not otherwise derived from or based on
-this application and so long as the work does not in itself generate
-output that contains the output from this application in its original
-or modified form.
-
-Exception 2:
-
-As a special exception, you have permission to combine this application
-with Plugins licensed under the terms of your choice, to produce an
-executable, and to copy and distribute the resulting executable under
-the terms of your choice. However, the executable must be accompanied
-by a prominent notice offering all users of the executable the entire
-source code to this application, excluding the source code of the
-independent modules, but including any changes you have made to this
-application, under the terms of this license.
-
-
--------------------------------------------------------------------------
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/LICENSE.GPLv3 b/LICENSE.GPLv3
deleted file mode 100644
index 71c4ad49c..000000000
--- a/LICENSE.GPLv3
+++ /dev/null
@@ -1,686 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
-
- The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd.
- Contact: http://www.qt.io/licensing/
-
- You may use, distribute and copy the Qt Toolkit under the terms of
- GNU Lesser General Public License version 3. That license references
- the General Public License version 3, that is displayed below. Other
- portions of the Qt Toolkit may be licensed directly under this license.
-
--------------------------------------------------------------------------
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3
deleted file mode 100644
index e200fb5b2..000000000
--- a/LICENSE.LGPLv3
+++ /dev/null
@@ -1,174 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
-
- The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd.
- Contact: http://www.qt.io/licensing/
-
- You may use, distribute and copy the Qt Toolkit under the terms of
- GNU Lesser General Public License version 3, which is displayed below.
- This license makes reference to the version 3 of the GNU General
- Public License, which you can find in the LICENSE.GPLv3 file.
-
--------------------------------------------------------------------------
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>
-Everyone is permitted to copy and distribute verbatim copies of this
-licensedocument, but changing it is not allowed.
-
-This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-0. Additional Definitions.
-
- As used herein, “this License†refers to version 3 of the GNU Lesser
-General Public License, and the “GNU GPL†refers to version 3 of the
-GNU General Public License.
-
- “The Library†refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An “Application†is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A “Combined Work†is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the “Linked
-Versionâ€.
-
- The “Minimal Corresponding Source†for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The “Corresponding Application Code†for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort
- to ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
-3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this
- license document.
-
-4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that, taken
-together, effectively do not restrict modification of the portions of
-the Library contained in the Combined Work and reverse engineering for
-debugging such modifications, if you also do each of the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this
- license document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of
- this License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with
- the Library. A suitable mechanism is one that (a) uses at run
- time a copy of the Library already present on the user's
- computer system, and (b) will operate properly with a modified
- version of the Library that is interface-compatible with the
- Linked Version.
-
- e) Provide Installation Information, but only if you would
- otherwise be required to provide such information under section 6
- of the GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the Application
- with a modified version of the Linked Version. (If you use option
- 4d0, the Installation Information must accompany the Minimal
- Corresponding Source and Corresponding Application Code. If you
- use option 4d1, you must provide the Installation Information in
- the manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.)
-
-5. Combined Libraries.
-
- You may place library facilities that are a work based on the Library
-side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities, conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of
- it is a work based on the Library, and explaining where to find
- the accompanying uncombined form of the same work.
-
-6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-as you received it specifies that a certain numbered version of the
-GNU Lesser General Public License “or any later version†applies to
-it, you have the option of following the terms and conditions either
-of that published version or of any later version published by the
-Free Software Foundation. If the Library as you received it does not
-specify a version number of the GNU Lesser General Public License,
-you may choose any version of the GNU Lesser General Public License
-ever published by the Free Software Foundation.
-
-If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the Library.
diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt
new file mode 100644
index 000000000..b91bbd894
--- /dev/null
+++ b/LICENSES/BSD-3-Clause.txt
@@ -0,0 +1,9 @@
+Copyright (c) <year> <owner>.
+
+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.
+ 3. Neither the name of the copyright holder 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 HOLDER 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.
diff --git a/LICENSE.FDL b/LICENSES/GFDL-1.3-no-invariants-only.txt
index 086177c0a..857214dd8 100644
--- a/LICENSE.FDL
+++ b/LICENSES/GFDL-1.3-no-invariants-only.txt
@@ -1,9 +1,10 @@
+
GNU Free Documentation License
Version 1.3, 3 November 2008
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
- <http://fsf.org/>
+ <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -376,7 +377,7 @@ The Free Software Foundation may publish new, revised versions of the
GNU Free Documentation License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in
detail to address new problems or concerns. See
-http://www.gnu.org/copyleft/.
+https://www.gnu.org/licenses/.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
diff --git a/LICENSE.GPL2 b/LICENSES/GPL-2.0-only.txt
index d159169d1..d159169d1 100644
--- a/LICENSE.GPL2
+++ b/LICENSES/GPL-2.0-only.txt
diff --git a/LICENSE.GPL3 b/LICENSES/GPL-3.0-only.txt
index 94a9ed024..94a9ed024 100644
--- a/LICENSE.GPL3
+++ b/LICENSES/GPL-3.0-only.txt
diff --git a/LICENSE.LGPL3 b/LICENSES/LGPL-3.0-only.txt
index 1f78e0508..65c5ca88a 100644
--- a/LICENSE.LGPL3
+++ b/LICENSES/LGPL-3.0-only.txt
@@ -1,15 +1,3 @@
- GNU LESSER GENERAL PUBLIC LICENSE
-
- The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd.
- Contact: http://www.qt.io/licensing/
-
- You may use, distribute and copy the Qt Toolkit under the terms of
- GNU Lesser General Public License version 3, which is displayed below.
- This license makes reference to the version 3 of the GNU General
- Public License, which you can find in the LICENSE.GPLv3 file.
-
--------------------------------------------------------------------------
-
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
diff --git a/LICENSES/LicenseRef-Qt-Commercial.txt b/LICENSES/LicenseRef-Qt-Commercial.txt
new file mode 100644
index 000000000..825b1f358
--- /dev/null
+++ b/LICENSES/LicenseRef-Qt-Commercial.txt
@@ -0,0 +1,8 @@
+Licensees holding valid commercial Qt licenses may use this software in
+accordance with the the terms contained in a written agreement between
+you and The Qt Company. Alternatively, the terms and conditions that were
+accepted by the licensee when buying and/or downloading the
+software do apply.
+
+For the latest licensing terms and conditions, see https://www.qt.io/terms-conditions.
+For further information use the contact form at https://www.qt.io/contact-us.
diff --git a/LICENSES/Qt-GPL-exception-1.0.txt b/LICENSES/Qt-GPL-exception-1.0.txt
new file mode 100644
index 000000000..d0322bf0e
--- /dev/null
+++ b/LICENSES/Qt-GPL-exception-1.0.txt
@@ -0,0 +1,22 @@
+The Qt Company GPL Exception 1.0
+
+Exception 1:
+
+As a special exception you may create a larger work which contains the
+output of this application and distribute that work under terms of your
+choice, so long as the work is not otherwise derived from or based on
+this application and so long as the work does not in itself generate
+output that contains the output from this application in its original
+or modified form.
+
+Exception 2:
+
+As a special exception, you have permission to combine this application
+with Plugins licensed under the terms of your choice, to produce an
+executable, and to copy and distribute the resulting executable under
+the terms of your choice. However, the executable must be accompanied
+by a prominent notice offering all users of the executable the entire
+source code to this application, excluding the source code of the
+independent modules, but including any changes you have made to this
+application, under the terms of this license.
+
diff --git a/cmake/FindGPerf.cmake b/cmake/FindGPerf.cmake
index 85b55f1b8..e42b8a372 100644
--- a/cmake/FindGPerf.cmake
+++ b/cmake/FindGPerf.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_program(GPerf_EXECUTABLE NAMES gperf)
include(FindPackageHandleStandardArgs)
diff --git a/cmake/FindGn.cmake b/cmake/FindGn.cmake
index 6bef6009e..fd03b7346 100644
--- a/cmake/FindGn.cmake
+++ b/cmake/FindGn.cmake
@@ -1,13 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(NOT DEFINED WEBENGINE_ROOT_BUILD_DIR)
set(WEBENGINE_ROOT_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
find_program(Gn_EXECUTABLE NAMES gn PATHS "${WEBENGINE_ROOT_BUILD_DIR}/install/bin" NO_DEFAULT_PATH)
if(NOT QT_HOST_PATH STREQUAL "")
find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_PATH}/${INSTALL_LIBEXECDIR} NO_DEFAULT_PATH)
-endif()
-# script mode does not have QT_HOST_PATH or INSTALL_LIBEXECDIR instead it uses QT_HOST_GN_PATH
-if(NOT QT_HOST_GN_PATH STREQUAL "")
- find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_GN_PATH} NO_DEFAULT_PATH)
+ # note: mingw installs with INSTALL_LIBEXECDIR = bin,
+ # however android on windows has INSTALL_LIBEXECDIR = libexec,
+ # so cover this case also
+ find_program(Gn_EXECUTABLE NAMES gn PATHS ${QT_HOST_PATH}/${INSTALL_BINDIR} NO_DEFAULT_PATH)
endif()
find_program(Gn_EXECUTABLE NAMES gn)
diff --git a/cmake/FindNinja.cmake b/cmake/FindNinja.cmake
index 720e73266..9b1e718c0 100644
--- a/cmake/FindNinja.cmake
+++ b/cmake/FindNinja.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT DEFINED WEBENGINE_ROOT_BUILD_DIR)
set(WEBENGINE_ROOT_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
endif()
diff --git a/cmake/FindNodejs.cmake b/cmake/FindNodejs.cmake
index 0e5efe4a3..00ce5696c 100644
--- a/cmake/FindNodejs.cmake
+++ b/cmake/FindNodejs.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_program(Nodejs_EXECUTABLE NAMES node nodejs)
if(Nodejs_EXECUTABLE)
@@ -6,6 +9,11 @@ if(Nodejs_EXECUTABLE)
OUTPUT_VARIABLE Nodejs_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(
+ COMMAND ${Nodejs_EXECUTABLE} -p "process.arch"
+ OUTPUT_VARIABLE Nodejs_ARCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
string (REGEX MATCHALL "([1-9][0-9])\..*" Nodejs_VERSION "${Nodejs_VERSION}")
diff --git a/cmake/FindPkgConfigHost.cmake b/cmake/FindPkgConfigHost.cmake
index de0216384..a7f9ab0ae 100644
--- a/cmake/FindPkgConfigHost.cmake
+++ b/cmake/FindPkgConfigHost.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# this is just simply pkg config wrapper to pass executable path to gn
if(CMAKE_CROSSCOMPILING)
diff --git a/cmake/FindSnappy.cmake b/cmake/FindSnappy.cmake
index 1470c55a9..e1c7d231b 100644
--- a/cmake/FindSnappy.cmake
+++ b/cmake/FindSnappy.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(TARGET Snappy::Snappy)
set(Snappy_FOUND TRUE)
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
index 6c7a49415..9864cf97b 100644
--- a/cmake/Functions.cmake
+++ b/cmake/Functions.cmake
@@ -1,7 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
function(assertTargets)
- qt_parse_all_arguments(arg "add_check_for_support"
- "" "" "MODULES;TARGETS" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "" "MODULES;TARGETS"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
+
foreach(module ${arg_MODULES})
if(NOT DEFINED ${module}_SUPPORT)
set(${module}_SUPPORT ON PARENT_SCOPE)
@@ -19,30 +24,20 @@ function(assertTargets)
endforeach()
endfunction()
-#TODO: remove me
-function(add_implicit_dependencies target)
- if(TARGET ${target})
- list(REMOVE_ITEM ARGN ${target})
- foreach(qtTarget IN ITEMS ${ARGN})
- if(TARGET Qt::${qtTarget})
- add_dependencies(${target} Qt::${qtTarget})
- endif()
- endforeach()
- endif()
-endfunction()
-
# TODO: this should be idealy in qtbase
function(add_check_for_support)
- qt_parse_all_arguments(arg "add_check_for_support"
- "" "" "MODULES;MESSAGE;CONDITION" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "" "MODULES;MESSAGE;CONDITION"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
+
foreach(module ${arg_MODULES})
if(NOT DEFINED ${module}_SUPPORT)
set(${module}_SUPPORT ON PARENT_SCOPE)
set(${module}_SUPPORT ON)
endif()
if(${module}_SUPPORT)
- if("x${arg_CONDITION}" STREQUAL x)
+ if("x${arg_CONDITION}" STREQUAL "x")
set(arg_CONDITION ON)
endif()
qt_evaluate_config_expression(result ${arg_CONDITION})
@@ -58,41 +53,42 @@ function(add_check_for_support)
endforeach()
endfunction()
-function(get_qt_features outList module)
- get_cmake_property(variableList VARIABLES)
- set(_featureList "")
- foreach (variableKey ${variableList})
- unset(FOUND)
- string(REGEX MATCH QT_FEATURE_${module} FOUND ${variableKey})
- if(FOUND)
- list(APPEND _featureList "${variableKey}=${${variableKey}}")
- endif()
- endforeach()
- if("${${outList}}" STREQUAL "")
- set(${outList} ${_featureList} PARENT_SCOPE)
- else()
- set(${outList} "${${outList}}" "${_featureList}" PARENT_SCOPE)
- endif()
-endfunction()
-
function(create_cxx_config cmakeTarget arch configFileName)
if(NOT QT_SUPERBUILD AND QT_WILL_INSTALL)
get_target_property(mocFilePath Qt6::moc IMPORTED_LOCATION)
else()
- set(mocFilePath "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/moc${CMAKE_EXECUTABLE_SUFFIX}")
+ if(CMAKE_CROSSCOMPILING)
+ set(mocFilePath "${QT_HOST_PATH}/${INSTALL_LIBEXECDIR}/moc${CMAKE_EXECUTABLE_SUFFIX}")
+ else()
+ set(mocFilePath "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/moc${CMAKE_EXECUTABLE_SUFFIX}")
+ endif()
endif()
file(GENERATE
- OUTPUT $<CONFIG>/${arch}/${configFileName}
- CONTENT "\
- set(GN_INCLUDES \"$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>\")\n\
- set(GN_DEFINES \"$<TARGET_PROPERTY:COMPILE_DEFINITIONS>\")\n\
- set(GN_LINK_OPTIONS \"$<TARGET_PROPERTY:LINK_OPTIONS>\")\n\
- set(GN_CXX_COMPILE_OPTIONS \"$<TARGET_PROPERTY:COMPILE_OPTIONS>\")\n\
- set(GN_MOC_PATH \"${mocFilePath}\")"
-# set(GN_LIBS $<TARGET_PROPERTY:LINK_LIBRARIES>)
- CONDITION $<COMPILE_LANGUAGE:CXX>
- TARGET ${cmakeTarget}
- )
+ OUTPUT $<CONFIG>/${arch}/${configFileName}
+ CONTENT "\
+ set(GN_INCLUDES \"$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>\")\n\
+ set(GN_DEFINES \"$<TARGET_PROPERTY:COMPILE_DEFINITIONS>\")\n\
+ set(GN_LINK_OPTIONS \"$<TARGET_PROPERTY:LINK_OPTIONS>\")\n\
+ set(GN_CXX_COMPILE_OPTIONS \"$<TARGET_PROPERTY:COMPILE_OPTIONS>\")\n\
+ set(GN_MOC_PATH \"${mocFilePath}\")"
+# set(GN_LIBS $<TARGET_PROPERTY:LINK_LIBRARIES>)
+ CONDITION $<COMPILE_LANGUAGE:CXX>
+ TARGET ${cmakeTarget}
+ )
+endfunction()
+
+function(create_static_config cmakeTarget arch configFileName)
+ list(APPEND libs Png Jpeg Harfbuzz Freetype Zlib)
+ foreach(lib IN LISTS libs)
+ string(TOUPPER ${lib} out)
+ set(lib Qt::${lib}Private)
+ list(APPEND contents "set(GN_${out}_INCLUDES \"$<$<STREQUAL:$<TARGET_NAME_IF_EXISTS:${lib}>,${lib}>:$<TARGET_PROPERTY:${lib},INTERFACE_INCLUDE_DIRECTORIES>>\")")
+ endforeach()
+ list(JOIN contents "\n" contents)
+ file(GENERATE
+ OUTPUT $<CONFIG>/${arch}/${configFileName}
+ CONTENT "${contents}"
+ )
endfunction()
function(create_c_config cmakeTarget arch configFileName)
@@ -160,8 +156,10 @@ endmacro()
function(extend_gn_target target)
get_target_property(elements ${target} ELEMENTS)
- qt_parse_all_arguments(GN "extend_gn_target" "" "" "CONDITION;${elements}" "${ARGN}")
- if("x${GN_CONDITION}" STREQUAL x)
+ cmake_parse_arguments(PARSE_ARGV 1 GN "" "" "CONDITION;${elements}")
+ _qt_internal_validate_all_args_are_parsed(GN)
+
+ if("x${GN_CONDITION}" STREQUAL "x")
set(GN_CONDITION ON)
endif()
qt_evaluate_config_expression(result ${GN_CONDITION})
@@ -172,8 +170,10 @@ function(extend_gn_target target)
endfunction()
function(extend_gn_list outList)
- qt_parse_all_arguments(GN "extend_gn_list" "" "" "ARGS;CONDITION" "${ARGN}")
- if("x${GN_CONDITION}" STREQUAL x)
+ cmake_parse_arguments(PARSE_ARGV 1 GN "" "" "ARGS;CONDITION")
+ _qt_internal_validate_all_args_are_parsed(GN)
+
+ if("x${GN_CONDITION}" STREQUAL "x")
set(GN_CONDITION ON)
endif()
qt_evaluate_config_expression(result ${GN_CONDITION})
@@ -193,10 +193,15 @@ function(configure_gn_target sourceDir inFilePath outFilePath)
# FIXME: GN_CONFIG
set(GN_CONFIG NOTUSED)
+ set(path_mode REALPATH)
+ if(APPLE AND QT_ALLOW_SYMLINK_IN_PATHS)
+ set(path_mode ABSOLUTE)
+ endif()
+
# GN_SOURCES GN_HEADERS
get_property(gnSources DIRECTORY PROPERTY GN_SOURCES)
foreach(gnSourceFile ${gnSources})
- get_filename_component(gnSourcePath ${sourceDir}/${gnSourceFile} REALPATH)
+ get_filename_component(gnSourcePath ${sourceDir}/${gnSourceFile} ${path_mode})
list(APPEND sourceList \"${gnSourcePath}\")
endforeach()
set(GN_HEADERS ${sourceList})
@@ -216,7 +221,7 @@ function(configure_gn_target sourceDir inFilePath outFilePath)
get_property(gnIncludes DIRECTORY PROPERTY GN_INCLUDES)
list(REMOVE_DUPLICATES gnIncludes)
foreach(gnInclude ${gnIncludes})
- get_filename_component(gnInclude ${gnInclude} REALPATH)
+ get_filename_component(gnInclude ${gnInclude} ${path_mode})
list(APPEND GN_ARGS_INCLUDES \"-I${gnInclude}\")
list(APPEND GN_INCLUDE_DIRS \"${gnInclude}\")
endforeach()
@@ -240,17 +245,23 @@ function(configure_gn_target sourceDir inFilePath outFilePath)
list(REMOVE_DUPLICATES GN_CFLAGS_C)
# GN_SOURCE_ROOT
- get_filename_component(GN_SOURCE_ROOT "${sourceDir}" REALPATH)
-
- # GN_RSP_PREFIX
- get_property(GN_RSP_PREFIX DIRECTORY PROPERTY GN_RSP_PREFIX)
+ get_filename_component(GN_SOURCE_ROOT "${sourceDir}" ${path_mode})
if(APPLE) # this runs in scrpit mode without qt-cmake so on MACOS here
recoverFrameworkBuild(GN_INCLUDE_DIRS GN_CFLAGS_C)
endif()
+ # Static setup
+ set(libs PNG JPEG FREETYPE HARFBUZZ ZLIB)
+ foreach(lib ${libs})
+ get_property(staticIncludes DIRECTORY PROPERTY GN_${lib}_INCLUDES)
+ foreach(is ${staticIncludes})
+ list(APPEND GN_${lib}_INCLUDES \"${is}\")
+ endforeach()
+ endforeach()
foreach(item GN_HEADERS GN_SOURCES GN_ARGS_DEFINES GN_DEFINES GN_ARGS_INCLUDES
- GN_INCLUDE_DIRS GN_CFLAGS_CC GN_CFLAGS_C)
+ GN_INCLUDE_DIRS GN_CFLAGS_CC GN_CFLAGS_C GN_PNG_INCLUDES GN_JPEG_INCLUDES
+ GN_FREETYPE_INCLUDES GN_HARFBUZZ_INCLUDES GN_ZLIB_INCLUDES)
string(REPLACE ";" ",\n " ${item} "${${item}}")
endforeach()
configure_file(${inFilePath} ${outFilePath} @ONLY)
@@ -276,7 +287,7 @@ function(get_install_config result)
set(${result} "Release" PARENT_SCOPE)
elseif("RelWithDebInfo" IN_LIST CMAKE_CONFIGURATION_TYPES)
set(${result} "RelWithDebInfo" PARENT_SCOPE)
- elseif("Debug" IN_LIST CMAKE_CONFIGURATION_TYPE)
+ elseif("Debug" IN_LIST CMAKE_CONFIGURATION_TYPES)
set(${result} "Debug" PARENT_SCOPE)
else()
# assume MinSizeRel ?
@@ -285,13 +296,6 @@ function(get_install_config result)
endif()
endfunction()
-macro(assertRunAsTopLevelBuild)
- if(NOT DEFINED WEBENGINE_REPO_BUILD)
- message(FATAL_ERROR "This cmake file should run as top level build.")
- return()
- endif()
-endmacro()
-
# we need to pass -F or -iframework in case of frameworks builds, which gn treats as
# compiler flag and cmake as include dir, so swap it.
function(recoverFrameworkBuild includeDirs compilerFlags)
@@ -341,45 +345,67 @@ function(get_darwin_sdk_version result)
endif()
endfunction()
-function(add_ninja_target target cmakeTarget ninjaTarget config arch buildDir)
- string(TOUPPER ${config} cfg)
- add_custom_target(${target} DEPENDS ${buildDir}/${config}/${arch}/${ninjaTarget}.stamp)
- set_target_properties(${target} PROPERTIES
- CONFIG ${config}
- ARCH ${arch}
- CMAKE_TARGET ${cmakeTarget}
- NINJA_TARGET ${ninjaTarget}
+function(get_ios_target_triple_and_sysroot result arch)
+ get_ios_sysroot(sysroot ${arch})
+ set(${result}
+ -target ${arch}-apple-ios${CMAKE_OSX_DEPLOYMENT_TARGET}
+ -isysroot ${sysroot} PARENT_SCOPE
)
endfunction()
-function(copy_response_files target)
+function(add_ninja_target)
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "TARGET;CMAKE_TARGET;NINJA_TARGET;BUILDDIR;NINJA_STAMP;NINJA_DATA_STAMP;CONFIG;ARCH" ""
+ )
+ _qt_internal_validate_all_args_are_parsed(arg)
+ set(stamps ${arg_NINJA_STAMP} ${arg_NINJA_DATA_STAMP})
+ list(TRANSFORM stamps PREPEND "${arg_BUILDDIR}/${arg_CONFIG}/${arg_ARCH}/")
+ add_custom_target(${arg_TARGET} DEPENDS ${stamps})
+ set_target_properties(${arg_TARGET} PROPERTIES
+ CONFIG ${arg_CONFIG}
+ ARCH ${arg_ARCH}
+ CMAKE_TARGET ${arg_CMAKE_TARGET}
+ NINJA_TARGET ${arg_NINJA_TARGET}
+ NINJA_STAMP ${arg_NINJA_STAMP}
+ )
+endfunction()
+
+function(get_copy_of_response_file result target rsp)
get_target_property(config ${target} CONFIG)
get_target_property(ninjaTarget ${target} NINJA_TARGET)
get_target_property(cmakeTarget ${target} CMAKE_TARGET)
- list(REMOVE_ITEM ARGN ${target})
- foreach(rsp IN ITEMS ${ARGN})
- set(rsp_dst "CMakeFiles_${ninjaTarget}_${config}_${rsp}.rsp")
- set(rsp_src "${${rsp}_rsp}")
- if(NOT QT_SUPERBUILD)
- set(rsp_output ${PROJECT_BINARY_DIR}/${rsp_dst})
- else()
- set(rsp_output ${PROJECT_BINARY_DIR}/../${rsp_dst})
- endif()
- add_custom_command(
- OUTPUT ${rsp_output}
- COMMAND ${CMAKE_COMMAND} -E copy ${rsp_src} ${rsp_output}
- DEPENDS ${rsp_src}
- USES_TERMINAL
- )
- set(${rsp}_rsp ${rsp_dst} PARENT_SCOPE)
- add_custom_target(${cmakeTarget}_${rsp}_copy_${config}
- DEPENDS ${rsp_output}
- )
- add_dependencies(${cmakeTarget} ${cmakeTarget}_${rsp}_copy_${config})
- endforeach()
+ set(rsp_dst "CMakeFiles_${ninjaTarget}_${config}_${rsp}.rsp")
+ set(rsp_src "${${result}}")
+ if(NOT QT_SUPERBUILD)
+ set(rsp_output ${PROJECT_BINARY_DIR}/${rsp_dst})
+ else()
+ set(rsp_output ${PROJECT_BINARY_DIR}/../${rsp_dst})
+ endif()
+ add_custom_command(
+ OUTPUT ${rsp_output}
+ COMMAND ${CMAKE_COMMAND} -E copy ${rsp_src} ${rsp_output}
+ DEPENDS ${rsp_src}
+ USES_TERMINAL
+ )
+ set(${result} ${rsp_dst} PARENT_SCOPE)
+ add_custom_target(${cmakeTarget}_${rsp}_copy_${config}
+ DEPENDS ${rsp_output}
+ )
+ add_dependencies(${cmakeTarget} ${cmakeTarget}_${rsp}_copy_${config})
endfunction()
-function(extend_cmake_target target buildDir)
+function(add_archiver_options target buildDir completeStatic)
+ get_target_property(config ${target} CONFIG)
+ string(TOUPPER ${config} cfg)
+ get_target_property(ninjaTarget ${target} NINJA_TARGET)
+ get_target_property(cmakeTarget ${target} CMAKE_TARGET)
+ set(objects_out "${buildDir}/${cmakeTarget}_objects.o")
+ add_library(GnObject_${cmakeTarget}_${config} OBJECT IMPORTED GLOBAL)
+ target_link_libraries(${cmakeTarget} PRIVATE $<$<CONFIG:${config}>:GnObject_${cmakeTarget}_${config}>)
+ set_property(TARGET GnObject_${cmakeTarget}_${config} PROPERTY IMPORTED_OBJECTS_${cfg} ${objects_out})
+endfunction()
+
+function(add_linker_options target buildDir completeStatic)
get_target_property(config ${target} CONFIG)
get_target_property(ninjaTarget ${target} NINJA_TARGET)
get_target_property(cmakeTarget ${target} CMAKE_TARGET)
@@ -388,96 +414,184 @@ function(extend_cmake_target target buildDir)
set(objects_rsp "${buildDir}/${ninjaTarget}_objects.rsp")
set(archives_rsp "${buildDir}/${ninjaTarget}_archives.rsp")
set(libs_rsp "${buildDir}/${ninjaTarget}_libs.rsp")
- if(LINUX)
- target_link_options(${cmakeTarget} PRIVATE
- "$<$<CONFIG:${config}>:@${objects_rsp}>"
- )
- target_link_libraries(${cmakeTarget} PRIVATE
- "-Wl,--start-group $<$<CONFIG:${config}>:@${archives_rsp}> -Wl,--end-group"
- )
+ set(ldir_rsp "${buildDir}/${ninjaTarget}_ldir.rsp")
+ set_target_properties(${cmakeTarget} PROPERTIES STATIC_LIBRARY_OPTIONS "@${objects_rsp}")
+ if(LINUX OR ANDROID)
+ get_gn_arch(cpu ${TEST_architecture_arch})
+ if(CMAKE_CROSSCOMPILING AND cpu STREQUAL "arm" AND ${config} STREQUAL "Debug")
+ target_link_options(${cmakeTarget} PRIVATE "LINKER:--long-plt")
+ endif()
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${objects_rsp}>")
+ # Chromium is meant for linking with gc-sections, which seems to not always get applied otherwise
+ target_link_options(${cmakeTarget} PRIVATE "-Wl,--gc-sections")
+ if(NOT completeStatic)
+ target_link_libraries(${cmakeTarget} PRIVATE
+ "$<1:-Wl,--start-group $<$<CONFIG:${config}>:@${archives_rsp}> -Wl,--end-group>"
+ )
+ endif()
+
# linker here options are just to prevent processing it by cmake
target_link_libraries(${cmakeTarget} PRIVATE
- "-Wl,--no-fatal-warnings $<$<CONFIG:${config}>:@${libs_rsp}> -Wl,--no-fatal-warnings"
+ "$<1:-Wl,--no-fatal-warnings $<$<CONFIG:${config}>:@${ldir_rsp}> $<$<CONFIG:${config}>:@${libs_rsp}> -Wl,--no-fatal-warnings>"
)
-
+ unset(cpu)
endif()
if(MACOS)
- target_link_options(${cmakeTarget} PRIVATE
- "$<$<CONFIG:${config}>:@${objects_rsp}>"
- "$<$<CONFIG:${config}>:@${archives_rsp}>"
- "$<$<CONFIG:${config}>:@${libs_rsp}>"
- )
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${objects_rsp}>")
+ if(NOT completeStatic)
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${archives_rsp}>")
+ endif()
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${ldir_rsp}>" "$<$<CONFIG:${config}>:@${libs_rsp}>")
endif()
if(WIN32)
- copy_response_files(${target} objects archives libs)
- target_link_options(${cmakeTarget} PRIVATE
- "$<$<CONFIG:${config}>:@${objects_rsp}>"
- "$<$<CONFIG:${config}>:@${archives_rsp}>"
- "$<$<CONFIG:${config}>:@${libs_rsp}>"
- )
+ get_copy_of_response_file(objects_rsp ${target} objects)
+ if(NOT MINGW)
+ target_link_options(${cmakeTarget}
+ PRIVATE /DELAYLOAD:mf.dll /DELAYLOAD:mfplat.dll /DELAYLOAD:mfreadwrite.dll /DELAYLOAD:winmm.dll
+ )
+ # enable larger PDBs if webenginecore debug build
+ if(cmakeTarget STREQUAL "WebEngineCore")
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:Debug>:/pdbpagesize:8192>")
+ endif()
+ endif()
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${objects_rsp}>")
+ if(NOT completeStatic)
+ get_copy_of_response_file(archives_rsp ${target} archives)
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${archives_rsp}>")
+ endif()
+ get_copy_of_response_file(libs_rsp ${target} libs)
+ target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${libs_rsp}>")
# we need libs rsp also when linking process with sandbox lib
set_property(TARGET ${cmakeTarget} PROPERTY LIBS_RSP ${libs_rsp})
endif()
endfunction()
-function(add_rsp_command target buildDir)
+function(add_intermediate_archive target buildDir completeStatic)
get_target_property(config ${target} CONFIG)
get_target_property(arch ${target} ARCH)
get_target_property(ninjaTarget ${target} NINJA_TARGET)
get_target_property(cmakeTarget ${target} CMAKE_TARGET)
+ get_target_property(ninjaStamp ${target} NINJA_STAMP)
string(TOUPPER ${config} cfg)
+ set(objects_rsp "${buildDir}/${ninjaTarget}_objects.rsp")
+ set(objects_out "${buildDir}/${cmakeTarget}_objects.o")
+ if(NOT completeStatic)
+ set(archives_rsp "${buildDir}/${ninjaTarget}_archives.rsp")
+ set(archives_out "${buildDir}/${cmakeTarget}_archives.o")
+ set(archives_command
+ COMMAND clang++ -r -nostdlib -arch ${arch}
+ -o ${archives_out}
+ -Wl,-keep_private_externs
+ -Wl,-all_load
+ @${archives_rsp}
+ )
+ endif()
add_custom_command(
OUTPUT ${buildDir}/${cmakeTarget}.a
- BYPRODUCTS
- ${buildDir}/${cmakeTarget}.o
+ BYPRODUCTS ${objects_out} ${archives_out}
COMMAND clang++ -r -nostdlib -arch ${arch}
- -o ${buildDir}/${cmakeTarget}.o
+ -o ${objects_out}
-Wl,-keep_private_externs
- @${buildDir}/${ninjaTarget}_objects.rsp
- -Wl,-all_load
- @${buildDir}/${ninjaTarget}_archives.rsp
- COMMAND ar -cr
+ @${objects_rsp}
+ ${archives_command}
+ COMMAND ar -crs
${buildDir}/${cmakeTarget}.a
- ${buildDir}/${cmakeTarget}.o
+ ${objects_out}
+ ${archives_out}
DEPENDS
- ${buildDir}/${ninjaTarget}.stamp
+ ${buildDir}/${ninjaStamp}
WORKING_DIRECTORY "${buildDir}/../../.."
+ COMMENT "Creating intermediate archives for ${cmakeTarget}/${config}/${arch}"
USES_TERMINAL
VERBATIM
COMMAND_EXPAND_LISTS
)
endfunction()
-function(add_lipo_command target buildDir)
+function(add_intermediate_object target buildDir completeStatic)
get_target_property(config ${target} CONFIG)
+ get_target_property(arch ${target} ARCH)
+ get_target_property(ninjaTarget ${target} NINJA_TARGET)
get_target_property(cmakeTarget ${target} CMAKE_TARGET)
- set(libs_rsp "${buildDir}/x86_64/${ninjaTarget}_libs.rsp")
- # Lipo the object files together to a single fat archive
- add_library(${cmakeTarget}_${config} STATIC IMPORTED GLOBAL)
+ get_target_property(ninjaStamp ${target} NINJA_STAMP)
+ string(TOUPPER ${config} cfg)
+ if(IOS)
+ get_ios_target_triple_and_sysroot(args ${arch})
+ endif()
+ set(objects_rsp "${buildDir}/${ninjaTarget}_objects.rsp")
+ set(objects_out "${buildDir}/${cmakeTarget}_objects.o")
add_custom_command(
- OUTPUT ${buildDir}/lib${cmakeTarget}.a
- COMMAND lipo -create
- -output ${buildDir}/lib${cmakeTarget}.a
- ARGS
- ${buildDir}/arm64/${cmakeTarget}.a
- ${buildDir}/x86_64/${cmakeTarget}.a
+ OUTPUT ${objects_out}
+ COMMAND clang++ -r -nostdlib
+ ${args}
+ -o ${objects_out}
+ -Wl,-keep_private_externs
+ @${objects_rsp}
DEPENDS
- ${buildDir}/arm64/${cmakeTarget}.a
- ${buildDir}/x86_64/${cmakeTarget}.a
+ ${buildDir}/${ninjaStamp}
+ WORKING_DIRECTORY "${buildDir}/../../.."
+ COMMENT "Creating intermediate object files for ${cmakeTarget}/${config}/${arch}"
USES_TERMINAL
VERBATIM
+ COMMAND_EXPAND_LISTS
)
+endfunction()
+
+# Lipo the object files together to a single fat archive
+function(create_lipo_command target buildDir fileName)
+ get_target_property(config ${target} CONFIG)
+ get_architectures(archs)
+ foreach(arch ${archs})
+ list(APPEND lipo_objects ${buildDir}/${arch}/${fileName})
+ endforeach()
+ add_custom_command(
+ OUTPUT ${buildDir}/${fileName}
+ COMMAND lipo -create
+ -output ${buildDir}/${fileName}
+ ARGS ${lipo_objects}
+ DEPENDS ${lipo_objects}
+ USES_TERMINAL
+ COMMENT "Running lipo for ${target}/${config}/${arch}"
+ VERBATIM
+ )
+endfunction()
+
+# this function only deals with objects as it is only
+# used by qtpdf and we do not need anything more
+function(add_ios_lipo_command target buildDir)
+ get_target_property(config ${target} CONFIG)
+ get_target_property(cmakeTarget ${target} CMAKE_TARGET)
+ set(fileName ${cmakeTarget}_objects.o)
+ create_lipo_command(${target} ${buildDir} ${fileName})
+ add_custom_target(lipo_${cmakeTarget}_${config} DEPENDS
+ ${buildDir}/${fileName}
+ )
+ add_dependencies(${cmakeTarget} lipo_${cmakeTarget}_${config})
+ qt_internal_get_target_property(options ${cmakeTarget} STATIC_LIBRARY_OPTIONS)
+ set_target_properties(${cmakeTarget} PROPERTIES STATIC_LIBRARY_OPTIONS
+ "${options}$<$<CONFIG:${config}>:${buildDir}/${fileName}>"
+ )
+endfunction()
+
+function(add_lipo_command target buildDir)
+ get_target_property(config ${target} CONFIG)
+ get_target_property(cmakeTarget ${target} CMAKE_TARGET)
+ get_target_property(ninjaTarget ${target} NINJA_TARGET)
+ set(fileName ${cmakeTarget}.a)
+ create_lipo_command(${target} ${buildDir} ${fileName})
+ add_library(${cmakeTarget}_${config} STATIC IMPORTED GLOBAL)
set_property(TARGET ${cmakeTarget}_${config}
- PROPERTY IMPORTED_LOCATION ${buildDir}/lib${cmakeTarget}.a
+ PROPERTY IMPORTED_LOCATION ${buildDir}/${fileName}
)
add_custom_target(lipo_${cmakeTarget}_${config} DEPENDS
- ${buildDir}/lib${cmakeTarget}.a
+ ${buildDir}/${fileName}
)
add_dependencies(${cmakeTarget}_${config} lipo_${cmakeTarget}_${config})
target_link_libraries(${cmakeTarget} PRIVATE ${cmakeTarget}_${config})
# Just link with dynamic libs once
# TODO: this is evil hack, since cmake has no idea about libs
+ set(libs_rsp "${buildDir}/x86_64/${ninjaTarget}_libs.rsp")
target_link_options(${cmakeTarget} PRIVATE "$<$<CONFIG:${config}>:@${libs_rsp}>")
endfunction()
@@ -501,40 +615,50 @@ function(qt_internal_add_external_project_dependency_to_root_project name)
cmake_policy(POP)
endfunction()
+# Function maps TEST_architecture_arch or CMAKE_SYSTEM_PROCESSOR into gn architecture
function(get_gn_arch result arch)
- if(arch STREQUAL "i386")
+ set(armList arm armv7-a)
+ set(mips64List mips64 mipsel64)
+ set(x86List i386 i686)
+ set(x64List x86_64 AMD64 x86_64h aarch64)
+ if(arch IN_LIST x86List)
set(${result} "x86" PARENT_SCOPE)
- elseif(arch STREQUAL "x86_64")
+ elseif(arch IN_LIST x64List)
set(${result} "x64" PARENT_SCOPE)
- elseif(arch STREQUAL "arm")
+ elseif(arch IN_LIST armList)
set(${result} "arm" PARENT_SCOPE)
elseif(arch STREQUAL "arm64")
set(${result} "arm64" PARENT_SCOPE)
elseif(arch STREQUAL "mipsel")
set(${result} "mipsel" PARENT_SCOPE)
- elseif(arch STREQUAL "mipsel64")
+ elseif(arch IN_LIST mipsList)
set(${result} "mips64el" PARENT_SCOPE)
+ elseif(arch STREQUAL "riscv64")
+ set(${result} "riscv64" PARENT_SCOPE)
else()
- message(DEBUG "Unsupported architecture: ${arch}")
+ message(FATAL_ERROR "Unknown architecture: ${arch}")
endif()
endfunction()
+# Function maps gn architecture for v8
function(get_v8_arch result targetArch hostArch)
- set(list32 i386 arm mipsel)
+ set(list32 x86 arm mipsel riscv32)
if(hostArch STREQUAL targetArch)
set(${result} "${targetArch}" PARENT_SCOPE)
elseif(targetArch IN_LIST list32)
# 32bit target which needs a 32bit compatible host
- if(hostArch STREQUAL "x86_64")
- set(${result} "i386" PARENT_SCOPE)
+ if(hostArch STREQUAL "x64")
+ set(${result} "x86" PARENT_SCOPE)
elseif(hostArch STREQUAL "arm64")
set(${result} "arm" PARENT_SCOPE)
- elseif(hostArch STREQUAL "mips64")
- set(${result} "mipsel" PARENT_SCOPE)
- elseif(hostArch STREQUAL "mipsel64")
+ elseif(hostArch STREQUAL "mips64el")
set(${result} "mipsel" PARENT_SCOPE)
+ elseif(hostArch STREQUAL "riscv64")
+ set(${result} "riscv32" PARENT_SCOPE)
+ elseif(hostArch IN_LIST list32)
+ set(${result} "${hostArch}" PARENT_SCOPE)
else()
- message(DEBUG "Unsupported architecture: ${hostArch}")
+ message(FATAL_ERROR "Unknown architecture: ${hostArch}")
endif()
else()
# assume 64bit target which matches 64bit host
@@ -564,12 +688,35 @@ function(get_gn_is_clang result)
endif()
endfunction()
-function(configure_gn_toolchain name binTargetCpu v8TargetCpu toolchainIn toolchainOut)
+
+function(get_gn_is_mingw result)
+ if(MINGW)
+ set(${result} "true" PARENT_SCOPE)
+ else()
+ set(${result} "false" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(get_ios_sysroot result arch)
+ if(NOT CMAKE_APPLE_ARCH_SYSROOTS)
+ message(FATAL_ERROR "CMAKE_APPLE_ARCH_SYSROOTS not set.")
+ endif()
+ get_architectures(archs)
+ list(FIND archs ${arch} known_arch)
+ if (known_arch EQUAL "-1")
+ message(FATAL_ERROR "Unknown iOS architecture ${arch}.")
+ endif()
+ list(GET CMAKE_APPLE_ARCH_SYSROOTS ${known_arch} sysroot)
+ set(${result} ${sysroot} PARENT_SCOPE)
+endfunction()
+
+function(configure_gn_toolchain name cpu v8Cpu toolchainIn toolchainOut)
set(GN_TOOLCHAIN ${name})
get_gn_os(GN_OS)
get_gn_is_clang(GN_IS_CLANG)
- get_gn_arch(GN_CPU ${binTargetCpu})
- get_gn_arch(GN_V8_CPU ${v8TargetCpu})
+ get_gn_is_mingw(GN_IS_MINGW)
+ set(GN_CPU ${cpu})
+ set(GN_V8_CPU ${v8Cpu})
configure_file(${toolchainIn} ${toolchainOut}/BUILD.gn @ONLY)
endfunction()
@@ -605,7 +752,9 @@ function(extract_cflag result cflag)
endfunction()
function(extend_gn_list_cflag outList)
- qt_parse_all_arguments(GN "extend_gn_list_cflag" "" "" "ARG;CFLAG" "${ARGN}")
+ cmake_parse_arguments(PARSE_ARGV 1 GN "" "" "ARG;CFLAG")
+ _qt_internal_validate_all_args_are_parsed(GN)
+
extract_cflag(cflag "${GN_CFLAG}")
if(cflag)
set(${outList} "${${outList}}" "${GN_ARG}=\"${cflag}\"" PARENT_SCOPE)
@@ -649,37 +798,40 @@ macro(create_pkg_config_host_wrapper buildDir)
endmacro()
macro(setup_toolchains)
+ get_gn_arch(gn_arch ${TEST_architecture_arch})
if(NOT CMAKE_CROSSCOMPILING) # delivered by hostBuild project
- configure_gn_toolchain(host ${TEST_architecture_arch} ${TEST_architecture_arch}
+ configure_gn_toolchain(host ${gn_arch} ${gn_arch}
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
${buildDir}/host_toolchain)
- configure_gn_toolchain(v8 ${TEST_architecture_arch} ${TEST_architecture_arch}
+ configure_gn_toolchain(v8 ${gn_arch} ${gn_arch}
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
${buildDir}/v8_toolchain)
endif()
- configure_gn_toolchain(target ${TEST_architecture_arch} ${TEST_architecture_arch}
+ configure_gn_toolchain(target ${gn_arch} ${gn_arch}
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
${buildDir}/target_toolchain)
+ unset(gn_arch)
endmacro()
macro(append_build_type_setup)
list(APPEND gnArgArg
- use_qt=true
+ is_qtwebengine=true
init_stack_vars=false
is_component_build=false
is_shared=true
use_sysroot=false
forbid_non_component_debug_builds=false
- enable_debugallocation=false
treat_warnings_as_errors=false
use_allocator_shim=false
- use_allocator="none"
+ use_partition_alloc=true
+ use_partition_alloc_as_malloc=false
use_custom_libcxx=false
+ enable_rust=false # We do not yet support rust
)
if(${config} STREQUAL "Debug")
list(APPEND gnArgArg is_debug=true symbol_level=2)
if(WIN32)
- list(APPEND gnArgArg enable_iterator_debugging=true v8_optimized_debug=false)
+ list(APPEND gnArgArg enable_iterator_debugging=true)
endif()
elseif(${config} STREQUAL "Release")
list(APPEND gnArgArg is_debug=false symbol_level=0)
@@ -696,7 +848,7 @@ macro(append_build_type_setup)
if(FEATURE_developer_build OR (${config} STREQUAL "Debug") OR QT_FEATURE_webengine_sanitizer)
list(APPEND gnArgArg
is_official_build=false
- from_here_uses_location_builtins=false
+ use_viz_debugger=false
)
else()
list(APPEND gnArgArg is_official_build=true)
@@ -711,8 +863,9 @@ macro(append_build_type_setup)
CONDITION FEATURE_developer_build
)
- if(NOT QT_FEATURE_webengine_full_debug_info)
- list(APPEND gnArgArg blink_symbol_level=0 remove_v8base_debug_symbols=true)
+ #TODO: refactor to not check for IOS here
+ if(NOT QT_FEATURE_webengine_full_debug_info AND NOT IOS)
+ list(APPEND gnArgArg blink_symbol_level=0 v8_symbol_level=0)
endif()
extend_gn_list(gnArgArg ARGS use_jumbo_build CONDITION QT_FEATURE_webengine_jumbo_build)
@@ -725,7 +878,7 @@ macro(append_build_type_setup)
extend_gn_list(gnArgArg
ARGS enable_precompiled_headers
- CONDITION BUILD_WITH_PCH
+ CONDITION BUILD_WITH_PCH AND NOT LINUX
)
extend_gn_list(gnArgArg
ARGS dcheck_always_on
@@ -739,6 +892,10 @@ macro(append_compiler_linker_sdk_setup)
endif()
extend_gn_list(gnArgArg ARGS is_clang CONDITION CLANG)
+ extend_gn_list(gnArgArg ARGS is_mingw CONDITION MINGW)
+ extend_gn_list(gnArgArg ARGS is_msvc CONDITION MSVC)
+ extend_gn_list(gnArgArg ARGS is_gcc CONDITION LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+
if(CLANG)
if(MACOS)
get_darwin_sdk_version(macSdkVersion)
@@ -750,9 +907,11 @@ macro(append_compiler_linker_sdk_setup)
get_filename_component(clangBasePath ${clangBasePath} DIRECTORY)
endif()
+ string(REGEX MATCH "[0-9]+" clangVersion ${CMAKE_CXX_COMPILER_VERSION})
list(APPEND gnArgArg
clang_base_path="${clangBasePath}"
clang_use_chrome_plugins=false
+ clang_version=${clangVersion}
fatal_linker_warnings=false
)
@@ -761,6 +920,29 @@ macro(append_compiler_linker_sdk_setup)
use_system_xcode=true
mac_deployment_target="${CMAKE_OSX_DEPLOYMENT_TARGET}"
mac_sdk_min="${macSdkVersion}"
+ use_libcxx=true
+ )
+ endif()
+ if(IOS)
+ list(APPEND gnArgArg
+ use_system_xcode=true
+ enable_ios_bitcode=true
+ ios_deployment_target="${CMAKE_OSX_DEPLOYMENT_TARGET}"
+ ios_enable_code_signing=false
+ use_libcxx=true
+ )
+ endif()
+ if(DEFINED QT_FEATURE_stdlib_libcpp AND LINUX)
+ extend_gn_list(gnArgArg ARGS use_libcxx
+ CONDITION QT_FEATURE_stdlib_libcpp
+ )
+ endif()
+ if(ANDROID)
+ list(APPEND gnArgArg
+ android_ndk_root="${CMAKE_ANDROID_NDK}"
+ android_ndk_version="${CMAKE_ANDROID_NDK_VERSION}"
+ clang_use_default_sample_profile=false
+ #android_ndk_major_version=22
)
endif()
else()
@@ -774,14 +956,16 @@ macro(append_compiler_linker_sdk_setup)
endif()
endif()
- if(WIN32)
- get_filename_component(windowsSdkPath $ENV{WINDOWSSDKDIR} DIRECTORY)
- get_filename_component(visualStudioPath $ENV{VSINSTALLDIR} DIRECTORY)
+ if(MSVC)
+ get_filename_component(windowsSdkPath $ENV{WINDOWSSDKDIR} ABSOLUTE)
+ get_filename_component(visualStudioPath $ENV{VSINSTALLDIR} ABSOLUTE)
+ set(windowSdkVersion $ENV{WindowsSDKVersion})
list(APPEND gnArgArg
win_linker_timing=true
use_incremental_linking=false
- visual_studio_version=2019
+ visual_studio_version=2022
visual_studio_path=\"${visualStudioPath}\"
+ windows_sdk_version=\"${windowsSdkVersion}\"
windows_sdk_path=\"${windowsSdkPath}\"
)
endif()
@@ -815,6 +999,11 @@ macro(append_compiler_linker_sdk_setup)
# we use arm_neon_optional for ARMv7
list(APPEND gnArgArg arm_optionally_use_neon=true)
endif()
+ extract_cflag(march "march")
+ get_arm_version(arm_version ${march})
+ if(arm_version EQUAL 7)
+ list(APPEND gnArgArg use_arm_crc32=false)
+ endif()
check_thumb(armThumb)
extend_gn_list(gnArgArg
ARGS arm_use_thumb
@@ -829,6 +1018,7 @@ macro(append_compiler_linker_sdk_setup)
ARGS use_lld
CONDITION QT_FEATURE_use_lld_linker
)
+ unset(cpu)
endmacro()
macro(append_sanitizer_setup)
@@ -849,50 +1039,92 @@ macro(append_sanitizer_setup)
ARGS is_ubsan is_ubsan_vptr
CONDITION undefined IN_LIST ECM_ENABLE_SANITIZERS
)
+ if(APPLE)
+ list(APPEND gnArgArg
+ clang_version=\"${QT_COMPILER_VERSION_MAJOR}.${QT_COMPILER_VERSION_MINOR}.${QT_COMPILER_VERSION_PATCH}\"
+ )
+ endif()
endif()
endmacro()
macro(append_toolchain_setup)
- if(LINUX)
+ if(WIN32)
+ get_gn_arch(cpu ${arch})
+ list(APPEND gnArgArg target_cpu="${cpu}")
+ if(MINGW)
+ get_gn_arch(cpu ${TEST_architecture_arch})
+ list(APPEND gnArgArg
+ # note '/' prefix
+ custom_toolchain="/${buildDir}/target_toolchain:target"
+ host_toolchain="/${buildDir}/host_toolchain:host"
+ host_cpu="${cpu}"
+ )
+ endif()
+ elseif(LINUX)
+ get_gn_arch(cpu ${TEST_architecture_arch})
list(APPEND gnArgArg
custom_toolchain="${buildDir}/target_toolchain:target"
host_toolchain="${buildDir}/host_toolchain:host"
- v8_snapshot_toolchain="${buildDir}/v8_toolchain:v8"
)
- get_gn_arch(cpu ${TEST_architecture_arch})
if(CMAKE_CROSSCOMPILING)
- list(APPEND gnArgArg target_cpu="${cpu}")
+ list(APPEND gnArgArg
+ v8_snapshot_toolchain="${buildDir}/v8_toolchain:v8"
+ target_cpu="${cpu}"
+ )
else()
list(APPEND gnArgArg host_cpu="${cpu}")
endif()
if(CMAKE_SYSROOT)
list(APPEND gnArgArg target_sysroot="${CMAKE_SYSROOT}")
endif()
- else()
+ elseif(MACOS)
get_gn_arch(cpu ${arch})
list(APPEND gnArgArg target_cpu="${cpu}")
+ elseif(IOS)
+ get_gn_arch(cpu ${arch})
+ get_ios_sysroot(sysroot ${arch})
+ list(APPEND gnArgArg target_cpu="${cpu}" target_sysroot="${sysroot}" target_os="ios")
+ elseif(ANDROID)
+ get_gn_arch(cpu ${TEST_architecture_arch})
+ list(APPEND gnArgArg target_os="android" target_cpu="${cpu}")
+ if(CMAKE_HOST_WIN32)
+ list(APPEND gnArgArg
+ host_toolchain="/${buildDir}/host_toolchain:host"
+ host_cpu="x64"
+ v8_snapshot_toolchain="/${buildDir}/v8_toolchain:v8"
+ )
+ endif()
endif()
+ unset(cpu)
endmacro()
macro(append_pkg_config_setup)
- if(LINUX)
+ if(PkgConfig_FOUND)
list(APPEND gnArgArg
pkg_config="${PKG_CONFIG_EXECUTABLE}"
host_pkg_config="${PKG_CONFIG_HOST_EXECUTABLE}"
)
+ if(NOT "$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+ list(APPEND gnArgArg
+ system_libdir="$ENV{PKG_CONFIG_LIBDIR}"
+ )
+ endif()
endif()
endmacro()
function(add_ninja_command)
- qt_parse_all_arguments(arg "add_ninja_command"
- "" "TARGET;OUTPUT;BUILDDIR;MODULE" "BYPRODUCTS" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "TARGET;BUILDDIR;MODULE" "OUTPUT;BYPRODUCTS"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
+
string(REPLACE " " ";" NINJAFLAGS "$ENV{NINJAFLAGS}")
+ list(TRANSFORM arg_OUTPUT PREPEND "${arg_BUILDDIR}/")
list(TRANSFORM arg_BYPRODUCTS PREPEND "${arg_BUILDDIR}/")
add_custom_command(
OUTPUT
- ${arg_BUILDDIR}/${arg_OUTPUT}
+ ${arg_OUTPUT}
${arg_BUILDDIR}/${arg_TARGET} # use generator expression in CMAKE 3.20
BYPRODUCTS ${arg_BYPRODUCTS}
COMMENT "Running ninja for ${arg_TARGET} in ${arg_BUILDDIR}"
@@ -909,92 +1141,142 @@ endfunction()
function(get_configs result)
if(QT_GENERATOR_IS_MULTI_CONFIG)
- set(${result} ${CMAKE_CONFIGURATION_TYPES} PARENT_SCOPE)
+ set(${result} ${CMAKE_CONFIGURATION_TYPES})
else()
- set(${result} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
+ set(${result} ${CMAKE_BUILD_TYPE})
+ endif()
+ if(NOT ${result})
+ message(FATAL_ERROR "No valid configurations found !")
endif()
+ set(${result} ${${result}} PARENT_SCOPE)
endfunction()
function(get_architectures result)
- if(NOT QT_IS_MACOS_UNIVERSAL)
- set(${result} ${CMAKE_SYSTEM_PROCESSOR} PARENT_SCOPE)
+ if(CMAKE_OSX_ARCHITECTURES)
+ set(${result} ${CMAKE_OSX_ARCHITECTURES})
else()
- set(${result} ${CMAKE_OSX_ARCHITECTURES} PARENT_SCOPE)
+ set(${result} ${CMAKE_SYSTEM_PROCESSOR})
endif()
+ if(NOT ${result})
+ message(FATAL_ERROR "No valid architectures found. In case of cross-compiling make sure you have CMAKE_SYSTEM_PROCESSOR in your toolchain file.")
+ endif()
+ set(${result} ${${result}} PARENT_SCOPE)
endfunction()
-function(add_gn_build_aritfacts_to_target cmakeTarget ninjaTarget module buildDir)
+function(add_gn_build_artifacts_to_target)
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "CMAKE_TARGET;NINJA_TARGET;BUILDDIR;MODULE;COMPLETE_STATIC;NINJA_STAMP;NINJA_DATA_STAMP" ""
+ )
+ _qt_internal_validate_all_args_are_parsed(arg)
+
# config loop is a workaround to be able to add_custom_command per config
# note this is fixed in CMAKE.3.20 and should be cleaned up when 3.20 is
# the minimum cmake we support
- get_configs(config)
+ get_configs(configs)
get_architectures(archs)
foreach(config ${configs})
foreach(arch ${archs})
- set(target ${ninjaTarget}_${config}_${arch})
- add_ninja_target(${target} ${cmakeTarget} ${ninjaTarget} ${config} ${arch} ${buildDir})
+ set(target ${arg_NINJA_TARGET}_${config}_${arch})
+ set(stamps ${arg_NINJA_STAMP} ${arg_NINJA_DATA_STAMP})
+ add_ninja_target(
+ TARGET ${target}
+ NINJA_TARGET ${arg_NINJA_TARGET}
+ CMAKE_TARGET ${arg_CMAKE_TARGET}
+ NINJA_STAMP ${arg_NINJA_STAMP}
+ NINJA_DATA_STAMP ${arg_NINJA_DATA_STAMP}
+ CONFIG ${config}
+ ARCH ${arch}
+ BUILDDIR ${arg_BUILDDIR}
+ )
add_ninja_command(
- TARGET ${ninjaTarget}
- OUTPUT ${ninjaTarget}.stamp
- BUILDDIR ${buildDir}/${config}/${arch}
- MODULE ${module}
+ TARGET ${arg_NINJA_TARGET}
+ OUTPUT ${stamps}
+ BUILDDIR ${arg_BUILDDIR}/${config}/${arch}
+ MODULE ${arg_MODULE}
)
- add_dependencies(run_${module}_NinjaDone ${target})
- set_target_properties(${cmakeTarget} PROPERTIES
- LINK_DEPENDS ${buildDir}/${config}/${arch}/${ninjaTarget}.stamp
+ add_dependencies(run_${arg_MODULE}_NinjaDone ${target})
+ set_target_properties(${arg_CMAKE_TARGET} PROPERTIES
+ LINK_DEPENDS ${arg_BUILDDIR}/${config}/${arch}/${arg_NINJA_STAMP}
)
if(QT_IS_MACOS_UNIVERSAL)
- add_rsp_command(${target} ${buildDir}/${config}/${arch})
+ add_intermediate_archive(${target} ${arg_BUILDDIR}/${config}/${arch} ${arg_COMPLETE_STATIC})
+ elseif(IOS)
+ add_intermediate_object(${target} ${arg_BUILDDIR}/${config}/${arch} ${arg_COMPLETE_STATIC})
else()
- extend_cmake_target(${target} ${buildDir}/${config}/${arch})
+ if(MACOS AND QT_FEATURE_static)
+ # mac archiver does not support @file notation, do intermediate object istead
+ add_intermediate_object(${target} ${arg_BUILDDIR}/${config}/${arch} ${arg_COMPLETE_STATIC})
+ add_archiver_options(${target} ${arg_BUILDDIR}/${config}/${arch} ${arg_COMPLETE_STATIC})
+ else()
+ add_linker_options(${target} ${arg_BUILDDIR}/${config}/${arch} ${arg_COMPLETE_STATIC})
+ endif()
endif()
+ unset(target)
endforeach()
+ list(GET archs 0 arch)
+ set(target ${arg_NINJA_TARGET}_${config}_${arch})
+ # Work around for broken builds with new Apple linker ld_prime. Force
+ # use of the classic linker until this has been fixed.
+ # TODO: remove once this has been fixed by Apple. See issue FB13667242
+ # or QTBUG-122655 for details.
+ if(APPLECLANG)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0.0")
+ target_link_options(${arg_CMAKE_TARGET} PRIVATE -ld_classic)
+ endif()
+ endif()
if(QT_IS_MACOS_UNIVERSAL)
- set(arch ${CMAKE_SYSTEM_PROCESSOR})
- set(target ${ninjaTarget}_${config}_${arch})
- add_lipo_command(${target} ${buildDir}/${config})
+ add_lipo_command(${target} ${arg_BUILDDIR}/${config})
+ endif()
+ if(IOS)
+ add_ios_lipo_command(${target} ${arg_BUILDDIR}/${config})
endif()
endforeach()
endfunction()
-function(get_config_filenames c_config cxx_config target_config)
+function(get_config_filenames c_config cxx_config static_config target_config)
set(${target_config} gn_config_target.cmake PARENT_SCOPE)
set(${cxx_config} gn_config_cxx.cmake PARENT_SCOPE)
set(${c_config} gn_config_c.cmake PARENT_SCOPE)
+ set(${static_config} gn_static.cmake PARENT_SCOPE)
endfunction()
function(add_gn_command)
- qt_parse_all_arguments(arg "add_gn_command"
- "" "CMAKE_TARGET;GN_TARGET;MODULE;BUILDDIR" "NINJA_TARGETS;GN_ARGS" "${ARGN}"
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "" "CMAKE_TARGET;GN_TARGET;MODULE;BUILDDIR" "NINJA_TARGETS;GN_ARGS"
)
+ _qt_internal_validate_all_args_are_parsed(arg)
- get_config_filenames(cConfigFileName cxxConfigFileName targetConfigFileName)
+ get_config_filenames(cConfigFileName cxxConfigFileName staticConfigFileName targetConfigFileName)
set(gnArgArgFile ${arg_BUILDDIR}/args.gn)
list(JOIN arg_GN_ARGS "\n" arg_GN_ARGS)
file(WRITE ${gnArgArgFile} ${arg_GN_ARGS})
foreach(ninjaTarget ${arg_NINJA_TARGETS})
- list(APPEND output ${ninjaTarget}_objects.rsp ${ninjaTarget}_archives.rsp ${ninjaTarget}_libs.rsp)
+ list(APPEND output ${ninjaTarget}_objects.rsp ${ninjaTarget}_archives.rsp ${ninjaTarget}_libs.rsp ${ninjaTarget}_ldir.rsp)
endforeach()
list(TRANSFORM output PREPEND "${arg_BUILDDIR}/")
- if(QT_HOST_PATH)
- set(QT_HOST_GN_PATH ${QT_HOST_PATH}/${INSTALL_LIBEXECDIR})
- endif()
-
add_custom_command(
OUTPUT ${output}
COMMAND ${CMAKE_COMMAND}
-DBUILD_DIR=${arg_BUILDDIR}
-DSOURCE_DIR=${CMAKE_CURRENT_LIST_DIR}
-DMODULE=${arg_MODULE}
- -DQT_HOST_GN_PATH=${QT_HOST_GN_PATH}
+ -DQT_HOST_PATH=${QT_HOST_PATH}
+ -DINSTALL_LIBEXECDIR=${INSTALL_LIBEXECDIR}
+ -DINSTALL_BINDIR=${INSTALL_BINDIR}
+ -DPython3_EXECUTABLE=${Python3_EXECUTABLE}
+ -DGN_THREADS=$ENV{QTWEBENGINE_GN_THREADS}
+ -DQT_ALLOW_SYMLINK_IN_PATHS=${QT_ALLOW_SYMLINK_IN_PATHS}
-P ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Gn.cmake
WORKING_DIRECTORY ${WEBENGINE_ROOT_BUILD_DIR}
COMMENT "Run gn for target ${arg_CMAKE_TARGET} in ${arg_BUILDDIR}"
- DEPENDS ${gnArgArgFile} run_${arg_MODULE}_GnReady
- USES_TERMINAL
+ DEPENDS
+ ${gnArgArgFile}
+ run_${arg_MODULE}_GnReady
+ "${WEBENGINE_ROOT_SOURCE_DIR}/src/${arg_MODULE}/configure/BUILD.root.gn.in"
+ "${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Gn.cmake"
)
add_custom_target(runGn_${arg_GN_TARGET}
DEPENDS #TODO this is fixed in cmake 3.20 so we could simply use GN_TARGET and not create new one
@@ -1004,13 +1286,17 @@ function(add_gn_command)
${arg_BUILDDIR}/${targetConfigFileName}
)
add_dependencies(run_${arg_MODULE}_GnDone runGn_${arg_GN_TARGET})
+ if(TARGET thirdparty_sync_headers)
+ add_dependencies(runGn_${arg_GN_TARGET} thirdparty_sync_headers)
+ endif()
create_gn_target_config(${arg_GN_TARGET} ${arg_BUILDDIR}/${targetConfigFileName})
endfunction()
function(create_cxx_configs cmakeTarget arch)
- get_config_filenames(cConfigFileName cxxConfigFileName targetConfigFileName)
+ get_config_filenames(cConfigFileName cxxConfigFileName staticConfigFileName targetConfigFileName)
create_c_config(${cmakeTarget} ${arch} ${cConfigFileName})
create_cxx_config(${cmakeTarget} ${arch} ${cxxConfigFileName})
+ create_static_config(${cmakeTarget} ${arch} ${staticConfigFileName})
endfunction()
# targets to gather per config / architecture targets
@@ -1034,16 +1320,6 @@ function(addCopyCommand target src dst)
)
endfunction()
-function(addCopyDirCommand target src dst)
- add_custom_command(
- POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${src} ${dst}
- TARGET ${target}
- DEPENDS ${src}
- USES_TERMINAL
- )
-endfunction()
-
function(check_for_ulimit)
message("-- Checking 'ulimit -n'")
execute_process(COMMAND bash -c "ulimit -n"
@@ -1096,3 +1372,34 @@ function(add_build feature value)
set(depTracker "${depTracker}" ${feature})
set_property(GLOBAL PROPERTY MATRIX_DEPENDENCY_TRACKER "${depTracker}")
endfunction()
+
+function(add_code_attributions_target)
+ cmake_parse_arguments(PARSE_ARGV 0 arg ""
+ "TARGET;OUTPUT;GN_TARGET;FILE_TEMPLATE;ENTRY_TEMPLATE;BUILDDIR"
+ "EXTRA_THIRD_PARTY_DIRS"
+ )
+ _qt_internal_validate_all_args_are_parsed(arg)
+ get_filename_component(fileTemplate ${arg_FILE_TEMPLATE} ABSOLUTE)
+ get_filename_component(entryTemplate ${arg_ENTRY_TEMPLATE} ABSOLUTE)
+ add_custom_command(
+ OUTPUT ${arg_OUTPUT}
+ COMMAND ${CMAKE_COMMAND}
+ -DLICENSE_SCRIPT=${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty/chromium/tools/licenses/licenses.py
+ -DFILE_TEMPLATE=${fileTemplate}
+ -DENTRY_TEMPLATE=${entryTemplate}
+ -DGN_TARGET=${arg_GN_TARGET}
+ -DEXTRA_THIRD_PARTY_DIRS="${arg_EXTRA_THIRD_PARTY_DIRS}"
+ -DBUILDDIR=${arg_BUILDDIR}
+ -DOUTPUT=${arg_OUTPUT}
+ -DPython3_EXECUTABLE=${Python3_EXECUTABLE}
+ -P ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/License.cmake
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_BUILD_DIR}
+ DEPENDS
+ ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty/chromium/tools/licenses/licenses.py
+ ${arg_FILE_TEMPLATE}
+ ${arg_ENTRY_TEMPLATE}
+ ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/License.cmake
+ USES_TERMINAL
+ )
+ add_custom_target(${arg_TARGET} DEPENDS ${arg_OUTPUT})
+endfunction()
diff --git a/cmake/Gn.cmake b/cmake/Gn.cmake
index e8dc956ee..15b349e08 100644
--- a/cmake/Gn.cmake
+++ b/cmake/Gn.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# This is gn wrapper script and it assables final BUILD.gn based on:
# gn_config_target.cmake gn_config_c.cmake gn_config_cxx.cmake
@@ -6,8 +9,13 @@ if(NOT CMAKE_SCRIPT_MODE_FILE)
return()
endif()
-get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." REALPATH)
-get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+set(path_mode REALPATH)
+if(APPLE AND QT_ALLOW_SYMLINK_IN_PATHS)
+ set(path_mode ABSOLUTE)
+endif()
+
+get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ${path_mode})
+get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" ${path_mode})
include(${WEBENGINE_ROOT_SOURCE_DIR}/.cmake.conf)
include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
@@ -15,8 +23,9 @@ include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
-find_package(Python2 2.7.5 REQUIRED)
-
+if(NOT Python3_EXECUTABLE)
+ find_package(Python3 3.6 REQUIRED)
+endif()
set(gnCmd ${Gn_EXECUTABLE})
set(buildDir ${BUILD_DIR})
set(sourceDir ${SOURCE_DIR})
@@ -31,6 +40,7 @@ endif()
init_gn_config(${buildDir}/gn_config_target.cmake)
read_gn_config(${buildDir}/gn_config_cxx.cmake)
read_gn_config(${buildDir}/gn_config_c.cmake)
+read_gn_config(${buildDir}/gn_static.cmake)
configure_gn_target(
"${sourceDir}"
@@ -39,9 +49,13 @@ configure_gn_target(
)
list(APPEND gnArg
- --script-executable=${Python2_EXECUTABLE}
+ --script-executable=${Python3_EXECUTABLE}
--root=${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty/chromium)
+if(GN_THREADS)
+ list(APPEND gnArg --threads=${GN_THREADS})
+endif()
+
STRING(REGEX REPLACE "\n" ";" printArgArg "${gnArgArg}")
LIST(SORT printArgArg)
STRING(REGEX REPLACE ";" "\n" printArgArg "${printArgArg}")
@@ -59,10 +73,11 @@ execute_process(
RESULT_VARIABLE gnResult
OUTPUT_VARIABLE gnOutput
ERROR_VARIABLE gnError
+ TIMEOUT 600
)
if(NOT gnResult EQUAL 0)
- message(FATAL_ERROR "\n-- GN FAILED\n${gnOutput}\n${gnError}")
+ message(FATAL_ERROR "\n-- GN FAILED\n${gnOutput}\n${gnError}\n${gnResult}\n")
else()
string(REGEX REPLACE "\n$" "" gnOutput "${gnOutput}")
message("-- GN ${gnOutput}")
diff --git a/cmake/License.cmake b/cmake/License.cmake
new file mode 100644
index 000000000..2427ad679
--- /dev/null
+++ b/cmake/License.cmake
@@ -0,0 +1,51 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT CMAKE_SCRIPT_MODE_FILE)
+ message("This files should run only in script mode")
+ return()
+endif()
+
+get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." REALPATH)
+get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+
+include(${WEBENGINE_ROOT_SOURCE_DIR}/.cmake.conf)
+include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
+if(NOT Python3_EXECUTABLE)
+ find_package(Python3 3.6 REQUIRED)
+endif()
+
+set(extraThirdPartyDirs "")
+if(NOT "${EXTRA_THIRD_PARTY_DIRS}" STREQUAL "")
+ string(REPLACE " " ";" dirList ${EXTRA_THIRD_PARTY_DIRS})
+ foreach(dir ${dirList})
+ string(CONCAT extraThirdPartyDirs ${extraThirdPartyDirs}"${dir}",)
+ endforeach()
+endif()
+
+execute_process(
+ COMMAND ${Python3_EXECUTABLE} ${LICENSE_SCRIPT}
+ --file-template ${FILE_TEMPLATE}
+ --entry-template ${ENTRY_TEMPLATE}
+ --gn-binary ${Gn_EXECUTABLE}
+ --gn-target ${GN_TARGET}
+ --gn-out-dir ${BUILDDIR}
+ --extra-third-party-dirs=[${extraThirdPartyDirs}]
+ credits ${OUTPUT}
+ WORKING_DIRECTORY ${BUILDDIR}
+ RESULT_VARIABLE gnResult
+ OUTPUT_VARIABLE gnOutput
+ ERROR_VARIABLE gnError
+ TIMEOUT 600
+)
+
+if(NOT gnResult EQUAL 0)
+ message(FATAL_ERROR "\n-- License FAILED\n${gnOutput}\n${gnError}\n${gnResult}\n")
+else()
+ string(REGEX REPLACE "\n$" "" gnOutput "${gnOutput}")
+ message("-- License ${gnOutput}")
+endif()
diff --git a/cmake/SubmoduleUpdate.cmake b/cmake/SubmoduleUpdate.cmake
new file mode 100644
index 000000000..123db55bf
--- /dev/null
+++ b/cmake/SubmoduleUpdate.cmake
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT CMAKE_SCRIPT_MODE_FILE)
+ message("This file should run only in script mode")
+ return()
+endif()
+
+get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." REALPATH)
+get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
+
+include(${WEBENGINE_ROOT_SOURCE_DIR}/.cmake.conf)
+include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
+
+find_program(GIT_EXECUTABLE NAMES git REQUIRED)
+
+execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty
+ OUTPUT_VARIABLE SUBMODULE_NEW_SHA
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD:src/3rdparty
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ OUTPUT_VARIABLE SUBMODULE_OLD_SHA
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+set(shas "${SUBMODULE_OLD_SHA}..${SUBMODULE_NEW_SHA}")
+set(format "* %s")
+execute_process(
+ COMMAND ${GIT_EXECUTABLE} log
+ --pretty=format:${format}
+ --abbrev-commit ${shas}
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty
+ OUTPUT_VARIABLE SUBMODULE_COMMITS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+if(SUBMODULE_COMMITS)
+ message("commits found for ${shas}")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} add src/3rdparty
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ )
+ set(commits ${SUBMODULE_COMMITS})
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} commit
+ --allow-empty
+ -m "Update Chromium"
+ -m "Submodule src/3rdparty ${shas}:\n${commits}"
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ RESULT_VARIABLE gitResult
+ OUTPUT_VARIABLE gitOutput
+ ERROR_VARIABLE gitError
+ )
+
+ if(NOT gitResult EQUAL 0)
+ message(FATAL_ERROR "\n-- Git Commit FAILED\n${gitOutput}\n${gitError}\n${gitResult}\n")
+ else()
+ string(REGEX REPLACE "\n$" "" gnOutput "${gitOutput}")
+ message("-- Git Commit ${gitOutput}")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} show HEAD
+ WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}
+ )
+ endif()
+else()
+ message(FATAL_ERROR "-- Git Commit found no commits for ${shas}")
+endif()
diff --git a/coin/module_config.yaml b/coin/module_config.yaml
index e60412517..f1d69a277 100644
--- a/coin/module_config.yaml
+++ b/coin/module_config.yaml
@@ -4,6 +4,12 @@ accept_configuration:
property: features
not_contains_value: Disable
+machine_type:
+ Build:
+ cores: 8
+ Test:
+ cores: 4
+
instructions:
Build:
- type: EnvironmentVariable
@@ -12,6 +18,13 @@ instructions:
- type: EnvironmentVariable
variableName: CMAKE_BUILD_OUTPUT_TIMEOUT
variableValue: "3600"
+ - type: EnvironmentVariable
+ variableName: QTWEBENGINE_GN_THREADS
+ variableValue: "1"
+ enable_if:
+ condition: property
+ property: host.os
+ equals_value: MacOS
- !include "{{qt/qtbase}}/coin_module_build_template_v2.yaml"
Test:
- type: EnvironmentVariable
diff --git a/coin/qt-installer-package-config.json b/coin/qt-installer-package-config.json
index 0ba69adac..ac604d77b 100644
--- a/coin/qt-installer-package-config.json
+++ b/coin/qt-installer-package-config.json
@@ -2,18 +2,23 @@
"version": "1",
"module-split": {
"qtpdf": [
+ "**/bin/*Pdf*",
"**/include/*QtPdf*/**/*",
- "**/lib/cmake/Qt5Gui/*",
- "**/lib/cmake/Qt5Pdf/*",
- "**/lib/cmake/Qt5PdfWidgets/*",
- "**/lib/pkgconfig/Qt5Pdf*",
- "**/lib/libQt5Pdf*",
+ "**/lib/cmake/Qt*Gui/*Pdf*",
+ "**/lib/cmake/Qt*Pdf*/*",
+ "**/lib/cmake/Qt*Qml/QmlPlugins/*Pdf*",
+ "**/lib/pkgconfig/*Pdf*",
+ "**/lib/*Pdf*",
"**/lib/static_chrome/*",
- "**/lib/QtPdf.framework/*",
+ "**/lib/QtPdf*.framework/**",
+ "**/metatypes/*pdf*",
"**/mkspecs/modules/qt_lib_pdf*",
"**/mkspecs/modules/qt_plugin_qpdf.pri",
- "**/plugins/imageformats/*",
- "**/qml/QtQuick/**/*"
+ "**/modules/Pdf*",
+ "**/plugins/imageformats/**/*",
+ "**/qml/QtQuick/**/*",
+ "**/qml/QtQuick/Pdf/**/.rcc/*",
+ "**/qml/QtQuick/Pdf/**/.rcc/qmlcache/*"
]
}
}
diff --git a/conanfile.py b/conanfile.py
index d0c0c7303..137285c08 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the release tools of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2021 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from conans import ConanFile
import re
@@ -33,10 +8,29 @@ from typing import Dict, Any
_qtwebengine_features = [
"qtpdf-build",
+ "qtpdf-quick-build",
+ "qtpdf-widgets-build",
"qtwebengine-build",
+ "qtwebengine-core-build",
"qtwebengine-quick-build",
"qtwebengine-widgets-build",
"webengine-developer-build",
+ "webengine-embedded-build",
+ "webengine-extensions",
+ "webengine-full-debug-info",
+ "webengine-jumbo-build",
+ "webengine-kerberos",
+ "webengine-native-spellchecker",
+ "webengine-pepper-plugins",
+ "webengine-printing-and-pdf",
+ "webengine-proprietary-codecs",
+ "webengine-sanitizer",
+ "webengine-spellchecker",
+ "webengine-webchannel",
+ "webengine-webrtc",
+ "webengine-webrtc-pipewire",
+ "system-webengine-ffmpeg",
+ "system-webengine-icu",
]
@@ -71,8 +65,25 @@ class QtWebEngine(ConanFile):
def get_qt_leaf_module_options(self) -> Dict[str, Any]:
"""Implements abstractmethod from qt-conan-common.QtLeafModule"""
- return {item.replace("-", "_"): ["yes", "no", None] for item in _qtwebengine_features}
+ return self._shared.convert_qt_features_to_conan_options(_qtwebengine_features)
def get_qt_leaf_module_default_options(self) -> Dict[str, Any]:
"""Implements abstractmethod from qt-conan-common.QtLeafModule"""
- return {item.replace("-", "_"): None for item in _qtwebengine_features}
+ return self._shared.convert_qt_features_to_default_conan_options(_qtwebengine_features)
+
+ def package_env_info(self) -> Dict[str, Any]:
+ """Implements abstractmethod from qt-conan-common.QtLeafModule"""
+ # this will be called only after a successful build
+ _f = lambda p: True
+ if tools.os_info.is_windows:
+ ptrn = "**/QtWebEngineProcess.exe"
+ elif tools.os_info.is_macos:
+ ptrn = "**/QtWebEngineProcess.app/**/QtWebEngineProcess"
+ _f = lambda p: not any(".dSYM" in item for item in p.parts)
+ else:
+ ptrn = "**/QtWebEngineProcess"
+ ret = [str(p) for p in Path(self.package_folder).rglob(ptrn) if p.is_file() and _f(p)]
+ if len(ret) != 1:
+ print("Expected to find one 'QtWebEngineProcess'. Found: {0}".format(ret))
+ return {"QTWEBENGINEPROCESS_PATH": ret.pop() if ret else ""}
+
diff --git a/config.tests/hostcompiler/hostcompiler.pro b/config.tests/hostcompiler/hostcompiler.pro
deleted file mode 100644
index 5a80246ab..000000000
--- a/config.tests/hostcompiler/hostcompiler.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-option(host_build)
-
-gcc:equals(QT_ARCH, "x86_64"):contains(QT_TARGET_ARCH, "arm"):!contains(QT_TARGET_ARCH, "arm64") {
- QMAKE_CXXFLAGS += -m32
- QMAKE_LFLAGS += -m32
-}
-
-SOURCES = main.cpp
-
diff --git a/config.tests/hostcompiler/main.cpp b/config.tests/hostcompiler/main.cpp
deleted file mode 100644
index c664a810f..000000000
--- a/config.tests/hostcompiler/main.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <stdio.h>
-int main()
-{
- printf("This works\n");
- return 0;
-}
diff --git a/configure.cmake b/configure.cmake
index 0129b8a28..9f4831257 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -1,19 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
if(QT_CONFIGURE_RUNNING)
function(assertTargets)
endfunction()
function(add_check_for_support)
endfunction()
+ function(check_for_ulimit)
+ endfunction()
else()
find_package(Ninja 1.7.2)
find_package(Gn ${QT_REPO_MODULE_VERSION} EXACT)
- find_package(Python2 2.7.5)
+ find_program(Python3_EXECUTABLE NAMES python3 python HINTS $ENV{PYTHON3_PATH})
+ if(NOT Python3_EXECUTABLE)
+ find_package(Python3 3.6)
+ endif()
find_package(GPerf)
find_package(BISON)
find_package(FLEX)
+ find_package(Perl)
find_package(PkgConfig)
find_package(Snappy)
- find_package(Nodejs 10.19)
+ find_package(Nodejs 14.0)
endif()
if(PkgConfig_FOUND)
@@ -30,22 +38,33 @@ if(PkgConfig_FOUND)
pkg_check_modules(X11 x11)
pkg_check_modules(XPROTO glproto)
pkg_check_modules(GLIB glib-2.0>=2.32.0)
- pkg_check_modules(HARFBUZZ harfbuzz>=2.4.0 harfbuzz-subset>=2.4.0)
+ pkg_check_modules(HARFBUZZ harfbuzz>=4.3.0 harfbuzz-subset>=4.3.0)
pkg_check_modules(JPEG libjpeg IMPORTED_TARGET)
pkg_check_modules(LIBEVENT libevent)
pkg_check_modules(MINIZIP minizip)
pkg_check_modules(PNG libpng>=1.6.0)
+ pkg_check_modules(TIFF libtiff-4>=4.2.0)
pkg_check_modules(ZLIB zlib)
- pkg_check_modules(RE2 re2 IMPORTED_TARGET)
- pkg_check_modules(ICU icu-uc>=68 icu-i18n>=68)
+ # TODO: chromium may replace base::StringView with std::string_view. See: crbug.com/691162
+ pkg_check_modules(RE2 re2>=11.0.0 IMPORTED_TARGET)
+ pkg_check_modules(ICU icu-uc>=70 icu-i18n>=70)
pkg_check_modules(WEBP libwebp libwebpmux libwebpdemux)
pkg_check_modules(LCMS2 lcms2)
pkg_check_modules(FREETYPE freetype2 IMPORTED_TARGET)
pkg_check_modules(LIBXML2 libxml-2.0 libxslt IMPORTED_TARGET)
- pkg_check_modules(FFMPEG libavcodec libavformat libavutil)
+ pkg_check_modules(FFMPEG libavcodec libavformat libavutil IMPORTED_TARGET)
pkg_check_modules(OPUS opus>=1.3.1)
pkg_check_modules(VPX vpx>=1.10.0 IMPORTED_TARGET)
pkg_check_modules(LIBPCI libpci)
+ pkg_check_modules(LIBOPENJP2 libopenjp2)
+endif()
+
+if(Python3_EXECUTABLE)
+ execute_process(
+ COMMAND ${Python3_EXECUTABLE} -c "import html5lib"
+ RESULT_VARIABLE html5lib_NOT_FOUND
+ OUTPUT_QUIET
+ )
endif()
#### Tests
@@ -60,11 +79,14 @@ qt_config_compile_test(re2
CODE
"
#include \"re2/filtered_re2.h\"
+#include <vector>
int main() {
std::string s;
re2::FilteredRE2 fre2(1);
int id = 0;
fre2.Add(s, {}, &id);
+ std::vector<std::string> pattern = {\"match\"};
+ fre2.Compile(&pattern);
const RE2 &re2 = fre2.GetRE2(id);
}"
)
@@ -84,6 +106,7 @@ int main() {
pkt.data.frame.height[0] = 0u;
auto a = CONSTRAINED_FROM_ABOVE_DROP;
auto b = VPX_IMG_FMT_NV12;
+ auto v9 = vpx_codec_vp9_cx();
}"
)
@@ -175,14 +198,21 @@ int main(void) {
}"
)
-qt_config_compile_test(winversion
- LABEL "winversion"
+qt_config_compile_test(libavformat
+ LABEL "libavformat"
+ LIBRARIES
+ PkgConfig::FFMPEG
CODE
"
-#if !defined(__clang__) && _MSC_FULL_VER < 191426428
-#error unsupported Visual Studio version
+#include \"libavformat/version.h\"
+extern \"C\" {
+#include \"libavformat/avformat.h\"
+}
+int main(void) {
+#if LIBAVFORMAT_VERSION_MAJOR >= 59
+ AVStream stream;
+ auto first_dts = av_stream_get_first_dts(&stream);
#endif
-int main(void){
return 0;
}"
)
@@ -220,15 +250,37 @@ qt_feature("qtpdf-widgets-build" PRIVATE
qt_feature("qtpdf-quick-build" PRIVATE
LABEL "Build QtPdfQuick"
PURPOSE "Enables building the QtPdfQuick module."
- CONDITION TARGET Qt::Quick AND TARGET Qt::Qml AND QT_FEATURE_qtpdf_build
+ CONDITION TARGET Qt::Quick AND TARGET Qt::Qml AND QT_FEATURE_qtpdf_build AND
+ Qt6Quick_VERSION VERSION_GREATER_EQUAL "6.4.0"
)
-qt_feature("webengine-system-ninja" PRIVATE
+
+function(qtwebengine_internal_is_file_inside_root_build_dir out_var file)
+ set(result ON)
+ if(NOT QT_CONFIGURE_RUNNING)
+ file(RELATIVE_PATH relpath "${WEBENGINE_ROOT_BUILD_DIR}" "${file}")
+ if(IS_ABSOLUTE "${relpath}" OR relpath MATCHES "^\\.\\./")
+ set(result OFF)
+ endif()
+ endif()
+ set(${out_var} ${result} PARENT_SCOPE)
+endfunction()
+
+if(Ninja_FOUND)
+ qtwebengine_internal_is_file_inside_root_build_dir(
+ Ninja_INSIDE_WEBENGINE_ROOT_BUILD_DIR "${Ninja_EXECUTABLE}")
+endif()
+qt_feature("webengine-build-ninja" PRIVATE
LABEL "Build Ninja"
- AUTODETECT NOT Ninja_FOUND OR Ninja_EXECUTABLE MATCHES ${WEBENGINE_ROOT_BUILD_DIR}
+ AUTODETECT NOT Ninja_FOUND OR Ninja_INSIDE_WEBENGINE_ROOT_BUILD_DIR
)
-qt_feature("webengine-system-gn" PRIVATE
+
+if(Gn_FOUND)
+ qtwebengine_internal_is_file_inside_root_build_dir(
+ Gn_INSIDE_WEBENGINE_ROOT_BUILD_DIR "${Gn_EXECUTABLE}")
+endif()
+qt_feature("webengine-build-gn" PRIVATE
LABEL "Build Gn"
- AUTODETECT NOT Gn_FOUND OR Gn_EXECUTABLE MATCHES ${WEBENGINE_ROOT_BUILD_DIR}
+ AUTODETECT NOT Gn_FOUND OR Gn_INSIDE_WEBENGINE_ROOT_BUILD_DIR
)
# default assumed merge limit (should match the one in qt_cmdline.cmake)
set(jumbo_merge_limit 8)
@@ -258,7 +310,7 @@ qt_feature("webengine-developer-build" PRIVATE
)
qt_feature("webengine-system-re2" PRIVATE
LABEL "re2"
- AUTODETECT UNIX AND TEST_re2
+ CONDITION UNIX AND TEST_re2
)
qt_feature("webengine-system-icu" PRIVATE
LABEL "icu"
@@ -269,6 +321,10 @@ qt_feature("webengine-system-libwebp" PRIVATE
LABEL "libwebp, libwebpmux and libwebpdemux"
CONDITION UNIX AND WEBP_FOUND
)
+qt_feature("webengine-system-libopenjpeg2" PRIVATE
+ LABEL "libopenjpeg2"
+ CONDITION UNIX AND LIBOPENJP2_FOUND
+)
qt_feature("webengine-system-opus" PRIVATE
LABEL "opus"
CONDITION UNIX AND OPUS_FOUND
@@ -280,6 +336,7 @@ qt_feature("webengine-system-ffmpeg" PRIVATE
)
qt_feature("webengine-system-libvpx" PRIVATE
LABEL "libvpx"
+ AUTODETECT FALSE
CONDITION UNIX AND TEST_vpx
)
qt_feature("webengine-system-snappy" PRIVATE
@@ -294,13 +351,18 @@ qt_feature("webengine-system-zlib" PRIVATE
LABEL "zlib"
CONDITION UNIX AND QT_FEATURE_system_zlib AND ZLIB_FOUND
)
+qt_feature("webengine-qt-zlib" PRIVATE
+ LABEL "qtzlib"
+ CONDITION QT_FEATURE_static
+ AND TARGET Qt::Gui
+ AND NOT QT_FEATURE_system_zlib
+)
qt_feature("webengine-system-minizip" PRIVATE
LABEL "minizip"
CONDITION UNIX AND MINIZIP_FOUND
)
qt_feature("webengine-system-libevent" PRIVATE
LABEL "libevent"
- AUTODETECT FALSE # coin bug 711
CONDITION UNIX AND LIBEVENT_FOUND
)
qt_feature("webengine-system-libxml" PRIVATE
@@ -315,18 +377,50 @@ qt_feature("webengine-system-libpng" PRIVATE
LABEL "png"
CONDITION UNIX AND TARGET Qt::Gui AND PNG_FOUND AND QT_FEATURE_system_png
)
+qt_feature("webengine-system-libtiff" PRIVATE
+ LABEL "tiff"
+ CONDITION UNIX AND TARGET Qt::Gui AND TIFF_FOUND
+)
+qt_feature("webengine-qt-libpng" PRIVATE
+ LABEL "qtpng"
+ CONDITION QT_FEATURE_static
+ AND TARGET Qt::Gui
+ AND QT_FEATURE_png
+ AND NOT QT_FEATURE_system_png
+)
qt_feature("webengine-system-libjpeg" PRIVATE
LABEL "jpeg"
CONDITION UNIX AND TARGET Qt::Gui AND TEST_jpeg AND QT_FEATURE_system_jpeg
)
+qt_feature("webengine-qt-libjpeg" PRIVATE
+ LABEL "qtjpeg"
+ CONDITION QT_FEATURE_static
+ AND TARGET Qt::Gui
+ AND QT_FEATURE_jpeg
+ AND NOT QT_FEATURE_system_jpeg
+)
qt_feature("webengine-system-harfbuzz" PRIVATE
LABEL "harfbuzz"
CONDITION UNIX AND TARGET Qt::Gui AND HARFBUZZ_FOUND AND QT_FEATURE_system_harfbuzz
)
+qt_feature("webengine-qt-harfbuzz" PRIVATE
+ LABEL "qtharfbuzz"
+ CONDITION QT_FEATURE_static
+ AND TARGET Qt::Gui
+ AND QT_FEATURE_harfbuzz
+ AND NOT QT_FEATURE_system_harfbuzz
+)
qt_feature("webengine-system-freetype" PRIVATE
LABEL "freetype"
CONDITION UNIX AND TARGET Qt::Gui AND TEST_freetype AND QT_FEATURE_system_freetype
)
+qt_feature("webengine-qt-freetype" PRIVATE
+ LABEL "qtfreetype"
+ CONDITION QT_FEATURE_static
+ AND TARGET Qt::Gui
+ AND QT_FEATURE_freetype
+ AND NOT QT_FEATURE_system_freetype
+)
qt_feature("webengine-system-libpci" PRIVATE
LABEL "libpci"
CONDITION UNIX AND LIBPCI_FOUND
@@ -355,37 +449,65 @@ else()
set(WIN_ARM_64 OFF)
endif()
+add_check_for_support(
+ MODULES QtWebEngine QtPdf
+ CONDITION
+ CMAKE_VERSION
+ VERSION_GREATER_EQUAL
+ ${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE}
+ MESSAGE
+ "Build requires CMake ${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE} or higher."
+)
+
assertTargets(
MODULES QtWebEngine QtPdf
TARGETS Gui Quick Qml
)
add_check_for_support(
- MODULES QtWebEngine QtPdf
- CONDITION LINUX OR (WIN32 AND NOT WIN_ARM_64) OR (MACOS AND NOT CMAKE_CROSSCOMPILING)
+ MODULES QtWebEngine
+ CONDITION LINUX OR (WIN32 AND NOT WIN_ARM_64) OR MACOS
MESSAGE "Build can be done only on Linux, Windows or macOS."
)
+add_check_for_support(
+ MODULES QtPdf
+ CONDITION LINUX OR (WIN32 AND NOT WIN_ARM_64) OR MACOS OR IOS OR ANDROID
+ MESSAGE "Build can be done only on Linux, Windows, macO, iOS and Android."
+)
if(LINUX AND CMAKE_CROSSCOMPILING)
- get_gn_arch(testArch ${TEST_architecture_arch})
+ set(supportedTargets "arm" "arm64" "armv7-a" "x86_64")
add_check_for_support(
MODULES QtWebEngine QtPdf
- CONDITION testArch
+ CONDITION TEST_architecture_arch IN_LIST supportedTargets
MESSAGE "Cross compiling is not supported for ${TEST_architecture_arch}."
)
+ unset(supportedTargets)
endif()
add_check_for_support(
- MODULES QtWebEngine QtPdf
+ MODULES QtWebEngine
CONDITION NOT QT_FEATURE_static
MESSAGE "Static build is not supported."
)
add_check_for_support(
MODULES QtWebEngine QtPdf
CONDITION TARGET Nodejs::Nodejs
- MESSAGE "node.js version 10.19 or later is required."
+ MESSAGE "node.js version 14 or later is required."
+)
+add_check_for_support(
+ MODULES QtWebEngine
+ CONDITION NOT (Nodejs_ARCH STREQUAL "ia32") AND
+ NOT (Nodejs_ARCH STREQUAL "x86") AND
+ NOT (Nodejs_ARCH STREQUAL "arm")
+ MESSAGE "32bit version of Nodejs is not supported."
+)
+add_check_for_support(
+ MODULES QtWebEngine QtPdf
+ CONDITION Python3_EXECUTABLE
+ MESSAGE "Python version 3.6 or later is required."
)
add_check_for_support(
MODULES QtWebEngine QtPdf
- CONDITION Python2_FOUND
- MESSAGE "Python2 version 2.7.5 or later is required."
+ CONDITION Python3_EXECUTABLE AND NOT html5lib_NOT_FOUND
+ MESSAGE "Python3 html5lib is missing."
)
add_check_for_support(
MODULES QtWebEngine QtPdf
@@ -432,47 +554,60 @@ add_check_for_support(
CONDITION NOT LINUX OR DBUS_FOUND
MESSAGE "Build requires dbus."
)
-# FIXME: This prevents non XCB Linux builds from building:
-set(xcbSupport X11 LIBDRM XCOMPOSITE XCURSOR XRANDR XI XPROTO XSHMFENCE XTST)
-foreach(xs ${xcbSupport})
- if(${xs}_FOUND)
- set(xcbErrorMessage "${xcbErrorMessage} ${xs}:YES")
- else()
- set(xcbErrorMessage "${xcbErrorMessage} ${xs}:NO")
- endif()
-endforeach()
add_check_for_support(
- MODULES QtWebEngine
- CONDITION NOT LINUX OR NOT QT_FEATURE_xcb OR QT_FEATURE_webengine_ozone_x11
- MESSAGE "Could not find all necessary libraries for qpa-xcb support.\
-${xcbErrorMessage}"
+ MODULES QtWebEngine
+ CONDITION NOT LINUX OR NOT QT_FEATURE_webengine_system_ffmpeg OR TEST_libavformat
+ MESSAGE "Unmodified ffmpeg >= 5.0 is not supported."
)
+
add_check_for_support(
- MODULES QtWebEngine QtPdf
- CONDITION NOT WIN32 OR TEST_winversion
- MESSAGE "Build requires Visual Studio 2019 or higher."
+ MODULES QtWebEngine
+ CONDITION MSVC OR
+ (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+ (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR
+ (MACOS AND CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ MESSAGE
+ "${CMAKE_CXX_COMPILER_ID} compiler is not supported."
)
+
add_check_for_support(
- MODULES QtWebEngine QtPdf
- CONDITION
- (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL GNU) OR
- (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) OR
- (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL MSVC) OR
- (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL Clang AND
- CMAKE_CXX_SIMULATE_ID STREQUAL MSVC) OR
- (MACOS AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang)
- MESSAGE "${CMAKE_CXX_COMPILER_ID} compiler is not supported."
+ MODULES QtPdf
+ CONDITION MSVC OR
+ (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+ (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR
+ (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") OR
+ (ANDROID AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR
+ (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+ (MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ MESSAGE
+ "${CMAKE_CXX_COMPILER_ID} compiler is not supported."
)
-
if(WIN32)
+ if(MSVC)
+ if(MSVC_TOOLSET_VERSION EQUAL 142) # VS 2019 (16.0)
+ add_check_for_support(
+ MODULES QtWebEngine QtPdf
+ CONDITION NOT MSVC_VERSION LESS 1929
+ MESSAGE "VS compiler version must be at least 14.29"
+ )
+ elseif(MSVC_TOOLSET_VERSION EQUAL 143) # VS 2022 (17.0)
+ add_check_for_support(
+ MODULES QtWebEngine QtPdf
+ CONDITION NOT MSVC_VERSION LESS 1936
+ MESSAGE "VS compiler version must be at least 14.36"
+ )
+ else()
+ message(FATAL_ERROR "Build requires Visual Studio 2019 or higher.")
+ endif()
+ endif()
set(windowsSdkVersion $ENV{WindowsSDKVersion})
string(REGEX REPLACE "([0-9.]+).*" "\\1" windowsSdkVersion "${windowsSdkVersion}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" sdkMinor "${windowsSdkVersion}")
message("-- Windows 10 SDK version: ${windowsSdkVersion}")
add_check_for_support(
- MODULES QtWebEngine QtPdf
- CONDITION sdkMinor GREATER_EQUAL 19041
- MESSAGE "Build requires Windows 10 SDK at least version 10.0.19041.0"
+ MODULES QtWebEngine
+ CONDITION sdkMinor GREATER_EQUAL 22621
+ MESSAGE "Build requires Windows 11 SDK at least version 10.0.22621.0"
)
endif()
@@ -480,8 +615,8 @@ endif()
# > Qt WebEngine Build Features
qt_configure_add_summary_section(NAME "WebEngine Repository Build Options")
-qt_configure_add_summary_entry(ARGS "webengine-system-ninja")
-qt_configure_add_summary_entry(ARGS "webengine-system-gn")
+qt_configure_add_summary_entry(ARGS "webengine-build-ninja")
+qt_configure_add_summary_entry(ARGS "webengine-build-gn")
qt_configure_add_summary_entry(ARGS "webengine-jumbo-build")
qt_configure_add_summary_entry(ARGS "webengine-developer-build")
qt_configure_add_summary_section(NAME "Build QtWebEngine Modules")
@@ -510,12 +645,24 @@ if(UNIX)
qt_configure_add_summary_entry(ARGS "webengine-system-libxml")
qt_configure_add_summary_entry(ARGS "webengine-system-lcms2")
qt_configure_add_summary_entry(ARGS "webengine-system-libpng")
+ qt_configure_add_summary_entry(ARGS "webengine-system-libtiff")
qt_configure_add_summary_entry(ARGS "webengine-system-libjpeg")
+ qt_configure_add_summary_entry(ARGS "webengine-system-libopenjpeg2")
qt_configure_add_summary_entry(ARGS "webengine-system-harfbuzz")
qt_configure_add_summary_entry(ARGS "webengine-system-freetype")
qt_configure_add_summary_entry(ARGS "webengine-system-libpci")
qt_configure_end_summary_section()
endif()
+
+if(QT_FEATURE_static)
+ qt_configure_add_summary_section(NAME "Qt 3rdparty libs")
+ qt_configure_add_summary_entry(ARGS "webengine-qt-freetype")
+ qt_configure_add_summary_entry(ARGS "webengine-qt-harfbuzz")
+ qt_configure_add_summary_entry(ARGS "webengine-qt-libpng")
+ qt_configure_add_summary_entry(ARGS "webengine-qt-libjpeg")
+ qt_configure_add_summary_entry(ARGS "webengine-qt-zlib")
+endif()
+
# << Optional system libraries
qt_configure_end_summary_section()
# < Qt WebEngine Build Features
@@ -537,9 +684,35 @@ qt_configure_add_report_entry(
MESSAGE "Building fat libray with device and simulator architectures will disable NEON."
CONDITION IOS AND simulator AND device AND QT_FEATURE_qtpdf_build
)
+
+if(LINUX AND QT_FEATURE_xcb AND TARGET Qt::Gui)
+ set(ozone_x11_support X11 LIBDRM XCOMPOSITE XCURSOR XRANDR XI XPROTO XSHMFENCE XTST)
+ set(ozone_x11_error OFF)
+ foreach(xs ${ozone_x11_support})
+ if(NOT ${xs}_FOUND)
+ set(ozone_x11_error ON)
+ set(ozone_x11_error_message "${ozone_x11_error_message}\n-- ${xs} libray not found")
+ endif()
+ endforeach()
+ if(ozone_x11_error)
+ qt_configure_add_report_entry(
+ TYPE WARNING
+ MESSAGE
+ "Could not find all necessary libraries for qpa-xcb support.${ozone_x11_error_message}"
+ )
+ endif()
+endif()
+
if(PRINT_BFD_LINKER_WARNING)
qt_configure_add_report_entry(
TYPE WARNING
MESSAGE "Using bfd linker requires at least 4096 open files limit"
)
endif()
+if(NOT FEATURE_webengine_opus_system AND NOT Perl_FOUND)
+ qt_configure_add_report_entry(
+ TYPE WARNING
+ MESSAGE "No perl found, compiling opus without some optimizations."
+ )
+endif()
+
diff --git a/dependencies.yaml b/dependencies.yaml
index ee2fb994e..f6dff0465 100644
--- a/dependencies.yaml
+++ b/dependencies.yaml
@@ -1,13 +1,13 @@
dependencies:
../qtdeclarative:
- ref: 3d23912b0e9710dad7ecaf238690e4a7d253534d
+ ref: c283d4473edd1532cf1bce91ad1215e42e4fa15b
required: true
../qtpositioning:
- ref: 3e7f7fae1b68cd91af97258c71bb699fb394247f
+ ref: 2750f3ecc47813c0c0de1e04d4d64f839801809b
required: false
../qttools:
- ref: 9ea05f1273565217831e0160bb8d5feff28c605a
+ ref: 94d1021cc54e61dcc24159f45ab47bb5fbfb1276
required: false
../qtwebchannel:
- ref: 439c429be2a79263d75f85f36073bf2e961c8953
+ ref: 0603692e37ebd026766a13d80afbf2c3620d906f
required: false
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 06e36ecc9..e863dafaf 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,6 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
-qt_examples_build_begin()
+qt_examples_build_begin(EXTERNAL_BUILD)
if(NOT CMAKE_CROSSCOMPILING) #QTBUG-86533
if(TARGET Qt::WebEngineCore)
add_subdirectory(webenginequick)
diff --git a/examples/pdf/CMakeLists.txt b/examples/pdf/CMakeLists.txt
index cca6c03db..bdc1d0f05 100644
--- a/examples/pdf/CMakeLists.txt
+++ b/examples/pdf/CMakeLists.txt
@@ -1,5 +1,8 @@
-add_subdirectory(pdfviewer)
-add_subdirectory(multipage)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+qt_internal_add_example(singlepage)
+qt_internal_add_example(multipage)
if(NOT TARGET Qt::Svg)
message(WARNING "QtSvg is required as runtime dependency for qtpdfquick examples.")
endif()
diff --git a/examples/pdf/multipage/CMakeLists.txt b/examples/pdf/multipage/CMakeLists.txt
index e89c8d238..8f8111c82 100644
--- a/examples/pdf/multipage/CMakeLists.txt
+++ b/examples/pdf/multipage/CMakeLists.txt
@@ -1,28 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(multipage LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/pdf/multipage")
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Qml)
+find_package(Qt6 REQUIRED COMPONENTS Gui Qml)
qt_add_executable(multipage
main.cpp
+ pdfapplication.h
+ pdfapplication.cpp
)
+
+if (APPLE AND NOT IOS)
+ set(MACOSX_BUNDLE_ICON_FILE multipage.icns)
+ set(app_icon_macos "${CMAKE_CURRENT_SOURCE_DIR}/resources/multipage.icns")
+ set_source_files_properties(${app_icon_macos} PROPERTIES
+ MACOSX_PACKAGE_LOCATION "Resources")
+ target_sources(multipage PRIVATE ${app_icon_macos})
+ set(MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resources/macos/Info.plist")
+endif()
+
set_target_properties(multipage PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(multipage PUBLIC
Qt::Gui
Qt::Qml
@@ -39,6 +50,8 @@ set(viewer_resource_files
"resources/go-up-search.svg"
"resources/rotate-left.svg"
"resources/rotate-right.svg"
+ "resources/sidebar-collapse-left.svg"
+ "resources/sidebar-expand-left.svg"
"resources/test.pdf"
"resources/zoom-fit-best.svg"
"resources/zoom-fit-width.svg"
@@ -50,7 +63,7 @@ set(viewer_resource_files
qt_add_resources(multipage "viewer"
PREFIX
- "/pdfviewer"
+ "/multipage"
FILES
${viewer_resource_files}
)
diff --git a/examples/pdf/multipage/doc/src/multipage.qdoc b/examples/pdf/multipage/doc/src/multipage.qdoc
new file mode 100644
index 000000000..7ce4b4a8b
--- /dev/null
+++ b/examples/pdf/multipage/doc/src/multipage.qdoc
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example multipage
+ \meta installpath pdf
+ \ingroup qtpdf-examples
+ \examplecategory {User Interface Components}
+
+ \title PDF Multipage Viewer Example
+ \brief A Qt Quick PDF viewer that allows scrolling through the pages.
+
+ \image multipageviewer.png
+
+ \e {PDF Multipage Viewer} demonstrates how to use the PdfMultiPageView
+ component to render PDF documents and search for text in them.
+
+ \include examples-run.qdocinc
+
+ \section1 Creating the Main Window
+
+ Instantiate an \l ApplicationWindow, bind its title to the title of the
+ PDF document, and create a toolbar:
+
+ \quotefromfile multipage/viewer.qml
+ \skipto ApplicationWindow
+ \printuntil rightMargin
+
+ The toolbar has buttons for most of the common actions:
+
+ \printuntil ZoomOut
+
+ Declare a PdfDocument and bind the \c status property and
+ \c passwordRequired signal to inform the user when an error occurs or a
+ password is required:
+
+ \skipto onAccepted
+ \skipto Dialog
+ \printto PdfMultiPageView
+
+ Add the main component, PdfMultiPageView:
+
+ \printto onCurrentPageChanged
+ \printto Drawer
+
+ A \l Drawer holds a ListView to show search results from the
+ \l {PdfMultiPageView::searchModel}{searchModel}:
+
+ \printto ToolBar
+
+ Finally, add a second toolbar as a footer, to hold the search field,
+ search up/down buttons and some status information:
+
+ \printuntil
+
+ \section1 Files and Attributions
+
+ \sa {PDF Single Page Viewer Example}
+*/
diff --git a/examples/pdf/multipage/main.cpp b/examples/pdf/multipage/main.cpp
index 9311afa8e..b9c31c7f8 100644
--- a/examples/pdf/multipage/main.cpp
+++ b/examples/pdf/multipage/main.cpp
@@ -1,54 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QGuiApplication>
+#include "pdfapplication.h"
+#include <QDir>
#include <QQmlApplicationEngine>
int main(int argc, char* argv[])
@@ -56,17 +10,18 @@ int main(int argc, char* argv[])
QCoreApplication::setApplicationName("Qt Quick Multi-page PDF Viewer Example");
QCoreApplication::setOrganizationName("QtProject");
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QGuiApplication app(argc, argv);
+ PdfApplication app(argc, argv);
QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:///pdfviewer/viewer.qml")));
+ engine.load(QUrl(QStringLiteral("qrc:///multipage/viewer.qml")));
+ app.setFileOpener(engine.rootObjects().constFirst());
if (app.arguments().count() > 1) {
- QUrl toLoad = QUrl::fromUserInput(app.arguments().at(1));
- engine.rootObjects().first()->setProperty("source", toLoad);
+ // alternatively, use QUrl::fromLocalFile(): network loading is not supported yet
+ QUrl toLoad = QUrl::fromUserInput(app.arguments().at(1), QDir::currentPath(), QUrl::AssumeLocalFile);
+ engine.rootObjects().constFirst()->setProperty("source", toLoad);
} else {
- engine.rootObjects().first()->setProperty("source", QStringLiteral("resources/test.pdf"));
+ engine.rootObjects().constFirst()->setProperty("source", QStringLiteral("resources/test.pdf"));
}
-
return app.exec();
}
diff --git a/examples/pdf/multipage/multipage.pro b/examples/pdf/multipage/multipage.pro
index bd08ba0de..c12651335 100644
--- a/examples/pdf/multipage/multipage.pro
+++ b/examples/pdf/multipage/multipage.pro
@@ -2,7 +2,7 @@ TEMPLATE = app
QT += qml quick pdf svg
-SOURCES += main.cpp
+SOURCES += main.cpp pdfapplication.cpp
RESOURCES += \
viewer.qrc
@@ -12,3 +12,5 @@ EXAMPLE_FILES = \
target.path = $$[QT_INSTALL_EXAMPLES]/pdf/multipage
INSTALLS += target
+macos:QMAKE_INFO_PLIST = resources/macos/Info.plist
+macos:ICON = resources/multipage.icns
diff --git a/examples/pdf/multipage/pdfapplication.cpp b/examples/pdf/multipage/pdfapplication.cpp
new file mode 100644
index 000000000..d8e7c6486
--- /dev/null
+++ b/examples/pdf/multipage/pdfapplication.cpp
@@ -0,0 +1,16 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "pdfapplication.h"
+#include <QFileOpenEvent>
+
+PdfApplication::PdfApplication(int &argc, char **argv)
+ : QGuiApplication(argc, argv) { }
+
+bool PdfApplication::event(QEvent *e) {
+ if (e->type() == QEvent::FileOpen) {
+ QFileOpenEvent *foEvent = static_cast<QFileOpenEvent *>(e);
+ m_fileOpener->setProperty("source", foEvent->url());
+ }
+ return QGuiApplication::event(e);
+}
diff --git a/examples/pdf/multipage/pdfapplication.h b/examples/pdf/multipage/pdfapplication.h
new file mode 100644
index 000000000..06c998e1c
--- /dev/null
+++ b/examples/pdf/multipage/pdfapplication.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef PDFAPPLICATION_H
+#define PDFAPPLICATION_H
+
+#include <QGuiApplication>
+#include <QObject>
+
+class PdfApplication : public QGuiApplication
+{
+public:
+ PdfApplication(int &argc, char **argv);
+ void setFileOpener(QObject *opener) {
+ m_fileOpener = opener;
+ }
+
+protected:
+ bool event(QEvent *e) override;
+
+ QObject *m_fileOpener;
+};
+
+#endif // PDFAPPLICATION_H
diff --git a/examples/pdf/multipage/resources/macos/Info.plist b/examples/pdf/multipage/resources/macos/Info.plist
new file mode 100644
index 000000000..512becda0
--- /dev/null
+++ b/examples/pdf/multipage/resources/macos/Info.plist
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.1">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>multipage</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.qt-project.multipage</string>
+ <key>CFBundleDisplayName</key>
+ <string>Multi-page PDF Viewer</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleExecutable</key>
+ <string>multipage</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>CFBundleTypeName</key>
+ <string>pdf</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>com.adobe.pdf</string>
+ </array>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/examples/pdf/multipage/resources/multipage.icns b/examples/pdf/multipage/resources/multipage.icns
new file mode 100644
index 000000000..2e3756903
--- /dev/null
+++ b/examples/pdf/multipage/resources/multipage.icns
Binary files differ
diff --git a/examples/pdf/multipage/resources/sidebar-collapse-left.svg b/examples/pdf/multipage/resources/sidebar-collapse-left.svg
new file mode 100644
index 000000000..06f84afb4
--- /dev/null
+++ b/examples/pdf/multipage/resources/sidebar-collapse-left.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ <g transform="translate(1,1)">
+ <g class="ColorScheme-Text" fill="currentColor">
+ <path d="m3 3v16h16v-16zm5 1h10v14h-10z" stroke-linecap="square" stroke-linejoin="round"/>
+ <path d="m14.646484 6.6464844-4.353515 4.3535156 4.353515 4.353516.707032-.707032-3.646485-3.646484 3.646485-3.6464844z"/>
+ </g>
+ </g>
+</svg>
diff --git a/examples/pdf/multipage/resources/sidebar-expand-left.svg b/examples/pdf/multipage/resources/sidebar-expand-left.svg
new file mode 100644
index 000000000..83b35206e
--- /dev/null
+++ b/examples/pdf/multipage/resources/sidebar-expand-left.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
+ <style type="text/css" id="current-color-scheme">
+ .ColorScheme-Text {
+ color:#232629;
+ }
+ </style>
+ <g transform="translate(1,1)">
+ <g class="ColorScheme-Text" fill="currentColor">
+ <path d="m3 3v16h16v-16zm5 1h10v14h-10z" stroke-linecap="square" stroke-linejoin="round"/>
+ <path d="m11.353516 6.6464844 4.353515 4.3535156-4.353515 4.353516-.707032-.707032 3.646485-3.646484-3.646485-3.6464844z"/>
+ </g>
+ </g>
+</svg>
diff --git a/examples/pdf/multipage/resources/test.pdf b/examples/pdf/multipage/resources/test.pdf
index a9dc1bc29..0832dfbed 100644
--- a/examples/pdf/multipage/resources/test.pdf
+++ b/examples/pdf/multipage/resources/test.pdf
Binary files differ
diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
index ed84d5547..55ca2994a 100644
--- a/examples/pdf/multipage/viewer.qml
+++ b/examples/pdf/multipage/viewer.qml
@@ -1,67 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 QtQml // workaround for QTBUG-82873
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
+import QtQuick.Dialogs
import QtQuick.Layouts
import QtQuick.Pdf
-import QtQuick.Shapes
-import QtQuick.Window
-import Qt.labs.platform as Platform
ApplicationWindow {
id: root
width: 800
height: 1024
color: "lightgrey"
- title: document.title
+ title: doc.title
visible: true
property string source // for main.cpp
@@ -72,7 +22,7 @@ ApplicationWindow {
ToolButton {
action: Action {
shortcut: StandardKey.Open
- icon.source: "qrc:/pdfviewer/resources/document-open.svg"
+ icon.source: "qrc:/multipage/resources/document-open.svg"
onTriggered: fileDialog.open()
}
}
@@ -80,7 +30,7 @@ ApplicationWindow {
action: Action {
shortcut: StandardKey.ZoomIn
enabled: view.renderScale < 10
- icon.source: "qrc:/pdfviewer/resources/zoom-in.svg"
+ icon.source: "qrc:/multipage/resources/zoom-in.svg"
onTriggered: view.renderScale *= Math.sqrt(2)
}
}
@@ -88,47 +38,47 @@ ApplicationWindow {
action: Action {
shortcut: StandardKey.ZoomOut
enabled: view.renderScale > 0.1
- icon.source: "qrc:/pdfviewer/resources/zoom-out.svg"
+ icon.source: "qrc:/multipage/resources/zoom-out.svg"
onTriggered: view.renderScale /= Math.sqrt(2)
}
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/zoom-fit-width.svg"
+ icon.source: "qrc:/multipage/resources/zoom-fit-width.svg"
onTriggered: view.scaleToWidth(root.contentItem.width, root.contentItem.height)
}
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/zoom-fit-best.svg"
+ icon.source: "qrc:/multipage/resources/zoom-fit-best.svg"
onTriggered: view.scaleToPage(root.contentItem.width, root.contentItem.height)
}
}
ToolButton {
action: Action {
shortcut: "Ctrl+0"
- icon.source: "qrc:/pdfviewer/resources/zoom-original.svg"
+ icon.source: "qrc:/multipage/resources/zoom-original.svg"
onTriggered: view.resetScale()
}
}
ToolButton {
action: Action {
shortcut: "Ctrl+L"
- icon.source: "qrc:/pdfviewer/resources/rotate-left.svg"
+ icon.source: "qrc:/multipage/resources/rotate-left.svg"
onTriggered: view.pageRotation -= 90
}
}
ToolButton {
action: Action {
shortcut: "Ctrl+R"
- icon.source: "qrc:/pdfviewer/resources/rotate-right.svg"
+ icon.source: "qrc:/multipage/resources/rotate-right.svg"
onTriggered: view.pageRotation += 90
}
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-previous-view-page.svg"
- enabled: view.backEnbled
+ icon.source: "qrc:/multipage/resources/go-previous-view-page.svg"
+ enabled: view.backEnabled
onTriggered: view.back()
}
ToolTip.visible: enabled && hovered
@@ -138,7 +88,7 @@ ApplicationWindow {
SpinBox {
id: currentPageSB
from: 1
- to: document.pageCount
+ to: doc.pageCount
editable: true
onValueModified: view.goToPage(value - 1)
Shortcut {
@@ -152,7 +102,7 @@ ApplicationWindow {
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-next-view-page.svg"
+ icon.source: "qrc:/multipage/resources/go-next-view-page.svg"
enabled: view.forwardEnabled
onTriggered: view.forward()
}
@@ -163,21 +113,24 @@ ApplicationWindow {
ToolButton {
action: Action {
shortcut: StandardKey.SelectAll
- icon.source: "qrc:/pdfviewer/resources/edit-select-all.svg"
+ icon.source: "qrc:/multipage/resources/edit-select-all.svg"
onTriggered: view.selectAll()
}
}
ToolButton {
action: Action {
shortcut: StandardKey.Copy
- icon.source: "qrc:/pdfviewer/resources/edit-copy.svg"
+ icon.source: "qrc:/multipage/resources/edit-copy.svg"
enabled: view.selectedText !== ""
onTriggered: view.copySelectionToClipboard()
}
}
Shortcut {
sequence: StandardKey.Find
- onActivated: searchField.forceActiveFocus()
+ onActivated: {
+ searchField.forceActiveFocus()
+ searchField.selectAll()
+ }
}
Shortcut {
sequence: StandardKey.Quit
@@ -186,11 +139,11 @@ ApplicationWindow {
}
}
- Platform.FileDialog {
+ FileDialog {
id: fileDialog
title: "Open a PDF file"
nameFilters: [ "PDF files (*.pdf)" ]
- onAccepted: document.source = file
+ onAccepted: doc.source = selectedFile
}
Dialog {
@@ -202,55 +155,63 @@ ApplicationWindow {
anchors.centerIn: parent
width: 300
- TextField {
+ contentItem: TextField {
id: passwordField
placeholderText: qsTr("Please provide the password")
echoMode: TextInput.Password
width: parent.width
onAccepted: passwordDialog.accept()
}
- onAccepted: document.password = passwordField.text
+ onOpened: passwordField.forceActiveFocus()
+ onAccepted: doc.password = passwordField.text
}
Dialog {
id: errorDialog
- title: "Error loading " + document.source
- standardButtons: Dialog.Ok
+ title: "Error loading " + doc.source
+ standardButtons: Dialog.Close
modal: true
closePolicy: Popup.CloseOnEscape
anchors.centerIn: parent
width: 300
+ visible: doc.status === PdfDocument.Error
- Label {
+ contentItem: Label {
id: errorField
- text: document.error
+ text: doc.error
}
}
PdfDocument {
- id: document
+ id: doc
source: Qt.resolvedUrl(root.source)
- onStatusChanged: {
- if (status === PdfDocument.Error) errorDialog.open()
- view.document = (status === PdfDocument.Ready ? document : undefined)
- }
- onPasswordRequired: {
- passwordDialog.open()
- passwordField.forceActiveFocus()
- }
+ onPasswordRequired: passwordDialog.open()
}
PdfMultiPageView {
id: view
anchors.fill: parent
- anchors.leftMargin: searchDrawer.position * searchDrawer.width
- document: root.document
+ anchors.leftMargin: sidebar.position * sidebar.width
+ document: doc
searchString: searchField.text
onCurrentPageChanged: currentPageSB.value = view.currentPage + 1
}
+ DropArea {
+ anchors.fill: parent
+ keys: ["text/uri-list"]
+ onEntered: (drag) => {
+ drag.accepted = (drag.proposedAction === Qt.MoveAction || drag.proposedAction === Qt.CopyAction) &&
+ drag.hasUrls && drag.urls[0].endsWith("pdf")
+ }
+ onDropped: (drop) => {
+ doc.source = drop.urls[0]
+ drop.acceptProposedAction()
+ }
+ }
+
Drawer {
- id: searchDrawer
+ id: sidebar
edge: Qt.LeftEdge
modal: false
width: 300
@@ -258,58 +219,189 @@ ApplicationWindow {
height: view.height
dim: false
clip: true
- ListView {
- id: searchResultsList
+
+ TabBar {
+ id: sidebarTabs
+ x: -width
+ rotation: -90
+ transformOrigin: Item.TopRight
+ currentIndex: 2 // bookmarks by default
+ TabButton {
+ text: qsTr("Info")
+ }
+ TabButton {
+ text: qsTr("Search Results")
+ }
+ TabButton {
+ text: qsTr("Bookmarks")
+ }
+ TabButton {
+ text: qsTr("Pages")
+ }
+ }
+
+ GroupBox {
anchors.fill: parent
- anchors.margins: 2
- model: view.searchModel
- ScrollBar.vertical: ScrollBar { }
- delegate: ItemDelegate {
- width: parent ? parent.width : 0
- RowLayout {
- anchors.fill: parent
- spacing: 0
- Label {
- text: "Page " + (page + 1) + ": "
- }
- Label {
- text: contextBefore
- elide: Text.ElideLeft
- horizontalAlignment: Text.AlignRight
- Layout.fillWidth: true
- Layout.preferredWidth: parent.width / 2
+ anchors.leftMargin: sidebarTabs.height
+
+ StackLayout {
+ anchors.fill: parent
+ currentIndex: sidebarTabs.currentIndex
+ component InfoField: TextInput {
+ width: parent.width
+ selectByMouse: true
+ readOnly: true
+ wrapMode: Text.WordWrap
+ }
+ Column {
+ spacing: 6
+ width: parent.width - 6
+ Label { font.bold: true; text: qsTr("Title") }
+ InfoField { text: doc.title }
+ Label { font.bold: true; text: qsTr("Author") }
+ InfoField { text: doc.author }
+ Label { font.bold: true; text: qsTr("Subject") }
+ InfoField { text: doc.subject }
+ Label { font.bold: true; text: qsTr("Keywords") }
+ InfoField { text: doc.keywords }
+ Label { font.bold: true; text: qsTr("Producer") }
+ InfoField { text: doc.producer }
+ Label { font.bold: true; text: qsTr("Creator") }
+ InfoField { text: doc.creator }
+ Label { font.bold: true; text: qsTr("Creation date") }
+ InfoField { text: doc.creationDate }
+ Label { font.bold: true; text: qsTr("Modification date") }
+ InfoField { text: doc.modificationDate }
+ }
+ ListView {
+ id: searchResultsList
+ implicitHeight: parent.height
+ model: view.searchModel
+ currentIndex: view.searchModel.currentResult
+ ScrollBar.vertical: ScrollBar { }
+ delegate: ItemDelegate {
+ id: resultDelegate
+ required property int index
+ required property int page
+ required property string contextBefore
+ required property string contextAfter
+ width: parent ? parent.width : 0
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+ Label {
+ text: "Page " + (resultDelegate.page + 1) + ": "
+ }
+ Label {
+ text: resultDelegate.contextBefore
+ elide: Text.ElideLeft
+ horizontalAlignment: Text.AlignRight
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width / 2
+ }
+ Label {
+ font.bold: true
+ text: view.searchString
+ width: implicitWidth
+ }
+ Label {
+ text: resultDelegate.contextAfter
+ elide: Text.ElideRight
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width / 2
+ }
+ }
+ highlighted: ListView.isCurrentItem
+ onClicked: view.searchModel.currentResult = resultDelegate.index
}
- Label {
- font.bold: true
- text: view.searchString
- width: implicitWidth
+ }
+ TreeView {
+ id: bookmarksTree
+ implicitHeight: parent.height
+ implicitWidth: parent.width
+ columnWidthProvider: function() { return width }
+ delegate: TreeViewDelegate {
+ required property int page
+ required property point location
+ required property real zoom
+ onClicked: view.goToLocation(page, location, zoom)
}
- Label {
- text: contextAfter
- elide: Text.ElideRight
- Layout.fillWidth: true
- Layout.preferredWidth: parent.width / 2
+ model: PdfBookmarkModel {
+ document: doc
}
+ ScrollBar.vertical: ScrollBar { }
}
- highlighted: ListView.isCurrentItem
- onClicked: {
- searchResultsList.currentIndex = index
- view.goToLocation(page, location, 0)
- view.searchModel.currentResult = indexOnPage
+ GridView {
+ id: thumbnailsView
+ implicitWidth: parent.width
+ implicitHeight: parent.height
+ model: doc.pageModel
+ cellWidth: width / 2
+ cellHeight: cellWidth + 10
+ delegate: Item {
+ required property int index
+ required property string label
+ required property size pointSize
+ width: thumbnailsView.cellWidth
+ height: thumbnailsView.cellHeight
+ Rectangle {
+ id: paper
+ width: image.width
+ height: image.height
+ x: (parent.width - width) / 2
+ y: (parent.height - height - pageNumber.height) / 2
+ PdfPageImage {
+ id: image
+ document: doc
+ currentFrame: index
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ property bool landscape: pointSize.width > pointSize.height
+ width: landscape ? thumbnailsView.cellWidth - 6
+ : height * pointSize.width / pointSize.height
+ height: landscape ? width * pointSize.height / pointSize.width
+ : thumbnailsView.cellHeight - 14
+ sourceSize.width: width
+ sourceSize.height: height
+ }
+ }
+ Text {
+ id: pageNumber
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: label
+ }
+ TapHandler {
+ onTapped: view.goToPage(index)
+ }
+ }
}
}
}
}
footer: ToolBar {
- height: footerRow.implicitHeight
+ height: footerRow.implicitHeight + 6
RowLayout {
id: footerRow
anchors.fill: parent
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-up-search.svg"
+ id: sidebarOpenAction
+ checkable: true
+ checked: sidebar.opened
+ icon.source: checked ? "qrc:/multipage/resources/sidebar-collapse-left.svg" : "qrc:/multipage/resources/sidebar-expand-left.svg"
+ onTriggered: sidebar.open()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "open sidebar"
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "qrc:/multipage/resources/go-up-search.svg"
shortcut: StandardKey.FindPrevious
+ enabled: view.searchModel.count > 0
onTriggered: view.searchBack()
}
ToolTip.visible: enabled && hovered
@@ -321,16 +413,19 @@ ApplicationWindow {
placeholderText: "search"
Layout.minimumWidth: 150
Layout.fillWidth: true
- onAccepted: searchDrawer.open()
+ Layout.bottomMargin: 3
+ onAccepted: {
+ sidebar.open()
+ sidebarTabs.setCurrentIndex(1)
+ }
Image {
visible: searchField.text !== ""
- source: "qrc:/pdfviewer/resources/edit-clear.svg"
+ source: "qrc:/multipage/resources/edit-clear.svg"
+ sourceSize.height: searchField.height - 6
anchors {
right: parent.right
- top: parent.top
- bottom: parent.bottom
+ verticalCenter: parent.verticalCenter
margins: 3
- rightMargin: 5
}
TapHandler {
onTapped: searchField.clear()
@@ -339,8 +434,9 @@ ApplicationWindow {
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-down-search.svg"
+ icon.source: "qrc:/multipage/resources/go-down-search.svg"
shortcut: StandardKey.FindNext
+ enabled: view.searchModel.count > 0
onTriggered: view.searchForward()
}
ToolTip.visible: enabled && hovered
@@ -349,11 +445,11 @@ ApplicationWindow {
}
Label {
id: statusLabel
- property size implicitPointSize: document.pagePointSize(view.currentPage)
- text: "page " + (currentPageSB.value) + " of " + document.pageCount +
+ property size implicitPointSize: doc.pagePointSize(view.currentPage)
+ text: "page " + (currentPageSB.value) + " of " + doc.pageCount +
" scale " + view.renderScale.toFixed(2) +
" original " + implicitPointSize.width.toFixed(1) + "x" + implicitPointSize.height.toFixed(1) + " pt"
- visible: document.pageCount > 0
+ visible: doc.pageCount > 0
}
}
}
diff --git a/examples/pdf/multipage/viewer.qrc b/examples/pdf/multipage/viewer.qrc
index ffca51679..e786ae4ce 100644
--- a/examples/pdf/multipage/viewer.qrc
+++ b/examples/pdf/multipage/viewer.qrc
@@ -1,5 +1,5 @@
<RCC>
- <qresource prefix="/pdfviewer">
+ <qresource prefix="/singlepage">
<file>viewer.qml</file>
<file>resources/document-open.svg</file>
<file>resources/edit-clear.svg</file>
@@ -11,6 +11,8 @@
<file>resources/go-up-search.svg</file>
<file>resources/rotate-left.svg</file>
<file>resources/rotate-right.svg</file>
+ <file>resources/sidebar-collapse-left.svg</file>
+ <file>resources/sidebar-expand-left.svg</file>
<file>resources/test.pdf</file>
<file>resources/zoom-in.svg</file>
<file>resources/zoom-fit-best.svg</file>
diff --git a/examples/pdf/pdf.pro b/examples/pdf/pdf.pro
index 0ae198ee7..96ead5948 100644
--- a/examples/pdf/pdf.pro
+++ b/examples/pdf/pdf.pro
@@ -1,3 +1,3 @@
TEMPLATE=subdirs
-qtHaveModule(svg): SUBDIRS += pdfviewer multipage
+qtHaveModule(svg): SUBDIRS += singlepage multipage
diff --git a/examples/pdf/pdfviewer/main.cpp b/examples/pdf/pdfviewer/main.cpp
deleted file mode 100644
index b9f1e22de..000000000
--- a/examples/pdf/pdfviewer/main.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QGuiApplication>
-#include <QQmlApplicationEngine>
-
-int main(int argc, char* argv[])
-{
- QCoreApplication::setApplicationName("Qt Quick PDF Viewer Example");
- QCoreApplication::setOrganizationName("QtProject");
- QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QGuiApplication app(argc, argv);
-
- QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:///pdfviewer/viewer.qml")));
- if (app.arguments().count() > 1) {
- QUrl toLoad = QUrl::fromUserInput(app.arguments().at(1));
- engine.rootObjects().first()->setProperty("source", toLoad);
- } else {
- engine.rootObjects().first()->setProperty("source", QStringLiteral("resources/test.pdf"));
- }
-
- return app.exec();
-}
diff --git a/examples/pdf/pdfviewer/CMakeLists.txt b/examples/pdf/singlepage/CMakeLists.txt
index 5a3821399..fac95f54a 100644
--- a/examples/pdf/pdfviewer/CMakeLists.txt
+++ b/examples/pdf/singlepage/CMakeLists.txt
@@ -1,28 +1,28 @@
-cmake_minimum_required(VERSION 3.16)
-project(pdfviewer LANGUAGES CXX)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
+cmake_minimum_required(VERSION 3.16)
+project(singlepage LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/pdf/pdfviewer")
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/pdf/singlepage")
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Qml)
+find_package(Qt6 REQUIRED COMPONENTS Gui Qml)
qt_add_executable(pdfviewerquick
main.cpp
)
+
set_target_properties(pdfviewerquick PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(pdfviewerquick PUBLIC
Qt::Gui
Qt::Qml
@@ -50,7 +50,7 @@ set(viewer_resource_files
qt_add_resources(pdfviewerquick "viewer"
PREFIX
- "/pdfviewer"
+ "/singlepage"
FILES
${viewer_resource_files}
)
diff --git a/examples/pdf/singlepage/doc/src/singlepage.qdoc b/examples/pdf/singlepage/doc/src/singlepage.qdoc
new file mode 100644
index 000000000..773f9acae
--- /dev/null
+++ b/examples/pdf/singlepage/doc/src/singlepage.qdoc
@@ -0,0 +1,62 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example singlepage
+ \meta installpath pdf
+ \ingroup qtpdf-examples
+ \examplecategory {User Interface Components}
+
+ \title PDF Single Page Viewer Example
+ \brief A Qt Quick PDF viewer that views one page at a time.
+
+ \image singlepageviewer.webp
+
+ \e {PDF Single Page Viewer Example} demonstrates how to use the PdfScrollablePageView
+ component to render PDF documents and search for text in them.
+
+ \include examples-run.qdocinc
+
+ \section1 Creating the Main Window
+
+ Instantiate an \l ApplicationWindow, bind its title to the title of the
+ PDF document, and create a toolbar:
+
+ \quotefromfile singlepage/viewer.qml
+ \skipto ApplicationWindow
+ \printuntil rightMargin
+
+ The toolbar has buttons for most of the common actions,
+ plus a SpinBox to show and control the current page number:
+
+ \printuntil ZoomOut
+ \dots
+ \skipto SpinBox
+ \printto onValueModified
+ \dots
+
+ Add dialogs to inform the user when an error occurs and to prompt for a
+ password if required:
+
+ \skipto onAccepted
+ \skipto Dialog
+ \printto PdfScrollablePageView
+
+ Add the main component, PdfScrollablePageView:
+
+ \printto Drawer {
+
+ A \l Drawer holds a ListView to show search results from the
+ \l {PdfScrollablePageView::searchModel}{searchModel}:
+
+ \printto ToolBar
+
+ Finally, add a second toolbar as a footer, to hold the search field,
+ search up/down buttons and some status information:
+
+ \printuntil
+
+ \section1 Files and Attributions
+
+ \sa {PDF Multipage Viewer Example}
+*/
diff --git a/examples/pdf/singlepage/main.cpp b/examples/pdf/singlepage/main.cpp
new file mode 100644
index 000000000..be5c8f73c
--- /dev/null
+++ b/examples/pdf/singlepage/main.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QQmlApplicationEngine>
+
+#include <QGuiApplication>
+
+#include <QCommandLineParser>
+#include <QCommandLineOption>
+
+int main(int argc, char* argv[])
+{
+ QCoreApplication::setApplicationName("Qt Quick PDF Viewer Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QGuiApplication app(argc, argv);
+
+ QCommandLineParser parser;
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("file", "The file to open.");
+ parser.process(app);
+
+ QQmlApplicationEngine engine;
+
+ QUrl toLoad = QUrl("qrc:/singlepage/resources/test.pdf");
+ if (!parser.positionalArguments().isEmpty())
+ toLoad = QUrl::fromLocalFile(parser.positionalArguments().constFirst());
+
+ engine.setInitialProperties({{"source", toLoad}});
+
+ engine.load(QUrl(QStringLiteral("qrc:///singlepage/viewer.qml")));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ return app.exec();
+}
diff --git a/examples/pdf/pdfviewer/resources/document-open.svg b/examples/pdf/singlepage/resources/document-open.svg
index bf23123a3..bf23123a3 100644
--- a/examples/pdf/pdfviewer/resources/document-open.svg
+++ b/examples/pdf/singlepage/resources/document-open.svg
diff --git a/examples/pdf/pdfviewer/resources/edit-clear.svg b/examples/pdf/singlepage/resources/edit-clear.svg
index 1c35aaf04..1c35aaf04 100644
--- a/examples/pdf/pdfviewer/resources/edit-clear.svg
+++ b/examples/pdf/singlepage/resources/edit-clear.svg
diff --git a/examples/pdf/pdfviewer/resources/edit-copy.svg b/examples/pdf/singlepage/resources/edit-copy.svg
index 9dd16877d..9dd16877d 100644
--- a/examples/pdf/pdfviewer/resources/edit-copy.svg
+++ b/examples/pdf/singlepage/resources/edit-copy.svg
diff --git a/examples/pdf/pdfviewer/resources/edit-select-all.svg b/examples/pdf/singlepage/resources/edit-select-all.svg
index 5f21950a0..5f21950a0 100644
--- a/examples/pdf/pdfviewer/resources/edit-select-all.svg
+++ b/examples/pdf/singlepage/resources/edit-select-all.svg
diff --git a/examples/pdf/pdfviewer/resources/go-down-search.svg b/examples/pdf/singlepage/resources/go-down-search.svg
index ae17ab93b..ae17ab93b 100644
--- a/examples/pdf/pdfviewer/resources/go-down-search.svg
+++ b/examples/pdf/singlepage/resources/go-down-search.svg
diff --git a/examples/pdf/pdfviewer/resources/go-next-view-page.svg b/examples/pdf/singlepage/resources/go-next-view-page.svg
index e453ddbec..e453ddbec 100644
--- a/examples/pdf/pdfviewer/resources/go-next-view-page.svg
+++ b/examples/pdf/singlepage/resources/go-next-view-page.svg
diff --git a/examples/pdf/pdfviewer/resources/go-previous-view-page.svg b/examples/pdf/singlepage/resources/go-previous-view-page.svg
index b032309e9..b032309e9 100644
--- a/examples/pdf/pdfviewer/resources/go-previous-view-page.svg
+++ b/examples/pdf/singlepage/resources/go-previous-view-page.svg
diff --git a/examples/pdf/pdfviewer/resources/go-up-search.svg b/examples/pdf/singlepage/resources/go-up-search.svg
index 5cc155873..5cc155873 100644
--- a/examples/pdf/pdfviewer/resources/go-up-search.svg
+++ b/examples/pdf/singlepage/resources/go-up-search.svg
diff --git a/examples/pdf/pdfviewer/resources/rotate-left.svg b/examples/pdf/singlepage/resources/rotate-left.svg
index 90ce53c9d..90ce53c9d 100644
--- a/examples/pdf/pdfviewer/resources/rotate-left.svg
+++ b/examples/pdf/singlepage/resources/rotate-left.svg
diff --git a/examples/pdf/pdfviewer/resources/rotate-right.svg b/examples/pdf/singlepage/resources/rotate-right.svg
index 7383d1c84..7383d1c84 100644
--- a/examples/pdf/pdfviewer/resources/rotate-right.svg
+++ b/examples/pdf/singlepage/resources/rotate-right.svg
diff --git a/examples/pdf/pdfviewer/resources/test.pdf b/examples/pdf/singlepage/resources/test.pdf
index a9dc1bc29..0832dfbed 100644
--- a/examples/pdf/pdfviewer/resources/test.pdf
+++ b/examples/pdf/singlepage/resources/test.pdf
Binary files differ
diff --git a/examples/pdf/pdfviewer/resources/zoom-fit-best.svg b/examples/pdf/singlepage/resources/zoom-fit-best.svg
index adf302621..adf302621 100644
--- a/examples/pdf/pdfviewer/resources/zoom-fit-best.svg
+++ b/examples/pdf/singlepage/resources/zoom-fit-best.svg
diff --git a/examples/pdf/pdfviewer/resources/zoom-fit-width.svg b/examples/pdf/singlepage/resources/zoom-fit-width.svg
index 985ee5205..985ee5205 100644
--- a/examples/pdf/pdfviewer/resources/zoom-fit-width.svg
+++ b/examples/pdf/singlepage/resources/zoom-fit-width.svg
diff --git a/examples/pdf/pdfviewer/resources/zoom-in.svg b/examples/pdf/singlepage/resources/zoom-in.svg
index efdc9f17d..efdc9f17d 100644
--- a/examples/pdf/pdfviewer/resources/zoom-in.svg
+++ b/examples/pdf/singlepage/resources/zoom-in.svg
diff --git a/examples/pdf/pdfviewer/resources/zoom-original.svg b/examples/pdf/singlepage/resources/zoom-original.svg
index 1b4080a03..1b4080a03 100644
--- a/examples/pdf/pdfviewer/resources/zoom-original.svg
+++ b/examples/pdf/singlepage/resources/zoom-original.svg
diff --git a/examples/pdf/pdfviewer/resources/zoom-out.svg b/examples/pdf/singlepage/resources/zoom-out.svg
index fcde9e526..fcde9e526 100644
--- a/examples/pdf/pdfviewer/resources/zoom-out.svg
+++ b/examples/pdf/singlepage/resources/zoom-out.svg
diff --git a/examples/pdf/pdfviewer/pdfviewer.pro b/examples/pdf/singlepage/singlepage.pro
index a1c578efc..3b9f6399d 100644
--- a/examples/pdf/pdfviewer/pdfviewer.pro
+++ b/examples/pdf/singlepage/singlepage.pro
@@ -9,6 +9,6 @@ RESOURCES += \
EXAMPLE_FILES = \
viewer.qml
-target.path = $$[QT_INSTALL_EXAMPLES]/pdf/pdfviewer
+target.path = $$[QT_INSTALL_EXAMPLES]/pdf/singlepage
INSTALLS += target
diff --git a/examples/pdf/pdfviewer/viewer.qml b/examples/pdf/singlepage/viewer.qml
index 8c85a09da..9b6668a3a 100644
--- a/examples/pdf/pdfviewer/viewer.qml
+++ b/examples/pdf/singlepage/viewer.qml
@@ -1,61 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 QtQml // workaround for QTBUG-82873
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
+import QtQuick.Dialogs
import QtQuick.Layouts
import QtQuick.Pdf
-import QtQuick.Shapes
-import QtQuick.Window
-import Qt.labs.animation
-import Qt.labs.platform as Platform
ApplicationWindow {
id: root
@@ -64,7 +13,7 @@ ApplicationWindow {
color: "lightgrey"
title: document.title
visible: true
- property string source // for main.cpp
+ required property url source // for main.cpp
property real scaleStep: Math.sqrt(2)
header: ToolBar {
@@ -74,7 +23,7 @@ ApplicationWindow {
ToolButton {
action: Action {
shortcut: StandardKey.Open
- icon.source: "qrc:/pdfviewer/resources/document-open.svg"
+ icon.source: "qrc:/singlepage/resources/document-open.svg"
onTriggered: fileDialog.open()
}
}
@@ -82,7 +31,7 @@ ApplicationWindow {
action: Action {
shortcut: StandardKey.ZoomIn
enabled: view.sourceSize.width < 10000
- icon.source: "qrc:/pdfviewer/resources/zoom-in.svg"
+ icon.source: "qrc:/singlepage/resources/zoom-in.svg"
onTriggered: view.renderScale *= root.scaleStep
}
}
@@ -90,46 +39,46 @@ ApplicationWindow {
action: Action {
shortcut: StandardKey.ZoomOut
enabled: view.sourceSize.width > 50
- icon.source: "qrc:/pdfviewer/resources/zoom-out.svg"
+ icon.source: "qrc:/singlepage/resources/zoom-out.svg"
onTriggered: view.renderScale /= root.scaleStep
}
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/zoom-fit-width.svg"
+ icon.source: "qrc:/singlepage/resources/zoom-fit-width.svg"
onTriggered: view.scaleToWidth(root.contentItem.width, root.contentItem.height)
}
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/zoom-fit-best.svg"
+ icon.source: "qrc:/singlepage/resources/zoom-fit-best.svg"
onTriggered: view.scaleToPage(root.contentItem.width, root.contentItem.height)
}
}
ToolButton {
action: Action {
shortcut: "Ctrl+0"
- icon.source: "qrc:/pdfviewer/resources/zoom-original.svg"
+ icon.source: "qrc:/singlepage/resources/zoom-original.svg"
onTriggered: view.resetScale()
}
}
ToolButton {
action: Action {
shortcut: "Ctrl+L"
- icon.source: "qrc:/pdfviewer/resources/rotate-left.svg"
+ icon.source: "qrc:/singlepage/resources/rotate-left.svg"
onTriggered: view.pageRotation -= 90
}
}
ToolButton {
action: Action {
shortcut: "Ctrl+R"
- icon.source: "qrc:/pdfviewer/resources/rotate-right.svg"
+ icon.source: "qrc:/singlepage/resources/rotate-right.svg"
onTriggered: view.pageRotation += 90
}
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-previous-view-page.svg"
+ icon.source: "qrc:/singlepage/resources/go-previous-view-page.svg"
enabled: view.backEnabled
onTriggered: view.back()
}
@@ -155,7 +104,7 @@ ApplicationWindow {
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-next-view-page.svg"
+ icon.source: "qrc:/singlepage/resources/go-next-view-page.svg"
enabled: view.forwardEnabled
onTriggered: view.forward()
}
@@ -166,21 +115,24 @@ ApplicationWindow {
ToolButton {
action: Action {
shortcut: StandardKey.SelectAll
- icon.source: "qrc:/pdfviewer/resources/edit-select-all.svg"
+ icon.source: "qrc:/singlepage/resources/edit-select-all.svg"
onTriggered: view.selectAll()
}
}
ToolButton {
action: Action {
shortcut: StandardKey.Copy
- icon.source: "qrc:/pdfviewer/resources/edit-copy.svg"
+ icon.source: "qrc:/singlepage/resources/edit-copy.svg"
enabled: view.selectedText !== ""
onTriggered: view.copySelectionToClipboard()
}
}
Shortcut {
sequence: StandardKey.Find
- onActivated: searchField.forceActiveFocus()
+ onActivated: {
+ searchField.forceActiveFocus()
+ searchField.selectAll()
+ }
}
Shortcut {
sequence: StandardKey.Quit
@@ -189,23 +141,44 @@ ApplicationWindow {
}
}
- Platform.FileDialog {
+ FileDialog {
id: fileDialog
title: "Open a PDF file"
nameFilters: [ "PDF files (*.pdf)" ]
- onAccepted: document.source = file
+ onAccepted: document.source = selectedFile
+ }
+
+ Dialog {
+ id: passwordDialog
+ title: "Password"
+ standardButtons: Dialog.Ok | Dialog.Cancel
+ modal: true
+ closePolicy: Popup.CloseOnEscape
+ anchors.centerIn: parent
+ width: 300
+
+ contentItem: TextField {
+ id: passwordField
+ placeholderText: qsTr("Please provide the password")
+ echoMode: TextInput.Password
+ width: parent.width
+ onAccepted: passwordDialog.accept()
+ }
+ onOpened: function() { passwordField.forceActiveFocus() }
+ onAccepted: document.password = passwordField.text
}
Dialog {
id: errorDialog
title: "Error loading " + document.source
- standardButtons: Dialog.Ok
+ standardButtons: Dialog.Close
modal: true
closePolicy: Popup.CloseOnEscape
anchors.centerIn: parent
width: 300
+ visible: document.status === PdfDocument.Error
- Label {
+ contentItem: Label {
id: errorField
text: document.error
}
@@ -218,7 +191,7 @@ ApplicationWindow {
document: PdfDocument {
id: document
source: Qt.resolvedUrl(root.source)
- onStatusChanged: if (status === PdfDocument.Error) errorDialog.open()
+ onPasswordRequired: passwordDialog.open()
}
searchString: searchField.text
}
@@ -237,17 +210,23 @@ ApplicationWindow {
anchors.fill: parent
anchors.margins: 2
model: view.searchModel
+ currentIndex: view.searchModel.currentResult
ScrollBar.vertical: ScrollBar { }
delegate: ItemDelegate {
+ id: resultDelegate
+ required property int index
+ required property int page
+ required property string contextBefore
+ required property string contextAfter
width: parent ? parent.width : 0
RowLayout {
anchors.fill: parent
spacing: 0
Label {
- text: "Page " + (page + 1) + ": "
+ text: "Page " + (resultDelegate.page + 1) + ": "
}
Label {
- text: contextBefore
+ text: resultDelegate.contextBefore
elide: Text.ElideLeft
horizontalAlignment: Text.AlignRight
Layout.fillWidth: true
@@ -259,18 +238,14 @@ ApplicationWindow {
width: implicitWidth
}
Label {
- text: contextAfter
+ text: resultDelegate.contextAfter
elide: Text.ElideRight
Layout.fillWidth: true
Layout.preferredWidth: parent.width / 2
}
}
highlighted: ListView.isCurrentItem
- onClicked: {
- searchResultsList.currentIndex = index
- view.goToLocation(page, location, 0)
- view.searchModel.currentResult = indexOnPage
- }
+ onClicked: view.searchModel.currentResult = resultDelegate.index
}
}
}
@@ -282,8 +257,9 @@ ApplicationWindow {
anchors.fill: parent
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-up-search.svg"
+ icon.source: "qrc:/singlepage/resources/go-up-search.svg"
shortcut: StandardKey.FindPrevious
+ enabled: view.searchModel.count > 0
onTriggered: view.searchBack()
}
ToolTip.visible: enabled && hovered
@@ -299,7 +275,7 @@ ApplicationWindow {
onAccepted: searchDrawer.open()
Image {
visible: searchField.text !== ""
- source: "qrc:/pdfviewer/resources/edit-clear.svg"
+ source: "qrc:/singlepage/resources/edit-clear.svg"
anchors {
right: parent.right
top: parent.top
@@ -314,8 +290,9 @@ ApplicationWindow {
}
ToolButton {
action: Action {
- icon.source: "qrc:/pdfviewer/resources/go-down-search.svg"
+ icon.source: "qrc:/singlepage/resources/go-down-search.svg"
shortcut: StandardKey.FindNext
+ enabled: view.searchModel.count > 0
onTriggered: view.searchForward()
}
ToolTip.visible: enabled && hovered
diff --git a/examples/pdf/pdfviewer/viewer.qrc b/examples/pdf/singlepage/viewer.qrc
index ffca51679..6f8af53ac 100644
--- a/examples/pdf/pdfviewer/viewer.qrc
+++ b/examples/pdf/singlepage/viewer.qrc
@@ -1,5 +1,5 @@
<RCC>
- <qresource prefix="/pdfviewer">
+ <qresource prefix="/singlepage">
<file>viewer.qml</file>
<file>resources/document-open.svg</file>
<file>resources/edit-clear.svg</file>
diff --git a/examples/pdfwidgets/CMakeLists.txt b/examples/pdfwidgets/CMakeLists.txt
index 37496ebe3..dbde7f1c2 100644
--- a/examples/pdfwidgets/CMakeLists.txt
+++ b/examples/pdfwidgets/CMakeLists.txt
@@ -1 +1 @@
-add_subdirectory(pdfviewer)
+qt_internal_add_example(pdfviewer)
diff --git a/examples/pdfwidgets/pdfviewer/CMakeLists.txt b/examples/pdfwidgets/pdfviewer/CMakeLists.txt
index 692c33371..4ace81618 100644
--- a/examples/pdfwidgets/pdfviewer/CMakeLists.txt
+++ b/examples/pdfwidgets/pdfviewer/CMakeLists.txt
@@ -1,34 +1,32 @@
-# Generated from pdfviewer.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(pdfviewer LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/pdfwidgets/pdfviewer")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Widgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets PdfWidgets)
qt_add_executable(pdfviewerwidgets
main.cpp
mainwindow.cpp mainwindow.h mainwindow.ui
- pageselector.cpp pageselector.h
+ searchresultdelegate.cpp searchresultdelegate.h
zoomselector.cpp zoomselector.h
)
+
set_target_properties(pdfviewerwidgets PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(pdfviewerwidgets PUBLIC
Qt::Core
Qt::Gui
@@ -36,17 +34,21 @@ target_link_libraries(pdfviewerwidgets PUBLIC
Qt::PdfWidgets
)
-
# Resources:
set(resources_resource_files
- "images/busy.png"
- "images/fileopen.png"
- "images/go-next-24.png"
- "images/go-previous-24.png"
- "images/zoom-in-24.png"
- "images/zoom-in-32.png"
- "images/zoom-out-24.png"
- "images/zoom-out-32.png"
+ "images/zoom-fit-width.svgz"
+ "images/zoom-in.svgz"
+ "images/go-previous-view-page.svgz"
+ "images/zoom-original.svgz"
+ "images/go-previous-view.svgz"
+ "images/go-next-view-page.svgz"
+ "images/zoom-fit-best.svgz"
+ "images/zoom-out.svgz"
+ "images/zoom-previous.svgz"
+ "images/document-open.svgz"
+ "images/go-next-view.svgz"
+ "images/go-down-search.svgz"
+ "images/go-up-search.svgz"
)
qt_add_resources(pdfviewerwidgets "resources"
diff --git a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
index 0cdd671be..b56958a9f 100644
--- a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
+++ b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc
@@ -1,43 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example pdfviewer
+ \meta installpath pdfwidgets
\ingroup qtpdf-examples
+ \examplecategory {User Interface Components}
- \title PDF Viewer Example
- \brief Renders PDF documents.
+ \title PDF Viewer Widget Example
+ \brief A widget-based PDF viewer that allows scrolling through the pages.
- \omit
- //! TODO add thumbnail \image pdfviewer.png
- \endomit
+ \image pdfviewer.png
- \e {PDF Viewer} demonstrates how to use the QPdfDocument class to render
- PDF documents and the QPdfPageNavigation class to navigate them.
+ \e {PDF Viewer} demonstrates how to use the QPdfView class to render
+ PDF documents and the QPdfPageNavigator class to navigate them.
Qt Creator and the integrated Qt Designer were used to create the example
UI and to connect it to the code. This affects the code, which might be
@@ -58,7 +34,7 @@
The class declares public and private slots that match the actions of the
selectors:
- \printuntil on_actionContinuous_triggered()
+ \printuntil on_actionForward_triggered()
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.
@@ -79,16 +55,17 @@
\skipto MainWindow
\printuntil {
- The constructor first calls \c setupUi() to construct the zoom and page
- selectors according to the UI file. We set the maximum width of the
- selectors.
+ The constructor first calls \c setupUi() to construct most of the main window
+ according to the UI file. The zoom and page selectors need to be added to
+ the toolbar via \l QToolBar::insertWidget(), because that cannot be done
+ in a UI file:
- \printuntil addWidget(m_pageSelector)
+ \printuntil insertWidget(ui->actionForward, m_pageSelector);
- We use the QPdfPageNavigation class to handle the navigation through a
- PDF document:
+ We connect relevant signals to the page selector spinbox and the browser-style
+ back and forward buttons:
- \printuntil setPageNavigation
+ \printuntil forwardAvailableChanged
We connect the \c zoomModeChanged and \c zoomFactor changed signals of the
PDF view to the functions that reset the zoom selector:
diff --git a/examples/pdfwidgets/pdfviewer/images/busy.png b/examples/pdfwidgets/pdfviewer/images/busy.png
deleted file mode 100644
index 69056c479..000000000
--- a/examples/pdfwidgets/pdfviewer/images/busy.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/document-open.svgz b/examples/pdfwidgets/pdfviewer/images/document-open.svgz
new file mode 100644
index 000000000..5ddde5981
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/document-open.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/fileopen.png b/examples/pdfwidgets/pdfviewer/images/fileopen.png
deleted file mode 100644
index 33e0d6394..000000000
--- a/examples/pdfwidgets/pdfviewer/images/fileopen.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-down-search.svgz b/examples/pdfwidgets/pdfviewer/images/go-down-search.svgz
new file mode 100644
index 000000000..f845473e7
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-down-search.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-next-24.png b/examples/pdfwidgets/pdfviewer/images/go-next-24.png
deleted file mode 100644
index 9a55ef3d8..000000000
--- a/examples/pdfwidgets/pdfviewer/images/go-next-24.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-next-view-page.svgz b/examples/pdfwidgets/pdfviewer/images/go-next-view-page.svgz
new file mode 100644
index 000000000..e7f7bece4
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-next-view-page.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-next-view.svgz b/examples/pdfwidgets/pdfviewer/images/go-next-view.svgz
new file mode 100644
index 000000000..2f86541cc
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-next-view.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-previous-24.png b/examples/pdfwidgets/pdfviewer/images/go-previous-24.png
deleted file mode 100644
index 2ea769eb8..000000000
--- a/examples/pdfwidgets/pdfviewer/images/go-previous-24.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-previous-view-page.svgz b/examples/pdfwidgets/pdfviewer/images/go-previous-view-page.svgz
new file mode 100644
index 000000000..f4df6df40
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-previous-view-page.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-previous-view.svgz b/examples/pdfwidgets/pdfviewer/images/go-previous-view.svgz
new file mode 100644
index 000000000..688f55ffe
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-previous-view.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/go-up-search.svgz b/examples/pdfwidgets/pdfviewer/images/go-up-search.svgz
new file mode 100644
index 000000000..6378721fa
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/go-up-search.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-fit-best.svgz b/examples/pdfwidgets/pdfviewer/images/zoom-fit-best.svgz
new file mode 100644
index 000000000..0cb1b3074
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-fit-best.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-fit-width.svgz b/examples/pdfwidgets/pdfviewer/images/zoom-fit-width.svgz
new file mode 100644
index 000000000..a467f6eae
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-fit-width.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png b/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png
deleted file mode 100644
index d29b142b6..000000000
--- a/examples/pdfwidgets/pdfviewer/images/zoom-in-24.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png b/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png
deleted file mode 100644
index 34d70af37..000000000
--- a/examples/pdfwidgets/pdfviewer/images/zoom-in-32.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-in.svgz b/examples/pdfwidgets/pdfviewer/images/zoom-in.svgz
new file mode 100644
index 000000000..21d6c2ab2
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-in.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-original.svgz b/examples/pdfwidgets/pdfviewer/images/zoom-original.svgz
new file mode 100644
index 000000000..afa79db19
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-original.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png b/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png
deleted file mode 100644
index 19703474f..000000000
--- a/examples/pdfwidgets/pdfviewer/images/zoom-out-24.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png b/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png
deleted file mode 100644
index b83220661..000000000
--- a/examples/pdfwidgets/pdfviewer/images/zoom-out-32.png
+++ /dev/null
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-out.svgz b/examples/pdfwidgets/pdfviewer/images/zoom-out.svgz
new file mode 100644
index 000000000..b6db7a144
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-out.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/images/zoom-previous.svgz b/examples/pdfwidgets/pdfviewer/images/zoom-previous.svgz
new file mode 100644
index 000000000..ad4c29215
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/images/zoom-previous.svgz
Binary files differ
diff --git a/examples/pdfwidgets/pdfviewer/main.cpp b/examples/pdfwidgets/pdfviewer/main.cpp
index 20fa6f8cd..6b890e0ac 100644
--- a/examples/pdfwidgets/pdfviewer/main.cpp
+++ b/examples/pdfwidgets/pdfviewer/main.cpp
@@ -1,51 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QApplication>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
#include <QUrl>
int main(int argc, char *argv[])
{
+ QCoreApplication::setApplicationName("Qt PDF Viewer");
+ QCoreApplication::setOrganizationName("QtProject");
+
QApplication a(argc, argv);
+
+ QCommandLineParser parser;
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("file", "The file to open.");
+ parser.process(a);
+
MainWindow w;
- QStringList args = a.arguments();
w.show();
- if (args.length() > 1)
- w.open(QUrl::fromLocalFile(args[1]));
+ if (!parser.positionalArguments().isEmpty())
+ w.open(QUrl::fromLocalFile(parser.positionalArguments().constFirst()));
return a.exec();
}
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.cpp b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
index 5f9bf389f..ce19359fc 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.cpp
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.cpp
@@ -1,50 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include "ui_mainwindow.h"
-#include "pageselector.h"
+#include "searchresultdelegate.h"
#include "zoomselector.h"
#include <QFileDialog>
+#include <QLineEdit>
#include <QMessageBox>
#include <QPdfBookmarkModel>
#include <QPdfDocument>
-#include <QPdfPageNavigation>
+#include <QPdfPageNavigator>
+#include <QPdfPageSelector>
+#include <QPdfSearchModel>
+#include <QShortcut>
+#include <QStandardPaths>
#include <QtMath>
const qreal zoomMultiplier = qSqrt(2.0);
@@ -55,7 +27,9 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_zoomSelector(new ZoomSelector(this))
- , m_pageSelector(new PageSelector(this))
+ , m_pageSelector(new QPdfPageSelector(this))
+ , m_searchModel(new QPdfSearchModel(this))
+ , m_searchField(new QLineEdit(this))
, m_document(new QPdfDocument(this))
{
ui->setupUi(this);
@@ -63,10 +37,13 @@ MainWindow::MainWindow(QWidget *parent)
m_zoomSelector->setMaximumWidth(150);
ui->mainToolBar->insertWidget(ui->actionZoom_In, m_zoomSelector);
- m_pageSelector->setMaximumWidth(150);
- ui->mainToolBar->addWidget(m_pageSelector);
-
- m_pageSelector->setPageNavigation(ui->pdfView->pageNavigation());
+ ui->mainToolBar->insertWidget(ui->actionForward, m_pageSelector);
+ connect(m_pageSelector, &QPdfPageSelector::currentPageChanged, this, &MainWindow::pageSelected);
+ m_pageSelector->setDocument(m_document);
+ auto nav = ui->pdfView->pageNavigator();
+ connect(nav, &QPdfPageNavigator::currentPageChanged, m_pageSelector, &QPdfPageSelector::setCurrentPage);
+ connect(nav, &QPdfPageNavigator::backAvailableChanged, ui->actionBack, &QAction::setEnabled);
+ connect(nav, &QPdfPageNavigator::forwardAvailableChanged, ui->actionForward, &QAction::setEnabled);
connect(m_zoomSelector, &ZoomSelector::zoomModeChanged, ui->pdfView, &QPdfView::setZoomMode);
connect(m_zoomSelector, &ZoomSelector::zoomFactorChanged, ui->pdfView, &QPdfView::setZoomFactor);
@@ -76,9 +53,26 @@ MainWindow::MainWindow(QWidget *parent)
bookmarkModel->setDocument(m_document);
ui->bookmarkView->setModel(bookmarkModel);
- connect(ui->bookmarkView, SIGNAL(activated(QModelIndex)), this, SLOT(bookmarkSelected(QModelIndex)));
-
- ui->tabWidget->setTabEnabled(1, false); // disable 'Pages' tab for now
+ connect(ui->bookmarkView, &QAbstractItemView::activated, this, &MainWindow::bookmarkSelected);
+
+ ui->thumbnailsView->setModel(m_document->pageModel());
+
+ m_searchModel->setDocument(m_document);
+ ui->pdfView->setSearchModel(m_searchModel);
+ ui->searchToolBar->insertWidget(ui->actionFindPrevious, m_searchField);
+ connect(new QShortcut(QKeySequence::Find, this), &QShortcut::activated, this, [this]() {
+ m_searchField->setFocus(Qt::ShortcutFocusReason);
+ });
+ m_searchField->setPlaceholderText(tr("Find in document"));
+ m_searchField->setMaximumWidth(400);
+ connect(m_searchField, &QLineEdit::textEdited, this, [this](const QString &text) {
+ m_searchModel->setSearchString(text);
+ ui->tabWidget->setCurrentWidget(ui->searchResultsTab);
+ });
+ ui->searchResultsView->setModel(m_searchModel);
+ ui->searchResultsView->setItemDelegate(new SearchResultDelegate(this));
+ connect(ui->searchResultsView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &MainWindow::searchResultSelected);
ui->pdfView->setDocument(m_document);
@@ -95,11 +89,11 @@ void MainWindow::open(const QUrl &docLocation)
{
if (docLocation.isLocalFile()) {
m_document->load(docLocation.toLocalFile());
- const auto documentTitle = m_document->metaData(QPdfDocument::Title).toString();
- setWindowTitle(!documentTitle.isEmpty() ? documentTitle : QStringLiteral("PDF Viewer"));
+ pageSelected(0);
} else {
- qCDebug(lcExample) << docLocation << "is not a valid local file";
- QMessageBox::critical(this, tr("Failed to open"), tr("%1 is not a valid local file").arg(docLocation.toString()));
+ const QString message = tr("%1 is not a valid local file").arg(docLocation.toString());
+ qCDebug(lcExample).noquote() << message;
+ QMessageBox::critical(this, tr("Failed to open"), message);
}
qCDebug(lcExample) << docLocation;
}
@@ -109,15 +103,48 @@ void MainWindow::bookmarkSelected(const QModelIndex &index)
if (!index.isValid())
return;
- const int page = index.data(QPdfBookmarkModel::PageNumberRole).toInt();
- ui->pdfView->pageNavigation()->setCurrentPage(page);
+ const int page = index.data(int(QPdfBookmarkModel::Role::Page)).toInt();
+ const qreal zoomLevel = index.data(int(QPdfBookmarkModel::Role::Level)).toReal();
+ ui->pdfView->pageNavigator()->jump(page, {}, zoomLevel);
+}
+
+void MainWindow::pageSelected(int page)
+{
+ auto nav = ui->pdfView->pageNavigator();
+ nav->jump(page, {}, nav->currentZoom());
+ const auto documentTitle = m_document->metaData(QPdfDocument::MetaDataField::Title).toString();
+ setWindowTitle(!documentTitle.isEmpty() ? documentTitle : QStringLiteral("PDF Viewer"));
+ setWindowTitle(tr("%1: page %2 (%3 of %4)")
+ .arg(documentTitle.isEmpty() ? u"PDF Viewer"_qs : documentTitle,
+ m_pageSelector->currentPageLabel(), QString::number(page + 1), QString::number(m_document->pageCount())));
+}
+
+void MainWindow::searchResultSelected(const QModelIndex &current, const QModelIndex &previous)
+{
+ Q_UNUSED(previous);
+ if (!current.isValid())
+ return;
+
+ const int page = current.data(int(QPdfSearchModel::Role::Page)).toInt();
+ const QPointF location = current.data(int(QPdfSearchModel::Role::Location)).toPointF();
+ ui->pdfView->pageNavigator()->jump(page, location);
+ ui->pdfView->setCurrentSearchResultIndex(current.row());
}
void MainWindow::on_actionOpen_triggered()
{
- QUrl toOpen = QFileDialog::getOpenFileUrl(this, tr("Choose a PDF"), QUrl(), "Portable Documents (*.pdf)");
- if (toOpen.isValid())
- open(toOpen);
+ if (m_fileDialog == nullptr) {
+ m_fileDialog = new QFileDialog(this, tr("Choose a PDF"),
+ QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
+ m_fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
+ m_fileDialog->setMimeTypeFilters({"application/pdf"});
+ }
+
+ if (m_fileDialog->exec() == QDialog::Accepted) {
+ const QUrl toOpen = m_fileDialog->selectedUrls().constFirst();
+ if (toOpen.isValid())
+ open(toOpen);
+ }
}
void MainWindow::on_actionQuit_triggered()
@@ -148,15 +175,51 @@ void MainWindow::on_actionZoom_Out_triggered()
void MainWindow::on_actionPrevious_Page_triggered()
{
- ui->pdfView->pageNavigation()->goToPreviousPage();
+ auto nav = ui->pdfView->pageNavigator();
+ nav->jump(nav->currentPage() - 1, {}, nav->currentZoom());
}
void MainWindow::on_actionNext_Page_triggered()
{
- ui->pdfView->pageNavigation()->goToNextPage();
+ auto nav = ui->pdfView->pageNavigator();
+ nav->jump(nav->currentPage() + 1, {}, nav->currentZoom());
+}
+
+void MainWindow::on_thumbnailsView_activated(const QModelIndex &index)
+{
+ auto nav = ui->pdfView->pageNavigator();
+ nav->jump(index.row(), {}, nav->currentZoom());
}
void MainWindow::on_actionContinuous_triggered()
{
- ui->pdfView->setPageMode(ui->actionContinuous->isChecked() ? QPdfView::MultiPage : QPdfView::SinglePage);
+ ui->pdfView->setPageMode(ui->actionContinuous->isChecked() ?
+ QPdfView::PageMode::MultiPage :
+ QPdfView::PageMode::SinglePage);
+}
+
+void MainWindow::on_actionBack_triggered()
+{
+ ui->pdfView->pageNavigator()->back();
+}
+
+void MainWindow::on_actionForward_triggered()
+{
+ ui->pdfView->pageNavigator()->forward();
+}
+
+void MainWindow::on_actionFindNext_triggered()
+{
+ int next = ui->searchResultsView->currentIndex().row() + 1;
+ if (next >= m_searchModel->rowCount({}))
+ next = 0;
+ ui->searchResultsView->setCurrentIndex(m_searchModel->index(next));
+}
+
+void MainWindow::on_actionFindPrevious_triggered()
+{
+ int prev = ui->searchResultsView->currentIndex().row() - 1;
+ if (prev < 0)
+ prev = m_searchModel->rowCount({}) - 1;
+ ui->searchResultsView->setCurrentIndex(m_searchModel->index(prev));
}
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.h b/examples/pdfwidgets/pdfviewer/mainwindow.h
index afdfcade4..7f5a5dbca 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.h
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
@@ -47,11 +14,15 @@ namespace Ui {
class MainWindow;
}
+class QFileDialog;
+class QLineEdit;
class QPdfDocument;
+class QPdfPageSelector;
+class QPdfSearchModel;
class QPdfView;
+class QSpinBox;
QT_END_NAMESPACE
-class PageSelector;
class ZoomSelector;
class MainWindow : public QMainWindow
@@ -67,6 +38,8 @@ public slots:
private slots:
void bookmarkSelected(const QModelIndex &index);
+ void pageSelected(int page);
+ void searchResultSelected(const QModelIndex &current, const QModelIndex &previous);
// action handlers
void on_actionOpen_triggered();
@@ -77,12 +50,20 @@ private slots:
void on_actionZoom_Out_triggered();
void on_actionPrevious_Page_triggered();
void on_actionNext_Page_triggered();
+ void on_thumbnailsView_activated(const QModelIndex &index);
void on_actionContinuous_triggered();
+ void on_actionBack_triggered();
+ void on_actionForward_triggered();
+ void on_actionFindNext_triggered();
+ void on_actionFindPrevious_triggered();
private:
Ui::MainWindow *ui;
ZoomSelector *m_zoomSelector;
- PageSelector *m_pageSelector;
+ QPdfPageSelector *m_pageSelector;
+ QPdfSearchModel *m_searchModel;
+ QLineEdit *m_searchField;
+ QFileDialog *m_fileDialog = nullptr;
QPdfDocument *m_document;
};
diff --git a/examples/pdfwidgets/pdfviewer/mainwindow.ui b/examples/pdfwidgets/pdfviewer/mainwindow.ui
index 2651525a5..881df2e1b 100644
--- a/examples/pdfwidgets/pdfviewer/mainwindow.ui
+++ b/examples/pdfwidgets/pdfviewer/mainwindow.ui
@@ -111,6 +111,74 @@
<attribute name="title">
<string>Pages</string>
</attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QListView" name="thumbnailsView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>128</width>
+ <height>128</height>
+ </size>
+ </property>
+ <property name="movement">
+ <enum>QListView::Static</enum>
+ </property>
+ <property name="resizeMode">
+ <enum>QListView::Adjust</enum>
+ </property>
+ <property name="viewMode">
+ <enum>QListView::IconMode</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="searchResultsTab">
+ <attribute name="title">
+ <string>Search Results</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>2</number>
+ </property>
+ <property name="bottomMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QListView" name="searchResultsView">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</widget>
<widget class="QPdfView" name="pdfView" native="true">
@@ -134,7 +202,7 @@
<x>0</x>
<y>0</y>
<width>700</width>
- <height>22</height>
+ <height>23</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -184,12 +252,27 @@
<addaction name="actionZoom_Out"/>
<addaction name="actionZoom_In"/>
<addaction name="separator"/>
+ <addaction name="actionBack"/>
+ <addaction name="actionForward"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
+ <widget class="QToolBar" name="searchToolBar">
+ <property name="windowTitle">
+ <string>toolBar</string>
+ </property>
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ <addaction name="actionFindPrevious"/>
+ <addaction name="actionFindNext"/>
+ </widget>
<action name="actionOpen">
<property name="icon">
- <iconset resource="resources.qrc">
- <normaloff>:/icons/images/fileopen.png</normaloff>:/icons/images/fileopen.png</iconset>
+ <iconset theme="document-open" resource="resources.qrc">
+ <normaloff>:/icons/images/document-open.svgz</normaloff>:/icons/images/document-open.svgz</iconset>
</property>
<property name="text">
<string>Open...</string>
@@ -199,6 +282,9 @@
</property>
</action>
<action name="actionQuit">
+ <property name="icon">
+ <iconset theme="application-exit"/>
+ </property>
<property name="text">
<string>Quit</string>
</property>
@@ -207,6 +293,9 @@
</property>
</action>
<action name="actionAbout">
+ <property name="icon">
+ <iconset theme="help-about"/>
+ </property>
<property name="text">
<string>About</string>
</property>
@@ -218,8 +307,8 @@
</action>
<action name="actionZoom_In">
<property name="icon">
- <iconset resource="resources.qrc">
- <normaloff>:/icons/images/zoom-in-24.png</normaloff>:/icons/images/zoom-in-24.png</iconset>
+ <iconset theme="zoom-in" resource="resources.qrc">
+ <normaloff>:/icons/images/zoom-in.svgz</normaloff>:/icons/images/zoom-in.svgz</iconset>
</property>
<property name="text">
<string>Zoom In</string>
@@ -230,8 +319,8 @@
</action>
<action name="actionZoom_Out">
<property name="icon">
- <iconset resource="resources.qrc">
- <normaloff>:/icons/images/zoom-out-24.png</normaloff>:/icons/images/zoom-out-24.png</iconset>
+ <iconset theme="zoom-out" resource="resources.qrc">
+ <normaloff>:/icons/images/zoom-out.svgz</normaloff>:/icons/images/zoom-out.svgz</iconset>
</property>
<property name="text">
<string>Zoom Out</string>
@@ -241,6 +330,10 @@
</property>
</action>
<action name="actionPrevious_Page">
+ <property name="icon">
+ <iconset theme="go-previous-view-page" resource="resources.qrc">
+ <normaloff>:/icons/images/go-previous-view-page.svgz</normaloff>:/icons/images/go-previous-view-page.svgz</iconset>
+ </property>
<property name="text">
<string>Previous Page</string>
</property>
@@ -249,6 +342,10 @@
</property>
</action>
<action name="actionNext_Page">
+ <property name="icon">
+ <iconset theme="go-next-view-page" resource="resources.qrc">
+ <normaloff>:/icons/images/go-next-view-page.svgz</normaloff>:/icons/images/go-next-view-page.svgz</iconset>
+ </property>
<property name="text">
<string>Next Page</string>
</property>
@@ -264,6 +361,66 @@
<string>Continuous</string>
</property>
</action>
+ <action name="actionBack">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/icons/images/go-previous-view.svgz</normaloff>:/icons/images/go-previous-view.svgz</iconset>
+ </property>
+ <property name="text">
+ <string>Back</string>
+ </property>
+ <property name="toolTip">
+ <string>back to previous view</string>
+ </property>
+ </action>
+ <action name="actionForward">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/icons/images/go-next-view.svgz</normaloff>:/icons/images/go-next-view.svgz</iconset>
+ </property>
+ <property name="text">
+ <string>Forward</string>
+ </property>
+ <property name="toolTip">
+ <string>forward to next view</string>
+ </property>
+ </action>
+ <action name="actionFindNext">
+ <property name="icon">
+ <iconset theme="go-down" resource=".rcc/resources.qrc">
+ <normaloff>:/icons/images/go-down-search.svgz</normaloff>:/icons/images/go-down-search.svgz</iconset>
+ </property>
+ <property name="text">
+ <string>Find Next</string>
+ </property>
+ <property name="toolTip">
+ <string>Find the next occurrence of the phrase</string>
+ </property>
+ <property name="shortcut">
+ <string>F3</string>
+ </property>
+ </action>
+ <action name="actionFindPrevious">
+ <property name="icon">
+ <iconset theme="go-up" resource=".rcc/resources.qrc">
+ <normaloff>:/icons/images/go-up-search.svgz</normaloff>:/icons/images/go-up-search.svgz</iconset>
+ </property>
+ <property name="text">
+ <string>Find Previous</string>
+ </property>
+ <property name="toolTip">
+ <string>Find the previous occurrence of the phrase</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+F3</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
diff --git a/examples/pdfwidgets/pdfviewer/pageselector.cpp b/examples/pdfwidgets/pdfviewer/pageselector.cpp
deleted file mode 100644
index cd3c4ba0e..000000000
--- a/examples/pdfwidgets/pdfviewer/pageselector.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "pageselector.h"
-
-#include <QHBoxLayout>
-#include <QLabel>
-#include <QLineEdit>
-#include <QPdfPageNavigation>
-#include <QToolButton>
-
-PageSelector::PageSelector(QWidget *parent)
- : QWidget(parent)
- , m_pageNavigation(nullptr)
-{
- QHBoxLayout *layout = new QHBoxLayout(this);
-
- m_previousPageButton = new QToolButton(this);
- m_previousPageButton->setText("<");
- m_previousPageButton->setEnabled(false);
-
- m_pageNumberEdit = new QLineEdit(this);
- m_pageNumberEdit->setAlignment(Qt::AlignRight);
-
- m_pageCountLabel = new QLabel(this);
- m_pageCountLabel->setText("0");
-
- m_nextPageButton = new QToolButton(this);
- m_nextPageButton->setText(">");
- m_nextPageButton->setEnabled(false);
-
- layout->addWidget(m_previousPageButton);
- layout->addWidget(m_pageNumberEdit);
- layout->addWidget(m_pageCountLabel);
- layout->addWidget(m_nextPageButton);
-}
-
-void PageSelector::setPageNavigation(QPdfPageNavigation *pageNavigation)
-{
- m_pageNavigation = pageNavigation;
-
- connect(m_previousPageButton, &QToolButton::clicked, m_pageNavigation, &QPdfPageNavigation::goToPreviousPage);
- connect(m_pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged, m_previousPageButton, &QToolButton::setEnabled);
-
- connect(m_pageNavigation, &QPdfPageNavigation::currentPageChanged, this, &PageSelector::onCurrentPageChanged);
- connect(m_pageNavigation, &QPdfPageNavigation::pageCountChanged, this, [this](int pageCount){ m_pageCountLabel->setText(QString::fromLatin1("/ %1").arg(pageCount)); });
-
- connect(m_pageNumberEdit, &QLineEdit::editingFinished, this, &PageSelector::pageNumberEdited);
-
- connect(m_nextPageButton, &QToolButton::clicked, m_pageNavigation, &QPdfPageNavigation::goToNextPage);
- connect(m_pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged, m_nextPageButton, &QToolButton::setEnabled);
-
- onCurrentPageChanged(m_pageNavigation->currentPage());
-}
-
-void PageSelector::onCurrentPageChanged(int page)
-{
- if (m_pageNavigation->pageCount() == 0)
- m_pageNumberEdit->setText(QString::number(0));
- else
- m_pageNumberEdit->setText(QString::number(page + 1));
-}
-
-void PageSelector::pageNumberEdited()
-{
- if (!m_pageNavigation)
- return;
-
- const QString text = m_pageNumberEdit->text();
-
- bool ok = false;
- const int pageNumber = text.toInt(&ok);
-
- if (!ok)
- onCurrentPageChanged(m_pageNavigation->currentPage());
- else
- m_pageNavigation->setCurrentPage(qBound(0, pageNumber - 1, m_pageNavigation->pageCount() - 1));
-}
diff --git a/examples/pdfwidgets/pdfviewer/pageselector.h b/examples/pdfwidgets/pdfviewer/pageselector.h
deleted file mode 100644
index 7a7283f99..000000000
--- a/examples/pdfwidgets/pdfviewer/pageselector.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 PAGESELECTOR_H
-#define PAGESELECTOR_H
-
-#include <QWidget>
-
-QT_BEGIN_NAMESPACE
-class QLabel;
-class QLineEdit;
-class QPdfDocument;
-class QPdfPageNavigation;
-class QToolButton;
-QT_END_NAMESPACE
-
-class PageSelector : public QWidget
-{
- Q_OBJECT
-
-public:
- explicit PageSelector(QWidget *parent = nullptr);
-
- void setPageNavigation(QPdfPageNavigation *pageNavigation);
-
-private slots:
- void onCurrentPageChanged(int page);
- void pageNumberEdited();
-
-private:
- QPdfPageNavigation *m_pageNavigation;
-
- QLineEdit *m_pageNumberEdit;
- QLabel *m_pageCountLabel;
- QToolButton *m_previousPageButton;
- QToolButton *m_nextPageButton;
-};
-
-#endif // PAGESELECTOR_H
diff --git a/examples/pdfwidgets/pdfviewer/pdfviewer.pro b/examples/pdfwidgets/pdfviewer/pdfviewer.pro
index ad0607ea5..5e48edeb9 100644
--- a/examples/pdfwidgets/pdfviewer/pdfviewer.pro
+++ b/examples/pdfwidgets/pdfviewer/pdfviewer.pro
@@ -5,12 +5,12 @@ QT += core gui widgets pdfwidgets
SOURCES += \
main.cpp \
mainwindow.cpp \
- pageselector.cpp \
+ searchresultdelegate.cpp \
zoomselector.cpp
HEADERS += \
mainwindow.h \
- pageselector.h \
+ searchresultdelegate.h \
zoomselector.h
FORMS += \
diff --git a/examples/pdfwidgets/pdfviewer/resources.qrc b/examples/pdfwidgets/pdfviewer/resources.qrc
index 02d9655b4..ea408b825 100644
--- a/examples/pdfwidgets/pdfviewer/resources.qrc
+++ b/examples/pdfwidgets/pdfviewer/resources.qrc
@@ -1,12 +1,13 @@
<RCC>
<qresource prefix="/icons">
- <file>images/fileopen.png</file>
- <file>images/go-next-24.png</file>
- <file>images/go-previous-24.png</file>
- <file>images/zoom-in-24.png</file>
- <file>images/zoom-in-32.png</file>
- <file>images/zoom-out-24.png</file>
- <file>images/zoom-out-32.png</file>
- <file>images/busy.png</file>
+ <file>images/document-open.svgz</file>
+ <file>images/go-down-search.svgz</file>
+ <file>images/go-next-view.svgz</file>
+ <file>images/go-previous-view.svgz</file>
+ <file>images/go-next-view-page.svgz</file>
+ <file>images/go-previous-view-page.svgz</file>
+ <file>images/go-up-search.svgz</file>
+ <file>images/zoom-in.svgz</file>
+ <file>images/zoom-out.svgz</file>
</qresource>
</RCC>
diff --git a/examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp b/examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp
new file mode 100644
index 000000000..87efd916d
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/searchresultdelegate.cpp
@@ -0,0 +1,46 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QFontMetrics>
+#include <QPainter>
+#include <QPdfSearchModel>
+
+#include "searchresultdelegate.h"
+
+SearchResultDelegate::SearchResultDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+void SearchResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ const QString displayText = index.data().toString();
+ const auto boldBegin = displayText.indexOf(u"<b>", 0, Qt::CaseInsensitive) + 3;
+ const auto boldEnd = displayText.indexOf(u"</b>", boldBegin, Qt::CaseInsensitive);
+ if (boldBegin >= 3 && boldEnd > boldBegin) {
+ const QString pageLabel = tr("Page %1: ").arg(index.data(int(QPdfSearchModel::Role::Page)).toInt());
+ const QString boldText = displayText.mid(boldBegin, boldEnd - boldBegin);
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(option.rect, option.palette.highlight());
+ const QFont defaultFont = painter->font();
+ QFontMetrics fm = painter->fontMetrics();
+ auto pageLabelWidth = fm.horizontalAdvance(pageLabel);
+ const int yOffset = (option.rect.height() - fm.height()) / 2 + fm.ascent();
+ painter->drawText(0, option.rect.y() + yOffset, pageLabel);
+ QFont boldFont = defaultFont;
+ boldFont.setBold(true);
+ auto boldWidth = QFontMetrics(boldFont).horizontalAdvance(boldText);
+ auto prefixSuffixWidth = (option.rect.width() - pageLabelWidth - boldWidth) / 2;
+ painter->setFont(boldFont);
+ painter->drawText(pageLabelWidth + prefixSuffixWidth, option.rect.y() + yOffset, boldText);
+ painter->setFont(defaultFont);
+ const QString suffix = fm.elidedText(displayText.mid(boldEnd + 4), Qt::ElideRight, prefixSuffixWidth);
+ painter->drawText(pageLabelWidth + prefixSuffixWidth + boldWidth, option.rect.y() + yOffset, suffix);
+ const QString prefix = fm.elidedText(displayText.left(boldBegin - 3), Qt::ElideLeft, prefixSuffixWidth);
+ painter->drawText(pageLabelWidth + prefixSuffixWidth - fm.horizontalAdvance(prefix),
+ option.rect.y() + yOffset, prefix);
+ } else {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
+}
diff --git a/examples/pdfwidgets/pdfviewer/searchresultdelegate.h b/examples/pdfwidgets/pdfviewer/searchresultdelegate.h
new file mode 100644
index 000000000..dcf886111
--- /dev/null
+++ b/examples/pdfwidgets/pdfviewer/searchresultdelegate.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef SEARCHRESULTDELEGATE_H
+#define SEARCHRESULTDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+//! [0]
+class SearchResultDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ SearchResultDelegate(QObject *parent = nullptr);
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+};
+
+#endif // SEARCHRESULTDELEGATE_H
diff --git a/examples/pdfwidgets/pdfviewer/zoomselector.cpp b/examples/pdfwidgets/pdfviewer/zoomselector.cpp
index a4d596ab7..0b314129a 100644
--- a/examples/pdfwidgets/pdfviewer/zoomselector.cpp
+++ b/examples/pdfwidgets/pdfviewer/zoomselector.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "zoomselector.h"
@@ -77,9 +44,9 @@ void ZoomSelector::reset()
void ZoomSelector::onCurrentTextChanged(const QString &text)
{
if (text == QLatin1String("Fit Width")) {
- emit zoomModeChanged(QPdfView::FitToWidth);
+ emit zoomModeChanged(QPdfView::ZoomMode::FitToWidth);
} else if (text == QLatin1String("Fit Page")) {
- emit zoomModeChanged(QPdfView::FitInView);
+ emit zoomModeChanged(QPdfView::ZoomMode::FitInView);
} else {
qreal factor = 1.0;
@@ -91,7 +58,7 @@ void ZoomSelector::onCurrentTextChanged(const QString &text)
if (ok)
factor = zoomLevel / 100.0;
- emit zoomModeChanged(QPdfView::CustomZoom);
+ emit zoomModeChanged(QPdfView::ZoomMode::Custom);
emit zoomFactorChanged(factor);
}
}
diff --git a/examples/pdfwidgets/pdfviewer/zoomselector.h b/examples/pdfwidgets/pdfviewer/zoomselector.h
index c58d09970..7c35bdab7 100644
--- a/examples/pdfwidgets/pdfviewer/zoomselector.h
+++ b/examples/pdfwidgets/pdfviewer/zoomselector.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klaralvdalens Datakonsult AB (KDAB).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef ZOOMSELECTOR_H
#define ZOOMSELECTOR_H
diff --git a/examples/webenginequick/CMakeLists.txt b/examples/webenginequick/CMakeLists.txt
index b08d03980..ec29a1e58 100644
--- a/examples/webenginequick/CMakeLists.txt
+++ b/examples/webenginequick/CMakeLists.txt
@@ -1,8 +1,5 @@
-add_subdirectory(customdialogs)
-add_subdirectory(lifecycle)
-add_subdirectory(minimal)
-add_subdirectory(quicknanobrowser)
-add_subdirectory(webengineaction)
-if(TARGET Qt::QuickControls2)
- add_subdirectory(recipebrowser)
-endif()
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+qt_internal_add_example(lifecycle)
+qt_internal_add_example(quicknanobrowser)
diff --git a/examples/webenginequick/customdialogs/MessageRectangle.qml b/examples/webenginequick/customdialogs/MessageRectangle.qml
deleted file mode 100644
index 880cf27d5..000000000
--- a/examples/webenginequick/customdialogs/MessageRectangle.qml
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-Rectangle {
- property alias text: messageText.text
- width: parent.width
- height: 30
- visible: false
- color: "#80c342"
- Text {
- id: messageText
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
- font.pointSize: 12
- }
-}
diff --git a/examples/webenginequick/customdialogs/SwitchButton.qml b/examples/webenginequick/customdialogs/SwitchButton.qml
deleted file mode 100644
index 55005899a..000000000
--- a/examples/webenginequick/customdialogs/SwitchButton.qml
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Controls
-import QtQuick.Layouts
-
-Item {
- width: parent.width
- height: 40
- property alias checked: switcher.checked
- RowLayout {
- anchors.centerIn: parent
- Text {
- text: qsTr("Use default dialogs")
- font.pointSize: 12
- }
- Switch {
- id: switcher
- checked: true
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.png
deleted file mode 100644
index 042712f5c..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.png
deleted file mode 100644
index 41828d36d..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-auth2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-color1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-color1.png
deleted file mode 100644
index 7f0492f87..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-color1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-color2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-color2.png
deleted file mode 100644
index 9087fdf14..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-color2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-file1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-file1.png
deleted file mode 100644
index 5023ced6f..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-file1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-file2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-file2.png
deleted file mode 100644
index aa25579d7..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-file2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-menu.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-menu.png
deleted file mode 100644
index 3409c951c..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-menu.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.png
deleted file mode 100644
index c34080b4d..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt1.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.png
deleted file mode 100644
index 2c8d92649..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-prompt2.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.png b/examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.png
deleted file mode 100644
index 498de9595..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs-tooltip.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/images/customdialogs.png b/examples/webenginequick/customdialogs/doc/images/customdialogs.png
deleted file mode 100644
index c42114a16..000000000
--- a/examples/webenginequick/customdialogs/doc/images/customdialogs.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc b/examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc
deleted file mode 100644
index 2d7b9f199..000000000
--- a/examples/webenginequick/customdialogs/doc/src/customdialogs.qdoc
+++ /dev/null
@@ -1,333 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginequick/customdialogs
- \title WebEngine Qt Quick Custom Dialogs Example
- \ingroup webengine-examples
- \brief Customizes UI elements of \QWE's dialogs.
-
- \image customdialogs.png
-
- A web page might request dialogs for various purposes, such as
- authentication, picking colors, choosing files, and responding to JavaScript
- alerts, confirmation requests, and prompts.
-
- \e {Custom Dialogs} demonstrates how to use WebEngine dialog request objects
- to implement custom dialogs for use instead of the default dialogs.
-
- \include examples-run.qdocinc
-
- \section1 UI Elements of WebEngineView
-
- In this example, we create a simple \c index.html page that contains buttons
- and text fields for triggering a context menu and the following dialogs:
-
- \list
- \li HTTP Authentication Dialog
- \li Proxy Authentication Dialog
- \li JavaScript Alert, Confirm, and Prompt Dialogs
- \li Color Picker Dialog
- \li File Picker Dialog
- \endlist
-
- \section1 Triggering Dialogs
-
- As mentioned, the \c index.html file is responsible for triggering the
- dialogs from the side of HTML and JavaScript. Additionally, the example
- program starts a localhost TCP server returning the mocked HTTP responses
- needed to trigger proxy and HTTP authentication dialogs.
-
- \section1 Custom Dialogs
-
- The custom dialogs are just \e {Qt Quick Designer UI Forms} without any
- business logic. The point here is to present the glue code that is required
- to display the custom dialog for a particular web engine dialog or a menu
- request.
-
- \section1 Creating the Main Window
-
- In \c main.cpp, we initialize the WebEngine the same way as in the
- \l {WebEngine Qt Quick Minimal Example}:
-
- \quotefromfile webenginequick/customdialogs/main.cpp
- \skipto main
- \printuntil }
-
- In addition, we set up a proxy and a TCP server to be able to simulate proxy
- and HTTP authetication requests.
-
- In \c main.qml, we create a top level window, which contains a StackView
- with a SwitchButton and a WebView:
-
- \quotefromfile webenginequick/customdialogs/main.qml
- \skipto Window
- \printuntil Component
- \printuntil }
- \printline }
-
- \section1 Handling Web Engine Requests
-
- In this example, we implement the handling of the following web engine
- requests:
-
- \list
- \li ContextMenuRequest
- \li AuthenticationDialogRequest
- \li JavaScriptDialogRequest
- \li ColorDialogRequest
- \li FileDialogRequest
- \endlist
-
- \section2 Context Menu Requests
-
- \l [QML]{ContextMenuRequest} is a request object that is passed as a
- parameter of the WebEngineView::contextMenuRequested signal. We use the
- \c onContextMenuRequested signal handler to handle requests for
- \c #openMenu URL links:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onContextMenuRequested
- \printuntil }
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- The first text field from the top on our page triggers the request. Next,
- we check whether we should use the default menu. If not, we accept the
- request and switch the view to show the \c MenuForm:
-
- \image customdialogs-menu.png
-
- \quotefromfile webenginequick/customdialogs/forms/Menu.qml
- \skipto MenuForm
- \printuntil }
- \printuntil }
-
- To keep things simple, we do not provide any logic on component completion,
- and we simply close the form on any action.
-
- \section2 Tooltip Requests
-
- \l [QML]{TooltipRequest} is a request object that is passed as a
- parameter of the WebEngineView::tooltipRequested signal. We use the
- \c onTooltipRequested signal handler to handle requests for
- custom tooltip menus at specific positions:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onTooltipRequested
- \printuntil }
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- The second text field from the top on our page triggers the request. Next,
- we check whether we should use the default menu. If not, we accept the
- request and show a custom QML element as tooltip:
-
- \image customdialogs-tooltip.png
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto Rectangle
- \printuntil }
-
- \section2 Authentication Dialog Requests
-
- \image customdialogs-auth1.png
-
- \l [QML]{AuthenticationDialogRequest} is a request object that is passed
- as a parameter of the WebEngineView::authenticationDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onAuthenticationDialogRequested
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- We use the \c onAuthenticationDialogRequested signal handler to check
- whether we should use the default authentication dialog. If not, we accept
- the request and switch the view to show the \c AuthenticationForm:
-
- \image customdialogs-auth2.png
-
- \quotefromfile webenginequick/customdialogs/forms/Authentication.qml
- \skipto AuthenticationForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we log the request type. The user can fill in the
- credentials and click \uicontrol Login. We provide \c onClicked handlers to
- accept or reject the authentication dialog. The TCP server on localhost does
- not handle real authentication, and therefore we call \c rejectDialog()
- instead of \c acceptDialog() also for the login button \c clicked signal.
-
- \section2 JavaScript Dialog Requests
-
- \image customdialogs-prompt1.png
-
- \l [QML]{JavaScriptDialogRequest} is a request object that is passed as a
- parameter of the WebEngineView::javaScriptDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onJavaScriptDialogRequested
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- We use the \c onJavaScriptDialogRequested signal handler to check
- whether we should use the default JavaScript dialog. If not, we accept the
- request and switch the view to show the \c JavaScriptForm:
-
- \image customdialogs-prompt2.png
-
- \quotefromfile webenginequick/customdialogs/forms/JavaScript.qml
- \skipto JavaScriptForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we customize the form based on the request type.
- For a JavaScript prompt dialog we use \c dialogAccept() with the
- \c prompt.text argument.
-
- \section2 Color Dialog Requests
-
- \image customdialogs-color1.png
-
- \l [QML]{ColorDialogRequest} is a request object that is passed as a
- parameter of the WebEngineView::colorDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onColorDialogRequested
- \printuntil }
- \printuntil }
- \dots 4
- \skipuntil onFileDialogRequested
- \skipuntil }});
- \skipuntil }
- \skipto }
- \printline }
-
- We use the \c onColorDialogRequested signal handler to check whether
- we should use the default color picker dialog. If not, we accept the request
- and switch the view to show the \c ColorPickerForm:
-
- \image customdialogs-color2.png
-
- \quotefromfile webenginequick/customdialogs/forms/ColorPicker.qml
- \skipto ColorPickerForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we create callbacks for all the color cells. When
- the user selects the color and clicks \c OK, we pass the selected color to
- the \c dialogAccept() method.
-
- \section2 File Dialog Requests
-
- \image customdialogs-file1.png
-
- \l [QML]{FileDialogRequest} is a request object that is passed as a
- parameter of the WebEngineView::fileDialogRequested signal:
-
- \quotefromfile webenginequick/customdialogs/WebView.qml
- \skipto WebEngineView
- \printuntil {
- \dots 4
- \skipto onFileDialogRequested
- \printuntil }
- \printuntil }
- \printuntil }
-
- We use the \c onFileDialogRequested signal handler to check whether
- we should use the default file picker dialog. If not, we accept the request
- and switch the view to show the \c FilePickerForm:
-
- \image customdialogs-file2.png
-
- \quotefromfile webenginequick/customdialogs/forms/FilePicker.qml
- \skipto FilePickerForm
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
- \printuntil }
-
- On component completion, we create callbacks for selecting files. When the user selects a
- file and clicks \c OK, we pass the selected file to the \c dialogAccept
- method.
-
-*/
diff --git a/examples/webenginequick/customdialogs/forms/Authentication.qml b/examples/webenginequick/customdialogs/forms/Authentication.qml
deleted file mode 100644
index 6365db9c3..000000000
--- a/examples/webenginequick/customdialogs/forms/Authentication.qml
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtWebEngine
-
-AuthenticationForm {
- property QtObject request
- signal closeForm()
-
- cancelButton.onClicked: {
- request.dialogReject();
- closeForm();
- }
-
- loginButton.onClicked: {
- request.dialogReject();
- closeForm();
- }
-
- Component.onCompleted: {
- switch (request.type) {
- case AuthenticationDialogRequest.AuthenticationTypeHTTP:
- console.log("HTTP Authentication Required. Host says: " + request.realm);
- break;
- case AuthenticationDialogRequest.AuthenticationTypeProxy:
- console.log("Proxy Authentication Required for: " + request.proxyHost);
- break;
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/ColorCell.qml b/examples/webenginequick/customdialogs/forms/ColorCell.qml
deleted file mode 100644
index 495a2900c..000000000
--- a/examples/webenginequick/customdialogs/forms/ColorCell.qml
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-Rectangle {
- id: rectangle
- width: 50
- height: 50
- signal clicked()
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- onClicked: rectangle.clicked()
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/ColorPicker.qml b/examples/webenginequick/customdialogs/forms/ColorPicker.qml
deleted file mode 100644
index 7c1545c43..000000000
--- a/examples/webenginequick/customdialogs/forms/ColorPicker.qml
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-ColorPickerForm {
- property QtObject request
- signal closeForm()
-
- okButton.onClicked: {
- request.dialogAccept(colorPicker.color);
- closeForm();
- }
-
- cancelButton.onClicked: {
- request.dialogReject();
- closeForm();
- }
-
- function createCallback(color) {
- return function() { colorPicker.color = color };
- }
-
- Component.onCompleted:{
- for (var i = 0; i < grid.children.length; i++) {
- var cell = grid.children[i];
- cell.clicked.connect(createCallback(cell.color));
- }
- colorPicker.color = request.color;
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/CustomButton.qml b/examples/webenginequick/customdialogs/forms/CustomButton.qml
deleted file mode 100644
index 3ab90a752..000000000
--- a/examples/webenginequick/customdialogs/forms/CustomButton.qml
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-Rectangle {
- id: root
- width: 200
- height: 30
- radius: 5
- property string btnText: "Name"
- property bool btnEnable: true
- property bool btnBlue: true
- opacity: btnEnable ? 1.0 : 0.5
- signal clicked()
- gradient: btnBlue ? blueButton : greenButton
- Text {
- id: textArea
- x: 54
- y: 5
- color: "#ffffff"
- text: parent.btnText
- font.pointSize: 12
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
- font.bold: false
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- onClicked: {
- if (btnEnable)
- root.clicked();
- }
- }
-
- Gradient {
- id: blueButton
- GradientStop {
- position: 0
- color: "#25a6e2"
- }
- GradientStop {
- position: mouseArea.pressed && root.btnEnable ? 0.7 :1
- color: "#188bd0"
- }
- }
-
- Gradient {
- id: greenButton
- GradientStop {
- position: 0
- color: "#80c342"
- }
- GradientStop {
- position: mouseArea.pressed && root.btnEnable ? 0.7 :1
- color: "#5fac18"
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/FilePicker.qml b/examples/webenginequick/customdialogs/forms/FilePicker.qml
deleted file mode 100644
index 97acda326..000000000
--- a/examples/webenginequick/customdialogs/forms/FilePicker.qml
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-FilePickerForm {
- property QtObject request
- property string selectedFile
- signal closeForm()
-
- cancelButton.onClicked: {
- request.dialogReject();
- closeForm();
- }
-
- okButton.onClicked: {
- request.dialogAccept('/' + selectedFile);
- closeForm();
- }
-
- function createCallback(fileIndex) {
- return function() {
- for (var i = 0; i < files.children.length; i++) {
- var file = files.children[i];
- if (i === fileIndex) {
- selectedFile = file.text;
- file.selected = true;
- } else {
- file.selected = false;
- }
- }
- }
- }
-
- Component.onCompleted: {
- selectedFile = request.defaultFileName;
- for (var i = 0; i < files.children.length; i++) {
- var file = files.children[i];
- file.clicked.connect(createCallback(i));
- if (file.text === selectedFile)
- file.selected = true;
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/FileRow.qml b/examples/webenginequick/customdialogs/forms/FileRow.qml
deleted file mode 100644
index 0356dceae..000000000
--- a/examples/webenginequick/customdialogs/forms/FileRow.qml
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Layouts
-
-Item {
- id: root
- height: 30
- property string text: "Filename"
- property bool selected: false
- signal clicked()
-
- RowLayout {
- id: fileRow
- width: 100
-
- Item {
- id: item5
- width: 10
- height: 10
- }
-
- Rectangle {
- id: rectangle2
- width: 10
- height: 10
- color: selected ? "#80c342" : "#25a6e2"
- }
-
- Text {
- id: filename
- text: root.text
- font.pointSize: 12
- }
- }
-
- MouseArea {
- id: mouseArea
- width: 200
- height: 30
- onClicked: root.clicked()
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/JavaScript.qml b/examples/webenginequick/customdialogs/forms/JavaScript.qml
deleted file mode 100644
index 61e009e54..000000000
--- a/examples/webenginequick/customdialogs/forms/JavaScript.qml
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtWebEngine
-
-JavaScriptForm {
- property QtObject request
- signal closeForm()
-
- cancelButton.onClicked: {
- request.dialogReject();
- closeForm();
- }
-
- okButton.onClicked: {
- request.dialogAccept(prompt.text);
- closeForm();
- }
-
- Component.onCompleted: {
- switch (request.type) {
- case JavaScriptDialogRequest.DialogTypeAlert:
- cancelButton.visible = false;
- title = qsTr("Alert");
- message = request.message;
- prompt.text = "";
- prompt.visible = false;
- break;
- case JavaScriptDialogRequest.DialogTypeConfirm:
- title = qsTr("Confirm");
- message = request.message;
- prompt.text = "";
- prompt.visible = false;
- break;
- case JavaScriptDialogRequest.DialogTypePrompt:
- title = qsTr("Prompt");
- message = request.message;
- prompt.text = request.defaultText;
- prompt.visible = true;
- break;
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml b/examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml
deleted file mode 100644
index 1d486eaac..000000000
--- a/examples/webenginequick/customdialogs/forms/JavaScriptForm.ui.qml
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Layouts
-import QtQuick.Controls
-
-Item {
- id: root
- property alias cancelButton: cancelButton
- property alias okButton: okButton
- property string message: "Message"
- property string title: "Title"
- property alias prompt: prompt
-
- ColumnLayout {
- id: columnLayout
- anchors.topMargin: 20
- anchors.top: parent.top
- anchors.bottomMargin: 20
- anchors.bottom: parent.bottom
- anchors.rightMargin: 20
- anchors.right: parent.right
- anchors.leftMargin: 20
- anchors.left: parent.left
-
- Image {
- id: image
- Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
- source: "qrc:/icon.svg"
- }
-
- Rectangle {
- id: rectangle
- height: 30
- Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
- gradient: Gradient {
- GradientStop {
- position: 0
- color: "#25a6e2"
- }
-
- GradientStop {
- color: "#188bd0"
- }
- }
-
- Text {
- id: title
- x: 54
- y: 5
- color: "#ffffff"
- text: qsTr("Title")
- font.pointSize: 12
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Item {
- width: 40
- height: 40
- }
-
- Text {
- id: message
- text: item.message
- font.pointSize: 12
- }
-
- TextField {
- id: prompt
- width: 300
- height: 22
- Layout.fillWidth: true
- font.pointSize: 12
- }
-
- Item {
- Layout.fillHeight: true
- }
-
- RowLayout {
- id: rowLayout
- width: 100
- height: 100
-
- Item {
- Layout.fillWidth: true
- }
-
- CustomButton {
- id: cancelButton
- width: 90
- height: 30
- btnText: qsTr("Cancel")
- btnBlue: false
- }
-
- CustomButton {
- id: okButton
- width: 90
- height: 30
- btnText: qsTr("OK")
- btnBlue: false
- }
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/Menu.qml b/examples/webenginequick/customdialogs/forms/Menu.qml
deleted file mode 100644
index 4f7f9f9e6..000000000
--- a/examples/webenginequick/customdialogs/forms/Menu.qml
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-MenuForm {
- property QtObject request
- signal closeForm()
-
- followLink.onClicked: closeForm()
- back.onClicked: closeForm()
- forward.onClicked: closeForm()
- reload.onClicked: closeForm()
- copyLinkUrl.onClicked: closeForm()
- saveLink.onClicked: closeForm()
- close.onClicked: closeForm()
-
- Component.onCompleted: {
- back.btnEnable = false;
- forward.btnEnable = false;
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/MenuForm.ui.qml b/examples/webenginequick/customdialogs/forms/MenuForm.ui.qml
deleted file mode 100644
index cba7a1b3f..000000000
--- a/examples/webenginequick/customdialogs/forms/MenuForm.ui.qml
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Layouts
-
-Item {
- property alias followLink: followLink
- property alias back: back
- property alias forward: forward
- property alias reload: reload
- property alias copyLinkUrl: copyLinkUrl
- property alias saveLink: saveLink
- property alias close: close
-
- ColumnLayout {
- id: columnLayout
- anchors.verticalCenter: parent.verticalCenter
- anchors.horizontalCenter: parent.horizontalCenter
-
- Image {
- id: image
- width: 100
- height: 100
- Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
- source: "qrc:/icon.svg"
- }
-
- CustomButton {
- id: followLink
- btnText: qsTr("Follow")
- }
-
- CustomButton {
- id: back
- btnText: qsTr("Back")
- }
-
- CustomButton {
- id: forward
- btnText: qsTr("Forward")
- }
-
- CustomButton {
- id: reload
- btnText: qsTr("Reload")
- }
-
- CustomButton {
- id: copyLinkUrl
- btnText: qsTr("Copy Link URL")
- }
-
- CustomButton {
- id: saveLink
- btnText: qsTr("Save Link")
- }
-
- CustomButton {
- id: close
- btnBlue: false
- btnText: qsTr("Close")
- }
- }
-}
diff --git a/examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml b/examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml
deleted file mode 100644
index 6d3dec564..000000000
--- a/examples/webenginequick/customdialogs/forms/TouchSelectionMenu.qml
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-
-TouchSelectionMenuForm {
- property QtObject request
- signal closeForm()
-
- cut.onClicked: closeForm()
- copy.onClicked: closeForm()
- paste.onClicked: closeForm()
- contextMenu.onClicked: closeForm()
-}
diff --git a/examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml b/examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
deleted file mode 100644
index 30d9a3179..000000000
--- a/examples/webenginequick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Layouts
-
-Item {
- property alias cut: cut
- property alias copy: copy
- property alias paste: paste
- property alias contextMenu: contextMenu
-
- ColumnLayout {
- id: columnLayout
- anchors.verticalCenter: parent.verticalCenter
- anchors.horizontalCenter: parent.horizontalCenter
-
- CustomButton {
- id: cut
- btnText: qsTr("Cut")
- }
-
- CustomButton {
- id: copy
- btnText: qsTr("Copy")
- }
-
- CustomButton {
- id: paste
- btnText: qsTr("Paste")
- }
-
- CustomButton {
- id: contextMenu
- btnText: qsTr("...")
- }
-
- }
-}
diff --git a/examples/webenginequick/customdialogs/main.cpp b/examples/webenginequick/customdialogs/main.cpp
deleted file mode 100644
index 6ed5771f1..000000000
--- a/examples/webenginequick/customdialogs/main.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 "server.h"
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-#include <QNetworkProxy>
-#include <QQmlApplicationEngine>
-#include <QTimer>
-#include <QtGui/QGuiApplication>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QtWebEngineQuick::initialize();
-
- QGuiApplication app(argc, argv);
-
- QQmlApplicationEngine engine;
- Server *server = new Server(&engine);
-
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
- QTimer::singleShot(0, server, &Server::run);
-
- QNetworkProxy proxy;
- proxy.setType(QNetworkProxy::HttpProxy);
- proxy.setHostName("localhost");
- proxy.setPort(5555);
- QNetworkProxy::setApplicationProxy(proxy);
-
- return app.exec();
-}
-
diff --git a/examples/webenginequick/customdialogs/main.qml b/examples/webenginequick/customdialogs/main.qml
deleted file mode 100644
index 6d81c7979..000000000
--- a/examples/webenginequick/customdialogs/main.qml
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Window
-
-Window {
- id: mainWindow
- width: 800
- height: 610
- visible: true
-
- StackView {
- id: stackView
- anchors.fill: parent
- focus: true
- initialItem: Item {
- id: main
- width: mainWindow.width
- height: mainWindow.height
- ColumnLayout {
- anchors.fill: parent
- SwitchButton {
- id: switcher
- Layout.fillWidth: true
- }
- WebView {
- id: webView
- useDefaultDialogs: switcher.checked
- Layout.fillWidth: true
- Layout.fillHeight: true
- }
- }
- }
-
- function closeForm()
- {
- pop(main);
- // reset url in case of proxy error
- webView.url = "qrc:/index.html"
- }
-
- function openForm(form)
- {
- push(form.item, form.properties);
- currentItem.closeForm.connect(closeForm);
- }
-
- }
-
- Component.onCompleted: {
- webView.openForm.connect(stackView.openForm);
- }
-}
diff --git a/examples/webenginequick/customdialogs/server.cpp b/examples/webenginequick/customdialogs/server.cpp
deleted file mode 100644
index 9b05d3a17..000000000
--- a/examples/webenginequick/customdialogs/server.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 "server.h"
-#include <QDataStream>
-#include <QTcpSocket>
-
-Server::Server(QObject *parent) : QObject(parent)
-{
- connect(&m_server, &QTcpServer::newConnection, this, &Server::handleNewConnection);
-}
-
-void Server::run()
-{
- if (!m_server.listen(QHostAddress::LocalHost, 5555))
- qWarning() << "Could not start the server -> http/proxy authentication dialog"
- " will not work. Error:" << m_server.errorString();
-}
-
-void Server::handleNewConnection()
-{
- QTcpSocket *socket = m_server.nextPendingConnection();
- connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
- connect(socket, &QAbstractSocket::readyRead, this, &Server::handleReadReady);
-}
-
-void Server::handleReadReady()
-{
- QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
- Q_ASSERT(socket);
- m_data.append(socket->readAll());
-
- // simply wait for whole request
- if (!m_data.endsWith("\r\n\r\n"))
- return;
- if (m_data.contains(QByteArrayLiteral("OPEN_AUTH"))) {
- socket->write("HTTP/1.1 401 Unauthorized\nWWW-Authenticate: "
- "Basic realm=\"Very Restricted Area\"\r\n\r\n");
- m_data.clear();
- return;
- }
-
- socket->write("HTTP/1.1 407 Proxy Auth Required\nProxy-Authenticate: "
- "Basic realm=\"Proxy requires authentication\"\r\n"
- "content-length: 0\r\n\r\n");
- m_data.clear();
-}
diff --git a/examples/webenginequick/customdialogs/server.h b/examples/webenginequick/customdialogs/server.h
deleted file mode 100644
index 0a495cc4b..000000000
--- a/examples/webenginequick/customdialogs/server.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 SERVER_H
-#define SERVER_H
-
-#include <QObject>
-#include <QTcpServer>
-
-class Server : public QObject
-{
- Q_OBJECT
-
-public:
- explicit Server(QObject *parent = nullptr);
-
-public slots:
- void run();
-
-private slots:
- void handleNewConnection();
- void handleReadReady();
-
-private:
- QTcpServer m_server;
- QByteArray m_data;
-};
-
-#endif // SERVER_H
diff --git a/examples/webenginequick/lifecycle/CMakeLists.txt b/examples/webenginequick/lifecycle/CMakeLists.txt
index 8f90cbf48..46478b622 100644
--- a/examples/webenginequick/lifecycle/CMakeLists.txt
+++ b/examples/webenginequick/lifecycle/CMakeLists.txt
@@ -1,37 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(lifecycle LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/lifecycle")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS QuickControls2)
-find_package(Qt6 COMPONENTS WebEngineQuick)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui QuickControls2 WebEngineQuick)
qt_add_executable(lifecycle
main.cpp
+ utils.h
)
+
set_target_properties(lifecycle PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(lifecycle PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineQuick
)
-
# Resources:
set(resources_resource_files
"WebBrowser.qml"
diff --git a/examples/webenginequick/lifecycle/WebBrowser.qml b/examples/webenginequick/lifecycle/WebBrowser.qml
index e29ac4f90..43edcc537 100644
--- a/examples/webenginequick/lifecycle/WebBrowser.qml
+++ b/examples/webenginequick/lifecycle/WebBrowser.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
diff --git a/examples/webenginequick/lifecycle/WebTab.qml b/examples/webenginequick/lifecycle/WebTab.qml
index f83ce9404..6fb6cb386 100644
--- a/examples/webenginequick/lifecycle/WebTab.qml
+++ b/examples/webenginequick/lifecycle/WebTab.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQml
import QtQuick
@@ -179,7 +132,7 @@ ColumnLayout {
text: view.url == "about:blank" ? "" : view.url
selectByMouse: true
- onAccepted: { view.url = text }
+ onAccepted: { view.url = utils.fromUserInput(text) }
}
WebToolButton {
text: "â‹®"
diff --git a/examples/webenginequick/lifecycle/WebTabBar.qml b/examples/webenginequick/lifecycle/WebTabBar.qml
index b883cfc36..e87380eb1 100644
--- a/examples/webenginequick/lifecycle/WebTabBar.qml
+++ b/examples/webenginequick/lifecycle/WebTabBar.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
diff --git a/examples/webenginequick/lifecycle/WebTabButton.qml b/examples/webenginequick/lifecycle/WebTabButton.qml
index 50bc463da..c26a53f54 100644
--- a/examples/webenginequick/lifecycle/WebTabButton.qml
+++ b/examples/webenginequick/lifecycle/WebTabButton.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
diff --git a/examples/webenginequick/lifecycle/WebTabStack.qml b/examples/webenginequick/lifecycle/WebTabStack.qml
index 6ceedb8a5..1bc16f4c9 100644
--- a/examples/webenginequick/lifecycle/WebTabStack.qml
+++ b/examples/webenginequick/lifecycle/WebTabStack.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQml.Models
import QtQuick
diff --git a/examples/webenginequick/lifecycle/WebToolButton.qml b/examples/webenginequick/lifecycle/WebToolButton.qml
index 9565dfb1d..bdf94b4ba 100644
--- a/examples/webenginequick/lifecycle/WebToolButton.qml
+++ b/examples/webenginequick/lifecycle/WebToolButton.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
diff --git a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc
index 80faf8b1e..1580da26d 100644
--- a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc
+++ b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc
@@ -1,35 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginequick/lifecycle
\title WebEngine Lifecycle Example
\ingroup webengine-examples
\brief Freezes and discards background tabs to reduce CPU and memory usage.
+ \examplecategory {Web Technologies}
\image lifecycle.png
@@ -55,6 +32,9 @@
window also has a \l {Drawer} for changing settings. The drawer can be
opened by clicking the "â‹®" button on the tool bar.
+ \note Note that \c {WebTab.qml} uses \l {QUrl::}
+ {fromUserInput} to handle incomplete URLs.
+
\section1 Lifecycle States in the Example
The example implements two ways of changing the lifecycle state: manual and
diff --git a/examples/webenginequick/lifecycle/lifecycle.pro b/examples/webenginequick/lifecycle/lifecycle.pro
index ccbe801f3..044d025d7 100644
--- a/examples/webenginequick/lifecycle/lifecycle.pro
+++ b/examples/webenginequick/lifecycle/lifecycle.pro
@@ -2,6 +2,7 @@ TEMPLATE = app
QT += quickcontrols2 webenginequick
+HEADERS += utils.h
SOURCES += main.cpp
RESOURCES += resources.qrc
diff --git a/examples/webenginequick/lifecycle/main.cpp b/examples/webenginequick/lifecycle/main.cpp
index 1e2a48679..1f45ad0ee 100644
--- a/examples/webenginequick/lifecycle/main.cpp
+++ b/examples/webenginequick/lifecycle/main.cpp
@@ -1,52 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "utils.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
@@ -59,6 +14,8 @@ int main(int argc, char *argv[])
QtWebEngineQuick::initialize();
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
+ Utils utils;
+ engine.rootContext()->setContextProperty("utils", &utils);
engine.load(QUrl(QStringLiteral("qrc:/WebBrowser.qml")));
return app.exec();
}
diff --git a/examples/webenginequick/lifecycle/utils.h b/examples/webenginequick/lifecycle/utils.h
new file mode 100644
index 000000000..d9a803907
--- /dev/null
+++ b/examples/webenginequick/lifecycle/utils.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QUrl>
+
+class Utils : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE static QUrl fromUserInput(const QString &userInput);
+};
+
+inline QUrl Utils::fromUserInput(const QString &userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+#endif // UTILS_H
diff --git a/examples/webenginequick/minimal/CMakeLists.txt b/examples/webenginequick/minimal/CMakeLists.txt
deleted file mode 100644
index 9155ce040..000000000
--- a/examples/webenginequick/minimal/CMakeLists.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(minimal LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/minimal-qml")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineQuick)
-
-qt_add_executable(webengine-minimal-qml
- main.cpp
-)
-set_target_properties(webengine-minimal-qml PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(webengine-minimal-qml PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineQuick
-)
-
-
-# Resources:
-set(qml_resource_files
- "main.qml"
-)
-
-qt_add_resources(webengine-minimal-qml "qml"
- PREFIX
- "/"
- FILES
- ${qml_resource_files}
-)
-
-install(TARGETS webengine-minimal-qml
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/minimal/doc/src/minimal.qdoc b/examples/webenginequick/minimal/doc/src/minimal.qdoc
deleted file mode 100644
index c4b3afef9..000000000
--- a/examples/webenginequick/minimal/doc/src/minimal.qdoc
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginequick/minimal
- \title WebEngine Qt Quick Minimal Example
- \ingroup webengine-examples
- \brief Displays a web page using the Qt Quick integration of \QWE.
-
- \image minimal-example.png
-
- \e {WebEngine Qt Quick Minimal Example} demonstrates how to use the
- \l{WebEngineView} item to render a web page. It shows the minimum amount of
- code needed to load and display an HTML page, and can be used as a basis for
- further experimentation.
-
- \include examples-run.qdocinc
-
- \section1 C++ Code
-
- In \c main.cpp we use only the QGuiApplication and QQmlApplicationEngine
- classes. We also include \c qtwebengineglobal.h to be able to use
- \l{QtWebEngineQuick::initialize}.
-
- \quotefromfile webenginequick/minimal/main.cpp
- \skipto #include
- \printto main
-
- In the \c main function we first set the
- \l{QCoreApplication::organizationName} property. This affects the locations
- where \QWE stores persistent and cached data (see also
- \l{WebEngineProfile::cachePath} and
- \l{WebEngineProfile::persistentStoragePath}).
-
- Next, we call \l{QtWebEngineQuick::initialize}, which makes sure that OpenGL
- contexts can be shared between the main process and the dedicated renderer
- process (\c QtWebEngineProcess). This method needs to be called before
- any OpenGL context is created.
-
- Then we create a QQmlApplicationEngine, and tell it to load \c main.qml
- from the \l{The Qt Resource System}{Qt Resource System}.
-
- Finally, QGuiApplication::exec() launches the main event loop.
-
- \printuntil }
-
- \section1 QML Code
-
- In \c main.qml we create the top level window, set a sensible default size
- and make it visible. The window will be filled by a WebEngineView item
- loading the \l{Qt Homepage}.
-
- \quotefromfile webenginequick/minimal/main.qml
- \skipto import
- \printuntil }
- \printline }
-
- \section1 Requirements
-
- The example requires a working internet connection to render the
- \l{Qt Homepage}.
- An optional system proxy should be picked up automatically.
-*/
diff --git a/examples/webenginequick/minimal/main.cpp b/examples/webenginequick/minimal/main.cpp
deleted file mode 100644
index cf11eea26..000000000
--- a/examples/webenginequick/minimal/main.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
- QtWebEngineQuick::initialize();
- QGuiApplication app(argc, argv);
-
- QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
-
- return app.exec();
-}
-
diff --git a/examples/webenginequick/minimal/main.qml b/examples/webenginequick/minimal/main.qml
deleted file mode 100644
index d32176662..000000000
--- a/examples/webenginequick/minimal/main.qml
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Window
-import QtWebEngine
-
-Window {
- width: 1024
- height: 750
- visible: true
- WebEngineView {
- anchors.fill: parent
- url: "https://www.qt.io"
- }
-}
diff --git a/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml b/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
index cd40a7fdb..55c414409 100644
--- a/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webenginequick/quicknanobrowser/ApplicationRoot.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtWebEngine
diff --git a/examples/webenginequick/quicknanobrowser/BrowserDialog.qml b/examples/webenginequick/quicknanobrowser/BrowserDialog.qml
index 281f44904..7af347ec3 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserDialog.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserDialog.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Window
@@ -55,7 +8,7 @@ import QtWebEngine
Window {
id: window
property alias currentWebView: webView
- flags: Qt.Dialog | Qt.WindowStaysOnTopHint
+ flags: Qt.Dialog
width: 800
height: 600
visible: true
diff --git a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
index 0da1bc043..3b911262b 100644
--- a/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webenginequick/quicknanobrowser/BrowserWindow.qml
@@ -1,60 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 Qt.labs.settings
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtCore
import QtQml
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls.Fusion
import QtQuick.Layouts
import QtQuick.Window
import QtWebEngine
+import BrowserUtils
ApplicationWindow {
id: browserWindow
@@ -90,6 +44,7 @@ ApplicationWindow {
property alias webRTCPublicInterfacesOnly : webRTCPublicInterfacesOnly.checked
property alias devToolsEnabled: devToolsEnabled.checked
property alias pdfViewerEnabled: pdfViewerEnabled.checked
+ property int imageAnimationPolicy: WebEngineSettings.AllowImageAnimation
}
Action {
@@ -319,7 +274,7 @@ ApplicationWindow {
when: currentWebView
value: currentWebView.url
}
- onAccepted: currentWebView.url = utils.fromUserInput(text)
+ onAccepted: currentWebView.url = Utils.fromUserInput(text)
selectByMouse: true
}
ToolButton {
@@ -408,10 +363,49 @@ ApplicationWindow {
}
MenuItem {
id: pdfViewerEnabled
- text: "PDF viewer enabled"
+ text: "PDF Viewer Enabled"
checkable: true
checked: WebEngine.settings.pdfViewerEnabled
}
+
+ Menu {
+ id: imageAnimationPolicy
+ title: "Image Animation Policy"
+
+ MenuItem {
+ id: disableImageAnimation
+ text: "Disable All Image Animation"
+ checkable: true
+ autoExclusive: true
+ checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.DisallowImageAnimation
+ onTriggered: {
+ appSettings.imageAnimationPolicy = WebEngineSettings.DisallowImageAnimation
+ }
+ }
+
+ MenuItem {
+ id: allowImageAnimation
+ text: "Allow All Animated Images"
+ checkable: true
+ autoExclusive: true
+ checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.AllowImageAnimation
+ onTriggered : {
+ appSettings.imageAnimationPolicy = WebEngineSettings.AllowImageAnimation
+ }
+ }
+
+ MenuItem {
+ id: animateImageOnce
+ text: "Animate Image Once"
+ checkable: true
+ autoExclusive: true
+ checked: WebEngine.settings.imageAnimationPolicy === WebEngineSettings.AnimateImageOnce
+ onTriggered : {
+ appSettings.imageAnimationPolicy = WebEngineSettings.AnimateImageOnce
+ }
+ }
+ }
+
}
}
}
@@ -517,7 +511,6 @@ ApplicationWindow {
}
function removeView(index) {
- tabBar.removeItem(index);
if (tabBar.count > 1) {
tabBar.removeItem(tabBar.itemAt(index));
tabLayout.children[index].destroy();
@@ -556,6 +549,8 @@ ApplicationWindow {
}
}
]
+ settings.localContentCanAccessRemoteUrls: true
+ settings.localContentCanAccessFileUrls: false
settings.autoLoadImages: appSettings.autoLoadImages
settings.javascriptEnabled: appSettings.javaScriptEnabled
settings.errorPageEnabled: appSettings.errorPageEnabled
@@ -565,6 +560,7 @@ ApplicationWindow {
settings.touchIconsEnabled: appSettings.touchIconsEnabled
settings.webRTCPublicInterfacesOnly: appSettings.webRTCPublicInterfacesOnly
settings.pdfViewerEnabled: appSettings.pdfViewerEnabled
+ settings.imageAnimationPolicy: appSettings.imageAnimationPolicy
onCertificateError: function(error) {
error.defer();
@@ -603,13 +599,6 @@ ApplicationWindow {
request.accept();
}
- onQuotaRequested: function(request) {
- if (request.requestedSize <= 5 * 1024 * 1024)
- request.accept();
- else
- request.reject();
- }
-
onRegisterProtocolHandlerRequested: function(request) {
console.log("accepting registerProtocolHandler request for "
+ request.scheme + " from " + request.origin);
@@ -654,6 +643,15 @@ ApplicationWindow {
findBar.reset();
}
+ onFeaturePermissionRequested: function(securityOrigin, feature) {
+ featurePermissionDialog.securityOrigin = securityOrigin;
+ featurePermissionDialog.feature = feature;
+ featurePermissionDialog.visible = true;
+ }
+ onWebAuthUxRequested: function(request) {
+ webAuthDialog.init(request);
+ }
+
Timer {
id: reloadTimer
interval: 0
@@ -692,22 +690,21 @@ ApplicationWindow {
Dialog {
id: sslDialog
anchors.centerIn: parent
- contentWidth: Math.max(mainText.width, detailedText.width)
- contentHeight: mainText.height + detailedText.height
+ contentWidth: Math.max(mainTextForSSLDialog.width, detailedTextForSSLDialog.width)
+ contentHeight: mainTextForSSLDialog.height + detailedTextForSSLDialog.height
property var certErrors: []
// fixme: icon!
// icon: StandardIcon.Warning
standardButtons: Dialog.No | Dialog.Yes
title: "Server's certificate not trusted"
contentItem: Item {
- id: textContentItem
Label {
- id: mainText
+ id: mainTextForSSLDialog
text: "Do you wish to continue?"
}
Text {
- id: detailedText
- anchors.top: mainText.bottom
+ id: detailedTextForSSLDialog
+ anchors.top: mainTextForSSLDialog.bottom
text: "If you wish so, you may continue with an unverified certificate.\n" +
"Accepting an unverified certificate means\n" +
"you may not be connected with the host you tried to connect to.\n" +
@@ -733,6 +730,74 @@ ApplicationWindow {
visible = certErrors.length > 0
}
}
+ Dialog {
+ id: featurePermissionDialog
+ anchors.centerIn: parent
+ width: Math.min(browserWindow.width, browserWindow.height) / 3 * 2
+ contentWidth: mainTextForPermissionDialog.width
+ contentHeight: mainTextForPermissionDialog.height
+ standardButtons: Dialog.No | Dialog.Yes
+ title: "Permission Request"
+
+ property var feature;
+ property url securityOrigin;
+
+ contentItem: Item {
+ Label {
+ id: mainTextForPermissionDialog
+ text: featurePermissionDialog.questionForFeature()
+ }
+ }
+
+ onAccepted: currentWebView && currentWebView.grantFeaturePermission(securityOrigin, feature, true)
+ onRejected: currentWebView && currentWebView.grantFeaturePermission(securityOrigin, feature, false)
+ onVisibleChanged: {
+ if (visible)
+ width = contentWidth + 20;
+ }
+
+ function questionForFeature() {
+ var question = "Allow " + securityOrigin + " to "
+
+ switch (feature) {
+ case WebEngineView.Geolocation:
+ question += "access your location information?";
+ break;
+ case WebEngineView.MediaAudioCapture:
+ question += "access your microphone?";
+ break;
+ case WebEngineView.MediaVideoCapture:
+ question += "access your webcam?";
+ break;
+ case WebEngineView.MediaVideoCapture:
+ question += "access your microphone and webcam?";
+ break;
+ case WebEngineView.MouseLock:
+ question += "lock your mouse cursor?";
+ break;
+ case WebEngineView.DesktopVideoCapture:
+ question += "capture video of your desktop?";
+ break;
+ case WebEngineView.DesktopAudioVideoCapture:
+ question += "capture audio and video of your desktop?";
+ break;
+ case WebEngineView.Notifications:
+ question += "show notification on your desktop?";
+ break;
+ case WebEngineView.ClipboardReadWrite:
+ question += "read from and write to your clipboard?";
+ break;
+ case WebEngineView.LocalFontsAccess:
+ question += "access the fonts stored on your machine?";
+ break;
+ default:
+ question += "access unknown or unsupported feature [" + feature + "] ?";
+ break;
+ }
+
+ return question;
+ }
+ }
FullScreenNotification {
id: fullScreenNotification
@@ -744,6 +809,11 @@ ApplicationWindow {
anchors.fill: parent
}
+ WebAuthDialog {
+ id: webAuthDialog
+ visible: false
+ }
+
function onDownloadRequested(download) {
downloadView.visible = true;
downloadView.append(download);
diff --git a/examples/webenginequick/quicknanobrowser/CMakeLists.txt b/examples/webenginequick/quicknanobrowser/CMakeLists.txt
index 9a70a2c22..7efb61127 100644
--- a/examples/webenginequick/quicknanobrowser/CMakeLists.txt
+++ b/examples/webenginequick/quicknanobrowser/CMakeLists.txt
@@ -1,32 +1,37 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(quicknanobrowser LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/quicknanobrowser")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Qml)
-find_package(Qt6 COMPONENTS Quick)
-find_package(Qt6 COMPONENTS WebEngineQuick)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick WebEngineQuick)
qt_add_executable(quicknanobrowser
main.cpp
utils.h
)
+
+if(WIN32)
+ set_property(
+ TARGET quicknanobrowser
+ APPEND PROPERTY
+ SOURCES quicknanobrowser.exe.manifest)
+endif()
+
set_target_properties(quicknanobrowser PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginequick.quicknanobrowser"
)
+
target_link_libraries(quicknanobrowser PUBLIC
Qt::Core
Qt::Gui
@@ -35,6 +40,11 @@ target_link_libraries(quicknanobrowser PUBLIC
Qt::WebEngineQuick
)
+qt_add_qml_module(quicknanobrowser
+ URI BrowserUtils
+ VERSION 1.0
+ RESOURCE_PREFIX /
+)
# Resources:
set(resources_resource_files
@@ -44,6 +54,7 @@ set(resources_resource_files
"DownloadView.qml"
"FindBar.qml"
"FullScreenNotification.qml"
+ "WebAuthDialog.qml"
)
qt_add_resources(quicknanobrowser "resources"
@@ -52,6 +63,7 @@ qt_add_resources(quicknanobrowser "resources"
FILES
${resources_resource_files}
)
+
set(resources1_resource_files
"icons/3rdparty/go-next.png"
"icons/3rdparty/go-previous.png"
@@ -74,6 +86,24 @@ if(TARGET Qt::Widgets)
)
endif()
+if (APPLE)
+ set_target_properties(quicknanobrowser PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist"
+ )
+
+ if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ # Need to sign application for location permissions to work
+ if(QT_FEATURE_debug_and_release)
+ set(exe_path "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/")
+ else()
+ unset(exe_path)
+ endif()
+ add_custom_command(TARGET quicknanobrowser
+ POST_BUILD COMMAND codesign --force -s - ${exe_path}quicknanobrowser.app
+ )
+ endif()
+endif()
+
install(TARGETS quicknanobrowser
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
diff --git a/examples/webenginequick/quicknanobrowser/DownloadView.qml b/examples/webenginequick/quicknanobrowser/DownloadView.qml
index ea7e0b53d..421b4f55c 100644
--- a/examples/webenginequick/quicknanobrowser/DownloadView.qml
+++ b/examples/webenginequick/quicknanobrowser/DownloadView.qml
@@ -1,55 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls.Fusion
import QtWebEngine
import QtQuick.Layouts
diff --git a/examples/webenginequick/quicknanobrowser/FindBar.qml b/examples/webenginequick/quicknanobrowser/FindBar.qml
index 738a38c84..409d8dcff 100644
--- a/examples/webenginequick/quicknanobrowser/FindBar.qml
+++ b/examples/webenginequick/quicknanobrowser/FindBar.qml
@@ -1,55 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls.Fusion
import QtQuick.Layouts
Rectangle {
@@ -98,6 +51,7 @@ Rectangle {
TextField {
id: findTextField
anchors.fill: parent
+ color: "black"
background: Rectangle {
color: "transparent"
}
@@ -111,6 +65,7 @@ Rectangle {
Label {
text: activeMatch + "/" + numberOfMatches
visible: findTextField.text != ""
+ color: "black"
}
Rectangle {
@@ -126,17 +81,29 @@ Rectangle {
text: "<"
enabled: numberOfMatches > 0
onClicked: root.findPrevious()
+ contentItem: Text {
+ color: "black"
+ text: parent.text
+ }
}
ToolButton {
text: ">"
enabled: numberOfMatches > 0
onClicked: root.findNext()
+ contentItem: Text {
+ color: "black"
+ text: parent.text
+ }
}
ToolButton {
text: "x"
onClicked: root.visible = false
+ contentItem: Text {
+ color: "black"
+ text: parent.text
+ }
}
}
}
diff --git a/examples/webenginequick/quicknanobrowser/FullScreenNotification.qml b/examples/webenginequick/quicknanobrowser/FullScreenNotification.qml
index c5f891db6..779406432 100644
--- a/examples/webenginequick/quicknanobrowser/FullScreenNotification.qml
+++ b/examples/webenginequick/quicknanobrowser/FullScreenNotification.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
diff --git a/examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist b/examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist
new file mode 100644
index 000000000..cac4fa1f4
--- /dev/null
+++ b/examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>NSLocationUsageDescription</key>
+ <string>Quick Nano Browser would like to give web sites access to your location for demo purposes.</string>
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Quick Nano Browser would like to give web sites access to your computer's microphone for demo purposes.</string>
+ <key>NSCameraUsageDescription</key>
+ <string>Quick Nano Browser would like to give web sites access to your computer's camera for demo purposes.</string>
+</dict>
+</plist>
diff --git a/examples/webenginequick/quicknanobrowser/WebAuthDialog.qml b/examples/webenginequick/quicknanobrowser/WebAuthDialog.qml
new file mode 100644
index 000000000..aeb6f5a0f
--- /dev/null
+++ b/examples/webenginequick/quicknanobrowser/WebAuthDialog.qml
@@ -0,0 +1,281 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtWebEngine
+
+Dialog {
+ id: webAuthDialog
+ anchors.centerIn: parent
+ width: Math.min(browserWindow.width, browserWindow.height) / 3 * 2
+ contentWidth: verticalLayout.width +10;
+ contentHeight: verticalLayout.height +10;
+ standardButtons: Dialog.Cancel | Dialog.Apply
+ title: "WebAuth Request"
+
+ property var selectAccount;
+ property var authrequest: null;
+
+ Connections {
+ id: webauthConnection
+ ignoreUnknownSignals: true
+ function onStateChanged(state) {
+ webAuthDialog.setupUI(state);
+ }
+ }
+
+ onApplied: {
+ switch (webAuthDialog.authrequest.state) {
+ case WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
+ webAuthDialog.authrequest.setPin(pinEdit.text);
+ break;
+ case WebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
+ webAuthDialog.authrequest.setSelectedAccount(webAuthDialog.selectAccount);
+ break;
+ default:
+ break;
+ }
+ }
+
+ onRejected: {
+ webAuthDialog.authrequest.cancel();
+ }
+
+ function init(request) {
+ pinLabel.visible = false;
+ pinEdit.visible = false;
+ confirmPinLabel.visible = false;
+ confirmPinEdit.visible = false;
+ selectAccountModel.clear();
+ webAuthDialog.authrequest = request;
+ webauthConnection.target = request;
+ setupUI(webAuthDialog.authrequest.state)
+ webAuthDialog.visible = true;
+ pinEntryError.visible = false;
+ }
+
+ function setupUI(state) {
+ switch (state) {
+ case WebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
+ setupSelectAccountUI();
+ break;
+ case WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
+ setupCollectPin();
+ break;
+ case WebEngineWebAuthUxRequest.WebAuthUxState.FinishTokenCollection:
+ setupFinishCollectToken();
+ break;
+ case WebEngineWebAuthUxRequest.WebAuthUxState.RequestFailed:
+ setupErrorUI();
+ break;
+ case WebEngineWebAuthUxRequest.WebAuthUxState.Completed:
+ webAuthDialog.close();
+ break;
+ }
+ }
+
+ ButtonGroup {
+ id : selectAccount;
+ exclusive: true;
+ }
+
+ ListModel {
+ id: selectAccountModel
+
+ }
+ contentItem: Item {
+ ColumnLayout {
+ id : verticalLayout
+ spacing : 10
+
+ Label {
+ id: heading
+ text: "";
+ }
+
+ Label {
+ id: description
+ text: "";
+ }
+
+ Row {
+ spacing : 10
+ Label {
+ id: pinLabel
+ text: "PIN";
+ }
+ TextInput {
+ id: pinEdit
+ text: "EnterPin"
+ enabled: true
+ focus: true
+ color: "white"
+ layer.sourceRect: Qt.rect(0, 0, 20, 20)
+ }
+ }
+
+ Row {
+ spacing : 10
+ Label {
+ id: confirmPinLabel
+ text: "Confirm PIN";
+ }
+ TextEdit {
+ id: confirmPinEdit
+ text: ""
+ }
+ }
+
+ Label {
+ id: pinEntryError
+ text: "";
+ }
+
+ Repeater {
+ id : selectAccountRepeater
+ model: selectAccountModel
+ Column {
+ spacing : 5
+ RadioButton {
+ text: modelData
+ ButtonGroup.group : selectAccount;
+ onClicked: function(){
+ webAuthDialog.selectAccount = text;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ function setupSelectAccountUI() {
+ webAuthDialog.selectAccount = "";
+ heading.text = "Choose a passkey";
+ description.text = "Which passkey do you want to use for " + webAuthDialog.authrequest.relyingPartyId;
+
+ selectAccountModel.clear();
+ var userNames = webAuthDialog.authrequest.userNames;
+ for (var i = 0; i < userNames.length; i++) {
+ selectAccountModel.append( {"name" : userNames[i]});
+ }
+ pinLabel.visible = false;
+ pinEdit.visible = false;
+ confirmPinLabel.visible = false;
+ confirmPinEdit.visible = false;
+ pinEntryError.visible = false;
+ standardButton(Dialog.Apply).visible = true;
+ standardButton(Dialog.Cancel).visible = true;
+ standardButton(Dialog.Cancel).text ="Cancel"
+ }
+
+ function setupCollectPin() {
+ var requestInfo = webAuthDialog.authrequest.pinRequest;
+
+ pinEdit.clear();
+
+ if (requestInfo.reason === WebEngineWebAuthUxRequest.PinEntryReason.Challenge) {
+ heading.text = "PIN required";
+ description.text = "Enter the PIN for your security key";
+ pinLabel.visible = true;
+ pinEdit.visible = true;
+ confirmPinLabel.visible = false;
+ confirmPinEdit.visible = false;
+ } else if (reason === WebEngineWebAuthUxRequest.PinEntryReason.Set) {
+ heading.text = "Set PIN ";
+ description.text = "Set new PIN for your security key";
+ pinLabel.visible = true;
+ pinEdit.visible = true;
+ confirmPinLabel.visible = true;
+ confirmPinEdit.visible = true;
+ }
+ pinEntryError.text = getPINErrorDetails() + " " + requestInfo.remainingAttempts + " attempts reamining";
+ pinEntryError.visible = true;
+ selectAccountModel.clear();
+ standardButton(Dialog.Cancel).visible = true;
+ standardButton(Dialog.Cancel).text ="Cancel"
+ standardButton(Dialog.Apply).visible = true;
+ }
+
+ function getPINErrorDetails() {
+ var requestInfo = webAuthDialog.authrequest.pinRequest;
+ switch (requestInfo.error) {
+ case WebEngineWebAuthUxRequest.PinEntryError.NoError:
+ return "";
+ case WebEngineWebAuthUxRequest.PinEntryError.TooShort:
+ return "Too short";
+ case WebEngineWebAuthUxRequest.PinEntryError.InternalUvLocked:
+ return "Internal Uv locked";
+ case WebEngineWebAuthUxRequest.PinEntryError.WrongPin:
+ return "Wrong PIN";
+ case WebEngineWebAuthUxRequest.PinEntryError.InvalidCharacters:
+ return "Invalid characters";
+ case WebEngineWebAuthUxRequest.PinEntryError.SameAsCurrentPin:
+ return "Same as current PIN";
+ }
+ }
+
+ function getRequestFailureResaon() {
+ var requestFailureReason = webAuthDialog.authrequest.requestFailureReason;
+ switch (requestFailureReason) {
+ case WebEngineWebAuthUxRequest.RequestFailureReason.Timeout:
+ return " Request Timeout";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.KeyNotRegistered:
+ return "Key not registered";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.KeyAlreadyRegistered:
+ return "You already registered this device. You don't have to register it again
+ Try agin with different key or device";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.SoftPinBlock:
+ return "The security key is locked because the wrong PIN was entered too many times.
+ To unlock it, remove and reinsert it.";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.HardPinBlock:
+ return "The security key is locked because the wrong PIN was entered too many times.
+ You'll need to reset the security key.";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorRemovedDuringPinEntry:
+ return "Authenticator removed during verification. Please reinsert and try again";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingResidentKeys:
+ return "Authenticator doesn't have resident key support";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingUserVerification:
+ return "Authenticator missing user verification";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingLargeBlob:
+ return "Authenticator missing Large Blob support";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.NoCommonAlgorithms:
+ return "No common Algorithms";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.StorageFull:
+ return "Storage full";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.UserConsentDenied:
+ return "User consent denied";
+ case WebEngineWebAuthUxRequest.RequestFailureReason.WinUserCancelled:
+ return "User cancelled request";
+ }
+ }
+
+ function setupFinishCollectToken() {
+ heading.text = "Use your security key with " + webAuthDialog.authrequest.relyingPartyId;
+ description.text = "Touch your security key again to complete the request.";
+ pinLabel.visible = false;
+ pinEdit.visible = false;
+ confirmPinLabel.visible = false;
+ confirmPinEdit.visible = false;
+ selectAccountModel.clear();
+ pinEntryError.visible = false;
+ standardButton(Dialog.Apply).visible = false;
+ standardButton(Dialog.Cancel).visible = true;
+ standardButton(Dialog.Cancel).text ="Cancel"
+ }
+
+ function setupErrorUI() {
+ heading.text = "Something went wrong";
+ description.text = getRequestFailureResaon();
+ pinLabel.visible = false;
+ pinEdit.visible = false;
+ confirmPinLabel.visible = false;
+ confirmPinEdit.visible = false;
+ selectAccountModel.clear();
+ pinEntryError.visible = false;
+ standardButton(Dialog.Apply).visible = false;
+ standardButton(Dialog.Cancel).visible = true;
+ standardButton(Dialog.Cancel).text ="Close"
+ }
+}
diff --git a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
index 3b9af68b2..1dc209c2e 100644
--- a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
+++ b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginequick/quicknanobrowser
@@ -32,6 +8,8 @@
\brief A web browser implemented using the WebEngineView QML type.
\image quicknanobrowser-demo.jpg
+ \examplecategory {Application Examples}
+ \examplecategory {Web Technologies}
\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
@@ -115,6 +93,31 @@
\skipto Dialog {
\printuntil /^\ {4}\}/
+ \section1 Handling Feature Permission Requests
+
+ We use the \c onFeaturePermissionRequested() signal handler to handle requests for
+ accessing a certain feature or device. The \c securityOrigin parameter identifies the
+ requester web site, and the \c feature parameter is the requested feature. We use these
+ to construct the message of the dialog:
+
+ \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml
+ \skipto onFeaturePermissionRequested
+ \printuntil }
+
+ We show a dialog where the user is asked to grant or deny access. The custom
+ \c questionForFeature() JavaScript function generates a human-readable question about
+ the request.
+ If users select \uicontrol Yes, we call the \l{WebEngineView::}{grantFeaturePermission()}
+ method with a third \c true parameter to grant the \c securityOrigin web site the permission
+ to access the \c feature.
+ If users select \uicontrol No, we call the same method but with the \c false parameter to
+ deny access:
+
+ \skipto id: sslDialog
+ \skipto Dialog {
+ \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
@@ -141,6 +144,37 @@
\skipto Escape
\printuntil /^\ {4}\}/
+ \section1 Handling WebAuth/FIDO UX Requests
+
+ We use the \c onWebAuthUxRequested() signal handler to handle requests for
+ WebAuth/FIDO UX. The \c request parameter is an instance of WebEngineWebAuthUxRequest
+ which contains UX request details and APIs required to process the request.
+ We use it to construct WebAuthUX dialog and initiates the UX request flow.
+
+ \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml
+ \skipto onWebAuthUxRequested
+ \printuntil }
+
+ The \l WebEngineWebAuthUxRequest object periodically emits the \l
+ {WebEngineWebAuthUxRequest::}{stateChanged} signal to notify potential
+ observers of the current WebAuth UX states. The observers update the WebAuth
+ dialog accordingly. We use onStateChanged() signal handler to handle
+ state change requests. See \c WebAuthDialog.qml for an example
+ of how these signals can be handled.
+
+ \quotefromfile webenginequick/quicknanobrowser/WebAuthDialog.qml
+ \skipto Connections
+ \printuntil }
+ \skipto function init(request)
+ \printuntil }
+
+ \section1 Signing Requirement for macOS
+
+ To allow web sites access to the location, camera, and microphone when running
+ \e {Quick Nano Browser} on macOS, the application needs to be signed. This is
+ done automatically when building, but you need to set up a valid signing identity
+ for the build environment.
+
\section1 Files and Attributions
The example uses icons from the Tango Icon Library:
diff --git a/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json b/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json
index 681223b12..d8d85d6f1 100644
--- a/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json
+++ b/examples/webenginequick/quicknanobrowser/icons/3rdparty/qt_attribution.json
@@ -12,13 +12,13 @@
"LicenseId": "urn:dje:license:public-domain",
"License": "Public Domain",
"LicenseFile": "COPYING",
- "Copyright": "Ulisse Perusin <uli.peru@gmail.com>
-Steven Garrity <sgarrity@silverorange.com>
-Lapo Calamandrei <calamandrei@gmail.com>
-Ryan Collier <rcollier@novell.com>
-Rodney Dawes <dobey@novell.com>
-Andreas Nilsson <nisses.mail@home.se>
-Tuomas Kuosmanen <tigert@tigert.com>
-Garrett LeSage <garrett@novell.com>
-Jakub Steiner <jimmac@novell.com>"
+ "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
+ "Steven Garrity <sgarrity@silverorange.com>",
+ "Lapo Calamandrei <calamandrei@gmail.com>",
+ "Ryan Collier <rcollier@novell.com>",
+ "Rodney Dawes <dobey@novell.com>",
+ "Andreas Nilsson <nisses.mail@home.se>",
+ "Tuomas Kuosmanen <tigert@tigert.com>",
+ "Garrett LeSage <garrett@novell.com>",
+ "Jakub Steiner <jimmac@novell.com>"]
}
diff --git a/examples/webenginequick/quicknanobrowser/main.cpp b/examples/webenginequick/quicknanobrowser/main.cpp
index f21b0362c..1e693cbcd 100644
--- a/examples/webenginequick/quicknanobrowser/main.cpp
+++ b/examples/webenginequick/quicknanobrowser/main.cpp
@@ -1,90 +1,53 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "utils.h"
-#include <QtGui/QGuiApplication>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-static QUrl startupUrl()
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QCommandLineOption>
+#include <QtCore/QLoggingCategory>
+
+static QUrl startupUrl(const QCommandLineParser &parser)
{
- QUrl ret;
- QStringList args(qApp->arguments());
- args.takeFirst();
- for (const QString &arg : qAsConst(args)) {
- if (arg.startsWith(QLatin1Char('-')))
- continue;
- ret = Utils::fromUserInput(arg);
- if (ret.isValid())
- return ret;
+ if (!parser.positionalArguments().isEmpty()) {
+ const QUrl url = Utils::fromUserInput(parser.positionalArguments().constFirst());
+ if (url.isValid())
+ return url;
}
- return QUrl(QStringLiteral("https://www.qt.io"));
+ return QUrl(QStringLiteral("chrome://qt"));
}
int main(int argc, char **argv)
{
- QCoreApplication::setOrganizationName("QtExamples");
+ QCoreApplication::setApplicationName("Quick Nano Browser");
+ QCoreApplication::setOrganizationName("QtProject");
+
QtWebEngineQuick::initialize();
QGuiApplication app(argc, argv);
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.webenginecontext.debug=true"));
+
+ QCommandLineParser parser;
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("url", "The URL to open.");
+ parser.process(app);
QQmlApplicationEngine appEngine;
- Utils utils;
- appEngine.rootContext()->setContextProperty("utils", &utils);
appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
- if (!appEngine.rootObjects().isEmpty())
- QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl()));
- else
+ if (appEngine.rootObjects().isEmpty())
qFatal("Failed to load sources");
+ const QUrl url = startupUrl(parser);
+ QMetaObject::invokeMethod(appEngine.rootObjects().constFirst(),
+ "load", Q_ARG(QVariant, url));
+
return app.exec();
}
diff --git a/examples/webenginequick/quicknanobrowser/quicknanobrowser.exe.manifest b/examples/webenginequick/quicknanobrowser/quicknanobrowser.exe.manifest
new file mode 100644
index 000000000..acc401776
--- /dev/null
+++ b/examples/webenginequick/quicknanobrowser/quicknanobrowser.exe.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!--The ID below indicates application support for Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!--The ID below indicates application support for Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!--The ID below indicates application support for Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!--The ID below indicates application support for Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!--The ID below indicates application support for Windows 10/11 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+</compatibility>
+</assembly>
diff --git a/examples/webenginequick/quicknanobrowser/quicknanobrowser.pro b/examples/webenginequick/quicknanobrowser/quicknanobrowser.pro
index 8208e446a..bd5427dc5 100644
--- a/examples/webenginequick/quicknanobrowser/quicknanobrowser.pro
+++ b/examples/webenginequick/quicknanobrowser/quicknanobrowser.pro
@@ -6,17 +6,19 @@ TARGET = quicknanobrowser
HEADERS = utils.h
SOURCES = main.cpp
-OTHER_FILES += ApplicationRoot.qml \
- BrowserDialog.qml \
- BrowserWindow.qml \
- DownloadView.qml \
- FindBar.qml \
- FullScreenNotification.qml
+win32 {
+ CONFIG -= embed_manifest_exe
+ QMAKE_MANIFEST = $$PWD/quicknanobrowser.exe.manifest
+}
RESOURCES += resources.qrc
QT += qml quick webenginequick
+CONFIG += qmltypes
+QML_IMPORT_NAME = BrowserUtils
+QML_IMPORT_MAJOR_VERSION = 1
+
qtHaveModule(widgets) {
QT += widgets # QApplication is required to get native styling with QtQuickControls
}
diff --git a/examples/webenginequick/quicknanobrowser/resources.qrc b/examples/webenginequick/quicknanobrowser/resources.qrc
index 9d1f927d3..0a0b42bbb 100644
--- a/examples/webenginequick/quicknanobrowser/resources.qrc
+++ b/examples/webenginequick/quicknanobrowser/resources.qrc
@@ -6,6 +6,7 @@
<file>DownloadView.qml</file>
<file>FindBar.qml</file>
<file>FullScreenNotification.qml</file>
+ <file>WebAuthDialog.qml</file>
</qresource>
<qresource prefix="/icons">
<file alias="go-next.png">icons/3rdparty/go-next.png</file>
diff --git a/examples/webenginequick/quicknanobrowser/utils.h b/examples/webenginequick/quicknanobrowser/utils.h
index 79aa38cc7..6c11e75fb 100644
--- a/examples/webenginequick/quicknanobrowser/utils.h
+++ b/examples/webenginequick/quicknanobrowser/utils.h
@@ -1,65 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
#ifndef UTILS_H
#define UTILS_H
+#include <QtQml/qqml.h>
+
#include <QtCore/QFileInfo>
#include <QtCore/QUrl>
-class Utils : public QObject {
+class Utils : public QObject
+{
Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
public:
- Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
+ Q_INVOKABLE static QUrl fromUserInput(const QString &userInput);
};
-inline QUrl Utils::fromUserInput(const QString& userInput)
+inline QUrl Utils::fromUserInput(const QString &userInput)
{
QFileInfo fileInfo(userInput);
if (fileInfo.exists())
diff --git a/examples/webenginequick/recipebrowser/CMakeLists.txt b/examples/webenginequick/recipebrowser/CMakeLists.txt
deleted file mode 100644
index 9643234e7..000000000
--- a/examples/webenginequick/recipebrowser/CMakeLists.txt
+++ /dev/null
@@ -1,143 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(recipebrowser LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/recipebrowser")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Quick)
-find_package(Qt6 COMPONENTS Qml)
-find_package(Qt6 COMPONENTS QuickControls2)
-find_package(Qt6 COMPONENTS WebEngineQuick)
-
-qt_add_executable(recipebrowser
- main.cpp
-)
-set_target_properties(recipebrowser PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(recipebrowser PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Qml
- Qt::Quick
- Qt::QuickControls2
- Qt::WebEngineQuick
-)
-
-
-# Resources:
-set_source_files_properties("resources/pages/assets/3rdparty/markdown.css"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/assets/3rdparty/marked.js"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/assets/custom.css"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/assets/custom.js"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/burger.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/cupcakes.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/burger.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/cupcakes.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/pasta.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/pizza.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/skewers.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/soup.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/images/steak.jpg"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/pasta.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/pizza.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/skewers.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/soup.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/pages/steak.html"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/qml/RecipeList.qml"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set_source_files_properties("resources/qml/main.qml"
- PROPERTIES QT_SKIP_QUICKCOMPILER 1
-)
-set(resources_resource_files
- "resources/pages/assets/3rdparty/markdown.css"
- "resources/pages/assets/3rdparty/marked.js"
- "resources/pages/assets/custom.css"
- "resources/pages/assets/custom.js"
- "resources/pages/burger.html"
- "resources/pages/cupcakes.html"
- "resources/pages/images/burger.jpg"
- "resources/pages/images/cupcakes.jpg"
- "resources/pages/images/pasta.jpg"
- "resources/pages/images/pizza.jpg"
- "resources/pages/images/skewers.jpg"
- "resources/pages/images/soup.jpg"
- "resources/pages/images/steak.jpg"
- "resources/pages/pasta.html"
- "resources/pages/pizza.html"
- "resources/pages/skewers.html"
- "resources/pages/soup.html"
- "resources/pages/steak.html"
- "resources/qml/main.qml"
- "resources/qml/RecipeList.qml"
-)
-
-qt_add_resources(recipebrowser "resources"
- PREFIX
- "/"
- BASE
- "resources"
- FILES
- ${resources_resource_files}
-)
-
-if(CMAKE_CROSSCOMPILING AND (LINUX OR QNX OR posix))
- target_compile_definitions(recipebrowser PUBLIC
- QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
- )
-endif()
-
-install(TARGETS recipebrowser
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpg b/examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpg
deleted file mode 100644
index 761ad3576..000000000
--- a/examples/webenginequick/recipebrowser/doc/images/recipebrowser-demo.jpg
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc
deleted file mode 100644
index a9fb5baee..000000000
--- a/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginequick/recipebrowser
- \title WebEngine Recipe Browser
- \ingroup webengine-examples
- \brief A small hybrid application based on the WebEngineView QML type and Qt Quick Controls 2.
-
- \image recipebrowser-demo.jpg
-
- \e {Recipe Browser} demonstrates how to use the \l{WebEngineView} item, \l{Qt Quick} items, and
- \l{Qt Quick Controls 2} items to develop a small hybrid web browser application.
- A \l{ListView}-based item is used to display a list of recipe names. Clicking on
- a name causes the web view to load the respective recipe page. The overall appearance
- of the application is provided by the \l{Qt Quick Controls 2} items, which have their active
- style set to the \l{Material Style}{Material} style. The web content is a mix of HTML and
- Markdown source compiled to HTML, along with CSS and JavaScript.
-
- \include examples-run.qdocinc
-
- \section1 C++ Code
-
- In \c main.cpp, we use the \l{QGuiApplication} and \l{QQmlApplicationEngine}
- classes to set up and load the main QML file. We call \l{QtWebEngineQuick::initialize} so we can use
- \l{WebEngineView} in our QML code. We set the default Qt Quick Controls 2 style
- to the Material style, so we do not have to specify it for each new item we add. Finally, we use
- a C++ define to check whether the application is compiled for an embedded platform.
- The value will be used in the main QML code to determine the window size.
-
- \quotefromfile webenginequick/recipebrowser/main.cpp
- \skipto #include
- \printuntil }
-
- \section1 QML Code
-
- In the \c main.qml file, we first create a top-level window and set a title for it. We also set
- up the size of the window depending on its primary orientation as well as the platform, so that
- the application is usable on both desktop and embedded platforms. On desktop, the size
- is constrained by a minimum of 320x480 pixels up to the maximum size that the screen supports.
- The default window size is 1024 pixels wide and 768 pixels high in landscape orientation.
- On embedded devices, the window will occupy the whole screen.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
- \skipto ApplicationWindow
- \printuntil minimumHeight
-
- Next, we add a \l{RowLayout} item so we can divide the window into two parts: one being a
- custom \c RecipeList item containing the recipe titles, and the other being the
- \l{WebEngineView}, which shows the recipe details. The spacing is set to zero so the items are
- positioned directly next to each other.
-
- \printuntil RecipeList
- \dots 16
- \skipuntil webView.showRecipe
- \printline }
- \printuntil WebEngineView
- \dots 16
- \skipuntil busy.running = true
- \skipline }
- \skipline }
- \printline }
- \printline }
-
- The \c RecipeList item has a few \l{Layout}{attached Layout properties}, in order to scale the
- item to a maximum of one third of the layout width. We give the item focus, so that the keyboard
- can be used to navigate the recipes, in addition to using mouse and touch. We also add a handler
- for the custom \c recipeSelected signal, to tell the WebEngineView to load the URL of the
- selected recipe.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
- \skipto RecipeList
- \printuntil }
-
- The WebEngineView has similar layout properties, to make it occupy two thirds of the layout
- width.
-
- \skipto WebEngineView
- \printuntil Layout.fillHeight
-
- We then disable the \l{WebEngineSettings::focusOnNavigationEnabled}{focusOnNavigationEnabled}
- setting to make sure that the \l{WebEngineView} does not steal focus from the \c RecipeList
- item every time its URL is changed. This allows the user to continue navigating through the
- recipes using the keyboard. We also disable the default context menu by accepting the
- ContextMenuRequest.
-
- \skipto focusOnNavigationEnabled
- \printuntil }
-
- When the application starts, instead of directly showing the \l{WebEngineView}, we show a
- placeholder \l{Rectangle} with a \l{BusyIndicator} to provide a nicer user experience while the
- application is loading.
-
- \printuntil }
- \dots 12
- \skipto Rectangle
- \printuntil }
-
- Once the first page in the view is loaded, we start a \l{Timer} that
- will hide the placeholder and show the actual page. The delay provides more time for the recipe
- images to load, so that when the view is shown, the page is completely rendered. The timer also
- shows a help \l{ToolTip} that informs the user on how to navigate the recipes.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
- \skipto Timer {
- \printuntil }
-
- Let's see what the \c RecipeList item looks like from the inside. The root item is a
- FocusScope to allow transferring focus to the child ListView whenever the root item receives
- focus. We also declare a custom \c recipeSelected signal, which will be emitted when the current
- item of the ListView changes.
-
- \quotefromfile webenginequick/recipebrowser/resources/qml/RecipeList.qml
- \skipto FocusScope
- \printuntil recipeSelected
-
- A ColumnLayout holds a header \l{Label} above the ListView, and the ListView itself.
- Again, we set the spacing to zero and make sure the layout occupies the whole space of
- the parent item.
-
- \skipto ColumnLayout
- \printuntil anchors.fill
-
- Inside the layout there is a styled \l{ToolBar} item, with a \l{Label} inside of it serving as
- the ListView header.
-
- \skipto ToolBar
- \printuntil Label
- \printuntil }
- \printuntil }
-
- The second item inside the layout is a \l{ListView}, whose contents will fill the remaining
- space in the layout. We set \l{Item::}{clip} to true, so that the delegates that are scrolled
- up are not seen under the ToolBar item. We set \l{Item::}{focus} to true, so the ListView gains
- focus when the FocusScope does. We add a vertical scroll bar, so the user can scroll through the
- recipes if the window size is small. We also specify the recipe model to be used by the
- ListView as described later in this topic.
-
- \skipto ListView
- \printuntil model
-
- We have an \l{ItemDelegate} set as the ListView delegate, which displays the
- recipe title. The contentItem is a \l{Text} item, customized with a few properties to adjust the
- visual appearance and position of the text. We create a binding to the current delegate's model
- URL, so we can access the respective URL outside the delegate itself. We set the
- \l{ItemDelegate::}{highlighted} property to \c true whenever the item is the current one in the
- ListView to provide visual feedback. And we set the focus on the ListView whenever a delegate
- is clicked, so that keyboard navigation works in case the focus was previously in the
- WebEngineView.
-
- \skipto delegate
- \printuntil onClicked
- \printuntil }
- \printuntil }
-
- A handler is defined for the \c currentItemChanged signal to emit our own \c recipeSelected
- signal with the URL that the WebEngineView should load.
-
- \skipto onCurrentItemChanged
- \printuntil }
-
- We use a \l{ListModel} with seven \l{ListElement}s, each of which contains a recipe
- title and the URL to an HTML page contained in a resource file. The model is used to populate
- the ListView with the recipes and to show the recipe details in the WebEngineView.
-
- \skipto ListModel
- \printuntil Cupcakes
- \printuntil }
- \printuntil }
-
- We use a \l{ToolTip} item that is displayed on application startup to inform the users
- how they can navigate and view the details of each recipe. The ToolTip is shown using the
- \c showHelp method, which is invoked by the \l{Timer} in the main.qml file.
-
- \skipto ToolTip
- \printuntil help.open()
- \printuntil }
- \printuntil }
-
- An example of a recipe page can be seen below. The page uses two stylesheets and
- two JavaScript files:
- \list
- \li \l{https://bitbucket.org/kevinburke/markdowncss/src/master/}{markdown.css} is
- a markdown-friendly stylesheet created by Kevin Burke
- \li \l{https://github.com/chjj/marked}{marked.min.js} is a markdown parser and
- compiler designed for speed written by Christopher Jeffrey
- \li custom.css makes some small styling adjustments to the final recipe page
- \li custom.js is used to invoke the conversion of the recipe content (which is written in
- markdown syntax) into HTML
- \endlist
-
- The images on the pages are loaded from the compiled resource file.
-
- \quotefromfile webenginequick/recipebrowser/resources/pages/soup.html
- \printuntil </html>
-
- \section1 Files and Attributions
-
- The example bundles the following code with third-party licenses:
-
- \table
- \row
- \li \l{recipebrowser-marked}{Marked}
- \li MIT License
- \row
- \li \l{recipebrowser-markdowncss}{Markdown.css}
- \li Apache License 2.0
- \endtable
-*/
diff --git a/examples/webenginequick/recipebrowser/main.cpp b/examples/webenginequick/recipebrowser/main.cpp
deleted file mode 100644
index 5e9281ce5..000000000
--- a/examples/webenginequick/recipebrowser/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QQmlContext>
-#include <QQuickStyle>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QtWebEngineQuick::initialize();
-
- QGuiApplication app(argc, argv);
-
- QQuickStyle::setStyle(QStringLiteral("Material"));
-
- QQmlApplicationEngine engine;
-
- bool isEmbedded = false;
-#ifdef QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
- isEmbedded = true;
-#endif
- engine.rootContext()->setContextProperty(QStringLiteral("isEmbedded"), isEmbedded);
-
- engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
-
- return app.exec();
-}
diff --git a/examples/webenginequick/recipebrowser/recipebrowser.pro b/examples/webenginequick/recipebrowser/recipebrowser.pro
deleted file mode 100644
index e358d00a3..000000000
--- a/examples/webenginequick/recipebrowser/recipebrowser.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-TEMPLATE = app
-
-QT += quick qml quickcontrols2 webenginequick
-
-cross_compile {
- posix|qnx|linux: DEFINES += QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
-}
-
-SOURCES += main.cpp
-
-RESOURCES += resources/resources.qrc
-
-# Make sure Qt Quick compiler does not remove the source code of the .js files.
-QTQUICK_COMPILER_SKIPPED_RESOURCES = resources/resources.qrc
-
-DISTFILES += \
- resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt \
- resources/pages/assets/3rdparty/MARKED-LICENSE.txt
-
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginequick/recipebrowser
-INSTALLS += target
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json b/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json
deleted file mode 100644
index 4dafa1acd..000000000
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json
+++ /dev/null
@@ -1,34 +0,0 @@
-[
- {
- "Id": "recipebrowser-marked",
- "Name": "Marked (WebEngine RecipeBrowser example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "Marked is used in the WebEngine RecipeBrowser example",
- "QtParts": [ "examples" ],
- "Files": "marked.js",
- "Description": "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
- "Homepage": "https://github.com/chjj/marked",
- "Version": "0.4.0",
- "DownloadLocation": "https://github.com/markedjs/marked/blob/0.4.0/lib/marked.js",
- "Copyright": "Copyright (c) 2011-2018, Christopher Jeffrey",
- "License": "MIT License",
- "LicenseId": "MIT",
- "LicenseFile": "MARKED-LICENSE.txt"
- },
- {
- "Id": "recipebrowser-markdowncss",
- "Name": "Markdown.css (WebEngine RecipeBrowser example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "markdown.css is used in the WebEngine RecipeBrowser example",
- "QtParts": [ "examples" ],
- "Files": "markdown.css",
- "Description": "Markdown.css is better default styling for your Markdown files.",
- "Version": "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
- "DownloadLocation": "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
- "Copyright": "Copyright 2011 Kevin Burke
- Copyright Twitter Inc.",
- "License": "Apache License 2.0",
- "LicenseId": "Apache-2.0",
- "LicenseFile": "MARKDOWN-LICENSE.txt"
- }
-]
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.css b/examples/webenginequick/recipebrowser/resources/pages/assets/custom.css
deleted file mode 100644
index 6089ae580..000000000
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.css
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
-
-body {
- padding-top: 0;
- margin-top: 0;
-}
-
-#content {
- display: none;
-}
-
-img {
- width: 100%;
- height: 100%;
-}
-
-li {
- margin-left: 25px;
-}
-
-ol li {
- margin-bottom: 10px;
-}
-
-* {
- max-width: 960px !important;
-}
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.js b/examples/webenginequick/recipebrowser/resources/pages/assets/custom.js
deleted file mode 100644
index 25bdf851a..000000000
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/custom.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
-
-marked.setOptions({
- renderer: new marked.Renderer(),
- gfm: true,
- tables: true,
- breaks: false,
- pedantic: false,
- sanitize: false,
- smartLists: true,
- smartypants: false
-});
-
-// Poor man document.ready();
-(function() {
- var placeholder = document.getElementById('placeholder');
- var content = document.getElementById('content');
- placeholder.innerHTML = marked(content.innerHTML);
-})();
diff --git a/examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml b/examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml
deleted file mode 100644
index e4ec684ac..000000000
--- a/examples/webenginequick/recipebrowser/resources/qml/RecipeList.qml
+++ /dev/null
@@ -1,172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
-import QtQuick.Controls
-import QtQuick.Controls.Material
-import QtQuick.Layouts
-
-FocusScope {
- id: root
- signal recipeSelected(url url)
-
- ColumnLayout {
- spacing: 0
- anchors.fill: parent
-
- ToolBar {
- id: headerBackground
- Layout.fillWidth: true
- implicitHeight: headerText.height + 20
-
- Label {
- id: headerText
- width: parent.width
- text: qsTr("Favorite recipes")
- padding: 10
- anchors.centerIn: parent
- }
- }
-
- ListView {
- id: listView
- Layout.fillWidth: true
- Layout.fillHeight: true
- keyNavigationWraps: true
- clip: true
- focus: true
- ScrollBar.vertical: ScrollBar { }
-
- model: recipeModel
-
- delegate: ItemDelegate {
- width: parent.width
- text: model.name
- contentItem: Text {
- text: parent.text
- font: parent.font
- color: parent.enabled ? parent.Material.primaryTextColor
- : parent.Material.hintTextColor
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignLeft
- verticalAlignment: Text.AlignVCenter
- wrapMode: Text.Wrap
- }
-
- property url url: model.url
- highlighted: ListView.isCurrentItem
-
- onClicked: {
- listView.forceActiveFocus()
- listView.currentIndex = model.index
- }
- }
-
- onCurrentItemChanged: {
- root.recipeSelected(currentItem.url)
- }
-
- ListModel {
- id: recipeModel
-
- ListElement {
- name: "Pizza Diavola"
- url: "qrc:///pages/pizza.html"
- }
- ListElement {
- name: "Steak"
- url: "qrc:///pages/steak.html"
- }
- ListElement {
- name: "Burger"
- url: "qrc:///pages/burger.html"
- }
- ListElement {
- name: "Soup"
- url: "qrc:///pages/soup.html"
- }
- ListElement {
- name: "Pasta"
- url: "qrc:///pages/pasta.html"
- }
- ListElement {
- name: "Grilled Skewers"
- url: "qrc:///pages/skewers.html"
- }
- ListElement {
- name: "Cupcakes"
- url: "qrc:///pages/cupcakes.html"
- }
- }
-
- ToolTip {
- id: help
- implicitWidth: root.width - padding * 3
- y: root.y + root.height
- delay: 1000
- timeout: 5000
- text: qsTr("Use keyboard, mouse, or touch controls to navigate through the\
- recipes.")
-
- contentItem: Text {
- text: help.text
- font: help.font
- color: help.Material.primaryTextColor
- wrapMode: Text.Wrap
- }
- }
- }
- }
-
- function showHelp() {
- help.open()
- }
-}
-
diff --git a/examples/webenginequick/recipebrowser/resources/qml/main.qml b/examples/webenginequick/recipebrowser/resources/qml/main.qml
deleted file mode 100644
index 927b4424f..000000000
--- a/examples/webenginequick/recipebrowser/resources/qml/main.qml
+++ /dev/null
@@ -1,168 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 QtQml
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Controls.Material
-import QtQuick.Layouts
-import QtQuick.Window
-import QtWebEngine
-
-ApplicationWindow {
- id: appWindow
- title: qsTr("Recipe Browser")
- visible: true
-
- property int shorterDesktop: 768
- property int longerDesktop: 1024
- property int shorterMin: 360
- property int longerMin: 480
- property bool isPortrait: Screen.primaryOrientation === Qt.PortraitOrientation
- width: {
- if (isEmbedded)
- return Screen.width
- var potentialWidth = shorterDesktop
- if (!isPortrait)
- potentialWidth = longerDesktop
- return potentialWidth > Screen.width ? Screen.width : potentialWidth
- }
- height: {
- if (isEmbedded)
- return Screen.height
- var potentialHeight = longerDesktop
- if (!isPortrait)
- potentialHeight = shorterDesktop
- return potentialHeight > Screen.height ? Screen.height : potentialHeight
- }
- minimumWidth: isPortrait ? shorterMin : longerMin
- minimumHeight: isPortrait ? longerMin : shorterMin
-
- RowLayout {
- id: container
- anchors.fill: parent
- spacing: 0
-
- RecipeList {
- id: recipeList
- Layout.minimumWidth: 124
- Layout.preferredWidth: parent.width / 3
- Layout.maximumWidth: 300
- Layout.fillWidth: true
- Layout.fillHeight: true
- focus: true
- activeFocusOnTab: true
- onRecipeSelected: function(url) {
- webView.showRecipe(url)
- }
- }
-
- WebEngineView {
- id: webView
- Layout.preferredWidth: 2 * parent.width / 3
- Layout.fillWidth: true
- Layout.fillHeight: true
- // Make sure focus is not taken by the web view, so user can continue navigating
- // recipes with the keyboard.
- settings.focusOnNavigationEnabled: false
-
- onContextMenuRequested: function(request) {
- request.accepted = true
- }
-
- property bool firstLoadComplete: false
- onLoadingChanged: function(loadRequest) {
- if (loadRequest.status === WebEngineView.LoadSucceededStatus
- && !firstLoadComplete) {
- // Debounce the showing of the web content, so images are more likely
- // to have loaded completely.
- showTimer.start()
- }
- }
-
- Timer {
- id: showTimer
- interval: 500
- repeat: false
- onTriggered: {
- webView.show(true)
- webView.firstLoadComplete = true
- recipeList.showHelp()
- }
- }
-
- Rectangle {
- id: webViewPlaceholder
- anchors.fill: parent
- z: 1
- color: "white"
-
- BusyIndicator {
- id: busy
- anchors.centerIn: parent
- }
- }
-
- function showRecipe(url) {
- webView.url = url
- }
-
- function show(show) {
- if (show === true) {
- busy.running = false
- webViewPlaceholder.visible = false
- } else {
- webViewPlaceholder.visible = true
- busy.running = true
- }
- }
- }
- }
-}
diff --git a/examples/webenginequick/recipebrowser/resources/resources.qrc b/examples/webenginequick/recipebrowser/resources/resources.qrc
deleted file mode 100644
index bd13dcfae..000000000
--- a/examples/webenginequick/recipebrowser/resources/resources.qrc
+++ /dev/null
@@ -1,27 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>qml/main.qml</file>
- <file>qml/RecipeList.qml</file>
-
- <file>pages/pizza.html</file>
- <file>pages/burger.html</file>
- <file>pages/steak.html</file>
- <file>pages/soup.html</file>
- <file>pages/pasta.html</file>
- <file>pages/skewers.html</file>
- <file>pages/cupcakes.html</file>
-
- <file>pages/assets/3rdparty/marked.js</file>
- <file>pages/assets/3rdparty/markdown.css</file>
- <file>pages/assets/custom.css</file>
- <file>pages/assets/custom.js</file>
-
- <file>pages/images/burger.jpg</file>
- <file>pages/images/pizza.jpg</file>
- <file>pages/images/steak.jpg</file>
- <file>pages/images/soup.jpg</file>
- <file>pages/images/pasta.jpg</file>
- <file>pages/images/skewers.jpg</file>
- <file>pages/images/cupcakes.jpg</file>
- </qresource>
-</RCC>
diff --git a/examples/webenginequick/webengineaction/CMakeLists.txt b/examples/webenginequick/webengineaction/CMakeLists.txt
deleted file mode 100644
index 926825d21..000000000
--- a/examples/webenginequick/webengineaction/CMakeLists.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(webengineaction LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/webengineaction")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineQuick)
-
-qt_add_executable(webengineaction
- main.cpp
-)
-set_target_properties(webengineaction PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(webengineaction PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineQuick
-)
-
-
-# Resources:
-set(qml_resource_files
- "main.qml"
-)
-
-qt_add_resources(webengineaction "qml"
- PREFIX
- "/"
- FILES
- ${qml_resource_files}
-)
-
-install(TARGETS webengineaction
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginequick/webengineaction/doc/images/webengineaction-example.png b/examples/webenginequick/webengineaction/doc/images/webengineaction-example.png
deleted file mode 100644
index 2e34bbf63..000000000
--- a/examples/webenginequick/webengineaction/doc/images/webengineaction-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc b/examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc
deleted file mode 100644
index 096a16fc4..000000000
--- a/examples/webenginequick/webengineaction/doc/src/webengineaction.qdoc
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginequick/webengineaction
- \title WebEngine Action Example
- \ingroup webengine-examples
- \brief A simple browser implemented using WebEngineActions.
-
- \image webengineaction-example.png
-
- \e {WebEngine Action Example} demonstrates how to perform actions on a web page
- using the \l{WebEngineAction} type. It shows the minimum amount of code needed
- to bind browser functionalities to input elements and build up a custom context
- menu.
-
- \include examples-run.qdocinc
-
- \section1 Working With Web Engine Actions
-
- An intended use of \l{WebEngineAction} is building a connection between UI
- elements and browser commands. It can be added to menus and toolbars via
- assigning its properties to the corresponding ones of the element.
-
- The \l{ToolButton} relies on the properties provided by a
- \l{WebEngineAction}. Clicking the button triggers backwards navigation on the
- originating \l{WebEngineView} of the action.
-
- \quotefromfile webenginequick/webengineaction/main.qml
- \skipto ToolButton {
- \printuntil }
-
- The simplest way to create custom context menus is enumerating the required
- \l{WebEngineAction} types in a data model and instantiating \l{MenuItem} types
- for them, for example using a \l{Repeater}.
-
- \quotefromfile webenginequick/webengineaction/main.qml
- \skipto property Menu contextMenu: Menu {
- \printuntil /^ {8}\}/
-
- Assigning a \l{WebEngineAction} to multiple UI elements will keep them in sync.
- As it can be seen in the picture above, if the browser engine disables a
- navigation action, both corresponding menu items will be disabled.
-*/
diff --git a/examples/webenginequick/webengineaction/main.cpp b/examples/webenginequick/webengineaction/main.cpp
deleted file mode 100644
index a30749ebe..000000000
--- a/examples/webenginequick/webengineaction/main.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QtWebEngineQuick::initialize();
-
- QGuiApplication app(argc, argv);
-
- QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
-
- return app.exec();
-}
diff --git a/examples/webenginequick/webenginequick.pro b/examples/webenginequick/webenginequick.pro
index 058868395..fb44f2c54 100644
--- a/examples/webenginequick/webenginequick.pro
+++ b/examples/webenginequick/webenginequick.pro
@@ -1,13 +1,9 @@
TEMPLATE=subdirs
SUBDIRS += \
- customdialogs \
- minimal \
- quicknanobrowser \
- webengineaction
+ quicknanobrowser
qtHaveModule(quickcontrols2) {
SUBDIRS += \
- lifecycle \
- recipebrowser
+ lifecycle
}
diff --git a/examples/webenginewidgets/CMakeLists.txt b/examples/webenginewidgets/CMakeLists.txt
index a0dc6330d..3ce666d72 100644
--- a/examples/webenginewidgets/CMakeLists.txt
+++ b/examples/webenginewidgets/CMakeLists.txt
@@ -1,22 +1,26 @@
-add_subdirectory(minimal)
-add_subdirectory(contentmanipulation)
-add_subdirectory(cookiebrowser)
-add_subdirectory(notifications)
-add_subdirectory(simplebrowser)
-add_subdirectory(stylesheetbrowser)
-add_subdirectory(videoplayer)
-add_subdirectory(webui)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+qt_internal_add_example(contentmanipulation)
+qt_internal_add_example(cookiebrowser)
+qt_internal_add_example(notifications)
+qt_internal_add_example(simplebrowser)
+qt_internal_add_example(push-notifications)
+qt_internal_add_example(videoplayer)
if(QT_FEATURE_webengine_geolocation)
- add_subdirectory(maps)
+ qt_internal_add_example(maps)
endif()
if(QT_FEATURE_webengine_webchannel)
- add_subdirectory(markdowneditor)
+ qt_internal_add_example(recipebrowser)
endif()
if(QT_FEATURE_webengine_printing_and_pdf)
- add_subdirectory(printme)
- add_subdirectory(html2pdf)
+ qt_internal_add_example(printme)
+ qt_internal_add_example(html2pdf)
endif()
if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING
AND NOT QT_FEATURE_webengine_native_spellchecker AND NOT WIN32)
- add_subdirectory(spellchecker)
+ qt_internal_add_example(spellchecker)
+endif()
+if(QT_FEATURE_ssl)
+ qt_internal_add_example(clientcertificate)
endif()
diff --git a/examples/webenginewidgets/clientcertificate/CMakeLists.txt b/examples/webenginewidgets/clientcertificate/CMakeLists.txt
new file mode 100644
index 000000000..97c9393ff
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/CMakeLists.txt
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(clientcertificate LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/clientcertificate")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
+
+qt_add_executable(server
+ server.cpp
+)
+
+qt_add_executable(client
+ client.cpp
+)
+
+set_target_properties(client PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+qt_add_resources(client "client"
+ PREFIX
+ "/"
+ FILES
+ "resources/client.pem"
+ "resources/client.key"
+)
+
+qt_add_resources(server "server"
+ PREFIX
+ "/"
+ FILES
+ "resources/server.pem"
+ "resources/server.key"
+ "resources/ca.pem"
+)
+
+target_link_libraries(client PUBLIC
+ Qt::WebEngineWidgets
+)
+
+target_link_libraries(server PUBLIC
+ Qt::Core
+ Qt::Network
+)
+
+install(TARGETS server client
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/webenginewidgets/clientcertificate/client.cpp b/examples/webenginewidgets/clientcertificate/client.cpp
new file mode 100644
index 000000000..1227fa28e
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/client.cpp
@@ -0,0 +1,67 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/qfile.h>
+#include <QtNetwork/qsslkey.h>
+#include <QtWebEngineCore/qwebenginecertificateerror.h>
+#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
+#include <QtWebEngineCore/qwebengineprofile.h>
+#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qdialog.h>
+#include <QtWidgets/qlabel.h>
+#include <QtWidgets/qlistwidget.h>
+#include <QtWidgets/qpushbutton.h>
+#include <QtWidgets/qboxlayout.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QApplication app(argc, argv);
+
+ QFile certFile(":/resources/client.pem");
+ certFile.open(QIODevice::ReadOnly);
+ const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
+
+ QFile keyFile(":/resources/client.key");
+ keyFile.open(QIODevice::ReadOnly);
+ const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
+
+ QWebEnginePage page;
+ QObject::connect(&page, &QWebEnginePage::certificateError,
+ [](QWebEngineCertificateError e) { e.acceptCertificate(); });
+
+ QObject::connect(
+ &page, &QWebEnginePage::selectClientCertificate, &page,
+ [&cert](QWebEngineClientCertificateSelection selection) {
+ QDialog dialog;
+ QVBoxLayout *layout = new QVBoxLayout;
+ QLabel *label = new QLabel(QLatin1String("Select certificate"));
+ QListWidget *listWidget = new QListWidget;
+ listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ QPushButton *button = new QPushButton(QLatin1String("Select"));
+ layout->addWidget(label);
+ layout->addWidget(listWidget);
+ layout->addWidget(button);
+ QObject::connect(button, &QPushButton::clicked, [&dialog]() { dialog.accept(); });
+ const QList<QSslCertificate> &list = selection.certificates();
+ for (const QSslCertificate &cert : list) {
+ listWidget->addItem(cert.subjectDisplayName() + " : " + cert.serialNumber());
+ }
+ dialog.setLayout(layout);
+ if (dialog.exec() == QDialog::Accepted)
+ selection.select(list[listWidget->currentRow()]);
+ else
+ selection.selectNone();
+ });
+
+ QWebEngineView view(&page);
+ view.setUrl(QUrl("https://localhost:5555"));
+ view.resize(800, 600);
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/clientcertificate/client.pro b/examples/webenginewidgets/clientcertificate/client.pro
new file mode 100644
index 000000000..e397d5efa
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/client.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+
+QT += webenginewidgets
+
+SOURCES += client.cpp
+
+RESOURCES += resources/client.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/clientcertificate/client
+INSTALLS += target
diff --git a/examples/webenginewidgets/clientcertificate/clientcertificate.pro b/examples/webenginewidgets/clientcertificate/clientcertificate.pro
new file mode 100644
index 000000000..66039d05c
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/clientcertificate.pro
@@ -0,0 +1,7 @@
+QT_FOR_CONFIG += network-private
+TEMPLATE = subdirs
+
+client.file = client.pro
+server.file = server.pro
+
+qtConfig(ssl): SUBDIRS += client server
diff --git a/examples/webenginewidgets/clientcertificate/doc/images/granted.png b/examples/webenginewidgets/clientcertificate/doc/images/granted.png
new file mode 100644
index 000000000..b2def9b5e
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/doc/images/granted.png
Binary files differ
diff --git a/examples/webenginewidgets/clientcertificate/doc/images/selection.png b/examples/webenginewidgets/clientcertificate/doc/images/selection.png
new file mode 100644
index 000000000..2756ac7be
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/doc/images/selection.png
Binary files differ
diff --git a/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc b/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc
new file mode 100644
index 000000000..c5440f08f
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/doc/src/clientcertificate.qdoc
@@ -0,0 +1,160 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example webenginewidgets/clientcertificate
+ \examplecategory {Web Technologies}
+ \title WebEngine Widgets Client Certificate Example
+ \ingroup webengine-widgetexamples
+ \brief A simple client certificate authentication scenario using \QWE and \l QSslServer.
+
+ \image selection.png
+
+ In this example we are going to show a client certificate authentication workflow.
+ The presented authentication scenario can be for example implemented
+ for an embedded device, which provides a web interface to handle its functionality.
+ The administrator uses the \QWE powered client to maintain the embedded device
+ and has a custom SSL certificate to authenticate.
+ The connection is encrypted with SSL sockets. The embedded device uses
+ a \c QSslSocket to handle the authentication and the encryption. This way the
+ administrator does not have to enter any credentials and just needs to select
+ a proper certificate that is recognized by the device.
+
+ In the example we focus on a very simple and minimalistic approach to demonstrate
+ the workflow. Note that QSslSocket is a low level solution as we do not have to
+ run a full-blown HTTPS server on the resource limited embedded device.
+
+ \section1 Creating Certificates
+
+ The example comes with certificates already generated, but let's see how to generate
+ new ones. We create certificates for the server and the client using
+ \l{https://www.openssl.org}{OpenSSL tooling}.
+
+ First, we create the certificate signing request \c CSR and sign it. We will use
+ a CA private key to sign and issue both local certificates for the client and the server.
+
+ \badcode
+ openssl req -out ca.pem -new -x509 -nodes -keyout ca.key
+ \endcode
+
+ \note Specify the \c {-days} option to override the default certificate validity of 30 days.
+
+ Now, let's create two private keys for our client and a server:
+
+ \badcode
+ openssl genrsa -out client.key 2048
+ \endcode
+ \badcode
+ openssl genrsa -out server.key 2048
+ \endcode
+
+ Next we need two certificate signing requests:
+
+ \badcode
+ openssl req -key client.key -new -out client.req
+ \endcode
+ \badcode
+ openssl req -key server.key -new -out server.req
+ \endcode
+
+ Let's issue now both certificates from CSRs:
+
+ \badcode
+ openssl x509 -req -in client.req -out client.pem -CA ca.pem -CAkey ca.key
+ \endcode
+ \badcode
+ openssl x509 -req -in server.req -out server.pem -CA ca.pem -CAkey ca.key
+ \endcode
+
+ The client certificate subject and the serial number will be displayed for
+ selection during authentication. The serial number can be printed with:
+
+ \badcode
+ openssl x509 -serial -noout -in client.pem
+ \endcode
+
+ \section1 Implementing the Client
+
+ Now we can implement our web browser client.
+
+ We start by loading our certificate and its private key and creating \l QSslCertificate
+ and \l QSslKey instances.
+
+
+ \quotefromfile webenginewidgets/clientcertificate/client.cpp
+ \skipto QFile
+ \printuntil QSslKey
+
+ Now we add the certificate and its private key to \l {QWebEngineClientCertificateStore}.
+
+ \printuntil clientCertificateStore
+
+ To handle certificates we need to create an instance of \l QWebEnginePage and connect to two
+ singals \l QWebEnginePage::certificateError and \l QWebEnginePage::selectClientCertificate.
+ The first one is only needed as our self-signed server certificate will trigger a certificate
+ error, which has to be accepted to proceed with the authentication. In production
+ environments self-signed certificates are not used, therefore in this example we handle
+ \l QWebEngineCertificateError just to avoid providing proper certificates.
+ Note the private key is a secret and should never be published.
+
+ \printuntil acceptCertificate
+
+ The handling for \l QWebEnginePage::selectClientCertificate simply displays \l QDialog
+ with \l QListWidget showing a list of client certificates to choose from.
+ The user selected certificate is then passed to the
+ \l QWebEngineClientCertificateSelection::select call.
+
+ \printto QWebEngineView
+
+ Finally, we create a \l QWebEngineView for our \l QWebEnginePage, load the server
+ URL, and show the page.
+
+ \printuntil show
+
+ \section1 Implementing the Server
+
+ For our embedded device we will develop a minimalistic HTTPS server. We can use \l QSslServer
+ to handle incoming connections and to provide an \l QSslSocket instance. To do that,
+ we create an instance of a \l QSslServer and, similarly to our client setup, we load a server
+ certificate and its private key. Next, we create \l QSslCertificate and \l QSslKey objects
+ accordingly. Additionally, we need a CA certificate so the server can validate the certificate
+ presented by the client. The CA and local certificate are set to \l QSslConfiguration and
+ used later by the server.
+
+ \quotefromfile webenginewidgets/clientcertificate/server.cpp
+ \skipto QSslServer
+ \printuntil setSslConfiguration
+
+ Next, we set the server to listen for incoming connections on port \c 5555
+
+ \printuntil qInfo
+
+ We provide a lambda function for the \l QTcpServer::pendingConnectionAvailable signal,
+ where we implement handling for incoming connections. This signal is triggered
+ after authentication has succeeded and \c socket TLS encryption has started.
+
+ \printto readyRead
+
+ The \c Request object used above is a simple wrapper around \l QByteArray as we use
+ \l QPointer to help with memory management. This object gathers incoming HTTP data.
+ It is deleted when the request has completed or a socket has been terminated.
+
+ \quotefromfile webenginewidgets/clientcertificate/server.cpp
+ \skipto struct
+ \printuntil };
+
+ The reply for the request depends on the requested URL, and it is sent back through
+ the socket in form of a HTML page. For the \c GET root request the administrator sees
+ the \c {Access Granted} message and an \c {Exit} HTML button. If the administrator clicks it,
+ the client sends another request. This time with the \c{/exit} relative URL,
+ which it turn triggers the server termination.
+
+ \quotefromfile webenginewidgets/clientcertificate/server.cpp
+ \skipto readyRead
+ \printuntil });
+
+ To run the example, start the \c server and then the \c client. After you select
+ the certificate, the \c {Access Granted} page is displayed.
+
+ \image granted.png
+*/
diff --git a/examples/webenginewidgets/clientcertificate/resources/ca.pem b/examples/webenginewidgets/clientcertificate/resources/ca.pem
new file mode 100644
index 000000000..cb62ad62c
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/ca.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECzCCAvOgAwIBAgIUdhDW1WgGxF313LYA0JjEQpKbanQwDQYJKoZIhvcNAQEL
+BQAwgZQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl
+cmxpbjEXMBUGA1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5n
+aW5lMRIwEAYDVQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5n
+aW5lQHF0LmlvMB4XDTIyMTExNjExMDQxNFoXDTMyMTExMzExMDQxNFowgZQxCzAJ
+BgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEXMBUG
+A1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5naW5lMRIwEAYD
+VQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5naW5lQHF0Lmlv
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxyNLLwAA+FgNQavVJ19n
+gdoy+NKLHQyhzcRFykKSp9aAbpAR6e4ukxwG7mWNBcuR7zv1Zw/JqLFE0gmVztVw
+FeQWdw1cvTN/OlVEuM+0ShTDHHsCqRpx7/XJT6ytMKVU8jdZN4Vl1m7MubWv4aPy
+0WYYd3zIAicciYgy/RHaRhPTKpPzWIPYhmHsM5w2cebL8I0aZXUkC0OeklJArnp9
+007Fr6SXXK0xQ3RO20n7X193gCfd5U70lug0ks/ZZqxtzPHmzIO1WGAOBura50HR
+hxUKAu7qQHzBiW5Qwdn0af4FPLJR/SX8ADKTLCSWlMOo1FLYO5w6D8hB4K6/b9VQ
+RwIDAQABo1MwUTAdBgNVHQ4EFgQUXuTuB85/iBgwJpLdOc+8TB0KESIwHwYDVR0j
+BBgwFoAUXuTuB85/iBgwJpLdOc+8TB0KESIwDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQsFAAOCAQEAvtucUJa0IECltWv8U6R+LQuZ1Q+ubbmstojO/h8tg6Wf
+v6FZ5bH3oboSyGEcytRr6INf4G6znUNAypbodehAEW6/PETdzGM9CJyv2JPJAWzV
+rxb1H5VTyiEs8924QOqcNATD+oe7G0vwnDkvprcqaWBA6yvQkWpCXoqMc+F95KnY
+8VFt2VQw17l4L4nhaX3Us6hJLMiKV+dLeF0pN+pkCPRP9G5WKgW3mT2U6Gig+rLz
+6L7rBbb5KWAttdAbuHCrMa65PgXoVD1P/GteFxUnghDd0PWgUaign8c/DyHGsrbA
+uvJqSym0kmQQXptryRaKFsGcCrizdbE6FfrH2iE7vQ==
+-----END CERTIFICATE-----
diff --git a/examples/webenginewidgets/clientcertificate/resources/client.key b/examples/webenginewidgets/clientcertificate/resources/client.key
new file mode 100644
index 000000000..21c8e3183
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/client.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAqnHbq38y1VprEaV2xXzv2nAPyjqCuIfuick8qETkzEsNWPQi
+dsBlLfcyf+15wEMhpRIwILXCrUM7Sb7WCGtg1XC00JZvCh2xPBMSD2fiQyHn4men
+Fwh9vVbTf1v7w21ZT/pXQrwlgLgNWYZHE3JrcEAwlThQRIdQfzSE6/QeHfYZoGB9
+WfvbREsOWiUlZze/yrblS9vnAVhYwVurelc7lXyHA0dHmkcZ0HwMxVJZ/vLuCyIw
+lNGT/ytnA9p1l8uFkAgTcbWZKoyJAsAZG9faZp46hk8+e3KAyKQ78aoUSbjAqnNQ
+tBM3bnHeHanf3ddCxyej+k9PfSIY27a9FZxHpQIDAQABAoIBAFsomA8p8ZsQR9Fh
+SJupDXMrmhZTotRkxxxkR4/LgP8OaO4ZbFFM5xBldFndPc+pV9Y8WwczjxIxsgTo
+Dvrjyx98rwgcXPjxFniFzpP0wJudB7McMs5r2SwpwuYL4SQNWMYgowjrLbehOGqY
+GW16NaIMgq9cNfng0RmnkivMHUtyE5GGdK+C6cyK+fIE+cNtQtHPRKfEnwbE9VHz
+3EY/nCXGZvMFyj5uHaU4EeZFCzo19TUqhh8H7b0EA44pBtb5U/CxsH4xphZ7rpjt
+iVjMfRSMR4qalQNIs6ZEj57We+M/zca/Qq1yhjW+0NYbZifcYo1Oj6e4lC9YlIgn
+kGkcuUECgYEA1j0iVFjgBXS8pJP3jBgmbrbBBTNEUv27yjnJCAQx5TbplJkvBM4/
+qzum1uH2o6uRrFtrYJFiAhDHARtg+70rMeYqZp8WFvzJT5c5s+FOmGQPfFjgrD6e
+wfnCwFzS7nohJ8TM2mPGJ88pBv0eBYW6D0f7fvcJmEk8hnGktdLRCrECgYEAy6tU
+YFZDzGhbgrG2wWzBvAKVngUNhrYZHMiF1WVN8zZdCm7Z8b1S/NMe0rPA5orhAkSX
+8fxlDfKOm+U2fKp43aiN0NDiP0TlGRbypAXe7FSnvDxNHbV+Ie0UbwuiJ4s3vJuc
+6cdzgKqAs5/rjPXPdUpM8C7344HV7azgSzHIYTUCgYAtVmCmcuxtmye0uG+BoTa4
+5UnxvMivu2x7PkFRxfl9JWLHBKfTn4YPyZ7kCIu2VT+NtwcBN6MDBuPmUxHyFDVI
+6Ql+EBqPoM1FX55hd8O3Mi2oxfI94T6dlCpnpP0qZIQRs28apFSx5gArr3Mj/gnC
+5BvP4Z2RMaZyWShfJg8A8QKBgQClZEhswyDjiYtmorJqeMsKxn6BiFDnqFDUUvJ7
+zHx0mR0NL9/Es54Eud059ccccIMwuEs7s17M6MBuUMDik/z647nmbPqNroDs0vnP
+wQS6njRoY/+rtIrtOf1x/9x6iE+G1keigNmHDu7c72z1V1hVQzUfhsS+99yl2dF6
+vr6eUQKBgF/OHW1bE3FruZ+53Arcb94N/IKnpH9VWoB3elIzr0w6pLtL4HHhmQ58
+TayEpq6YguUAjTvCBbaHuYuKPHiXCAy5DhtrXvP4YdMNH9X1nHc7jVEbGltVbnQU
+bG/p5YfZSrDmsjf8w0z7feFOcovC6vF1YCXc8OHK/LQ6JFJ/gtO1
+-----END RSA PRIVATE KEY-----
diff --git a/examples/webenginewidgets/clientcertificate/resources/client.pem b/examples/webenginewidgets/clientcertificate/resources/client.pem
new file mode 100644
index 000000000..dd1f898f7
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/client.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApcCFFNQAgGBu5nr81tUMdXXLGkm8Li+MA0GCSqGSIb3DQEBCwUAMIGU
+MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
+FzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTES
+MBAGA1UEAwwJd3d3LnF0LmlvMSAwHgYJKoZIhvcNAQkBFhFxdHdlYmVuZ2luZUBx
+dC5pbzAeFw0yMjExMTYxMjExMDFaFw0zMjExMTMxMjExMDFaMIGSMQswCQYDVQQG
+EwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAoM
+DlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTEVMBMGA1UEAwwM
+Y2xpZW50LnF0LmlvMRswGQYJKoZIhvcNAQkBFgxjbGllbnRAcXQuaW8wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqcdurfzLVWmsRpXbFfO/acA/KOoK4
+h+6JyTyoROTMSw1Y9CJ2wGUt9zJ/7XnAQyGlEjAgtcKtQztJvtYIa2DVcLTQlm8K
+HbE8ExIPZ+JDIefiZ6cXCH29VtN/W/vDbVlP+ldCvCWAuA1ZhkcTcmtwQDCVOFBE
+h1B/NITr9B4d9hmgYH1Z+9tESw5aJSVnN7/KtuVL2+cBWFjBW6t6VzuVfIcDR0ea
+RxnQfAzFUln+8u4LIjCU0ZP/K2cD2nWXy4WQCBNxtZkqjIkCwBkb19pmnjqGTz57
+coDIpDvxqhRJuMCqc1C0Ezducd4dqd/d10LHJ6P6T099Ihjbtr0VnEelAgMBAAEw
+DQYJKoZIhvcNAQELBQADggEBALE75ZQxmEXJA16cNAxxmxCKHkaqAE6Ulim1vXNH
+jCFfNCDGYn/R28F3BVtMe+bIMoomaTh3h5eOd/9uc2nm8IiT5FUz9epJWPeRG/cl
+I+hQ3fvaE7oJ3m3EwfGq1mdqUf1zi+DFjtkimNbn9ZRDocZfpO5VN0u23ptEuk0P
+5cH4+Dst0giRMv5W0kXG6QD13H/eVH3jDZCtZa/8T4oxGGskHEa4yDr8s976lVOV
+XLI1r7oN4a/KXKow8WN3oHFeKn4QJx86z1uecuZLtT8xjABKSWpZqgsIlmGTGE1a
+9W06C+uPVamwn5ND3gnf93YQqn6PwrjlHdrQOTG/vngJLPw=
+-----END CERTIFICATE-----
diff --git a/examples/webenginewidgets/clientcertificate/resources/client.qrc b/examples/webenginewidgets/clientcertificate/resources/client.qrc
new file mode 100644
index 000000000..cc3492e80
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/client.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/resources">
+ <file>client.key</file>
+ <file>client.pem</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/clientcertificate/resources/server.key b/examples/webenginewidgets/clientcertificate/resources/server.key
new file mode 100644
index 000000000..632cc4d2e
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/server.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA5gQoJryenjmvzy4RbqHdNXHK8Gk/8Lto1SwT8+Wbh5EyYRTt
+hFdioT1JYcIe3XMwOmx3TjADY1jAXAPfeRcjTkMcnZwF76AXUK2XqBANhaG1wjsi
+b7ISGU/U5/Jarm2iwQJ5zjKsNm8pZYqpmKsYAVFMErtfcpdLdSp6BG54SrbItcXh
+WHfsUs5cuVEi9nCeugLkDzoPLlj/TeouKWOdzhyvLXkPvPmD4/hD0dULTXpCDZhf
+73AuQBWTGsWeUnJQiQhDRwuXWhGRX8qFJQ4rzY8rIbaKhge+BQ6BL+pij2uzHKNQ
+j12ZLFZgLihLDJogGp08y9Ud6Ru/3WGoFkY38wIDAQABAoIBABM/TczQA8XhteB0
+Tmkfik8qknzDkeInDIKqCZFjKTyS3dBZ2/YzCcHMSxOvFr4ZIXQCF4mnYuExUAdj
+G5QaZ43o98AIikae8tSBcitSDI+eFIOIRz1pfTI5B+vQz93AttnHx0GF4/s6GhCx
+JbfsuTmDAAahPz9rgZjwUP2F8PLvaAZqJrXBPY+QLWz0SN2zh6vWAHPbJA0sO/4E
+oWUhRPXJDf33YCFxnwtbUBie5313suAfNspODcyH+AxBH2FFh63pe0ZGOhX7XFMJ
+yxJqujeZrQdfwFZNPXAPVLJGbd7AIOrVE+O8/bYUB/uuj6pPJBqr+Ob/JhY48pRb
+VG2qL4ECgYEA9n3PuL13F9XFcLeergGH7fUcSQeD1T6Z1qaI2Wth0Umfmer/fFZh
+IKSCSwEGMTLsalFdlTj8jsSAasjuSorQTeSgHjzvzik1Ll2P6syputjsD1RX/nkl
+8L50Pwdeey57Y9dgow7Cw/heGYs6dkXLe9H6qM7eoB8Vrk7/TAFuqNECgYEA7uOl
+oKyOxeLn005cenc5enY2IxDhXTaAjTGHE64C0lmicD2OZB7/b+ZIb8M5R7GnCNox
+4TxLSRhZYOMO/QcTrnSND5PXbX/HLd3nyQRIN1XtBbg7pJooxP/MQ/Ne5XTTMjCg
+qPudkOe0ZgUHEcuH8m/YAFY3DDJC50uiXqYtxYMCgYBHfL+ExbZHfGExyp9Duf/x
+PHhCmeJbMzessEnaPLF24FJgcm48YlTzAaMkG5zvIeS9BPIOOCPPSCAyWCn8BnxZ
+SuhBPM0TzpG067+0ijzjiswTuhN3Iy2kv6e5K+rz8MwqbamCQOKtsVehMub2rFFS
+jNiUosKgT8Oa9SBHq9arMQKBgQCE3EVEnFP3iOAILH/QeLiV/GLVk9DTR7mtTUtj
+zZayKLnoFMQ5uOe182x8BCa6UfqlOL0fGKqCZ7Fl6kJuxV3T2+yMKlxZAQTk5JLB
+wMjtRbPCR5mcTUS5c87GR/eSRCwlsNfZw775VXSGfOtWoUzlsACBB3IsLVP6UZ1n
+aKLyQwKBgC61BvKiyGBEYIchqMI4dSF+zCJbSjNUtjwVobcgC6yERZtX2OeLFCoh
+NEf9CcL2Eqb+RzwAD3OV65AiZcrThQNXZ8poBxvwWK8I6E6zB+LX7POAvNu/AV/5
+ANnxwHGGLqi+wTcdMZal2iXkdsrno1Ek/nGMCdA7IVs7l5k7fEpG
+-----END RSA PRIVATE KEY-----
diff --git a/examples/webenginewidgets/clientcertificate/resources/server.pem b/examples/webenginewidgets/clientcertificate/resources/server.pem
new file mode 100644
index 000000000..4706fa73e
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/server.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApcCFFNQAgGBu5nr81tUMdXXLGkm8Li/MA0GCSqGSIb3DQEBCwUAMIGU
+MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
+FzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTES
+MBAGA1UEAwwJd3d3LnF0LmlvMSAwHgYJKoZIhvcNAQkBFhFxdHdlYmVuZ2luZUBx
+dC5pbzAeFw0yMjExMTYxMjExMTRaFw0zMjExMTMxMjExMTRaMIGSMQswCQYDVQQG
+EwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAoM
+DlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTEVMBMGA1UEAwwM
+c2VydmVyLnF0LmlvMRswGQYJKoZIhvcNAQkBFgxzZXJ2ZXJAcXQuaW8wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmBCgmvJ6eOa/PLhFuod01ccrwaT/w
+u2jVLBPz5ZuHkTJhFO2EV2KhPUlhwh7dczA6bHdOMANjWMBcA995FyNOQxydnAXv
+oBdQrZeoEA2FobXCOyJvshIZT9Tn8lqubaLBAnnOMqw2bylliqmYqxgBUUwSu19y
+l0t1KnoEbnhKtsi1xeFYd+xSzly5USL2cJ66AuQPOg8uWP9N6i4pY53OHK8teQ+8
++YPj+EPR1QtNekINmF/vcC5AFZMaxZ5SclCJCENHC5daEZFfyoUlDivNjyshtoqG
+B74FDoEv6mKPa7Mco1CPXZksVmAuKEsMmiAanTzL1R3pG7/dYagWRjfzAgMBAAEw
+DQYJKoZIhvcNAQELBQADggEBAHotgaBbqIlG4EqjzSpX8kQnZnGJUsA51dbY3K5C
+4tNCd+JquQfPmCIKDHkRsmmEU6pcU+LT8m+toJ8Gx0XG4nrdUIDt0Nlf/QrykbPj
+hN8z+aSfP9J5tg4NsT7qMWmqUHOa3BcsgWcC4IwWVkbOMz/XbczEQqdBJMbE0+PC
+32ihTKPZBPC2QlIvXyuwupvQtcXgEjw1r2FQeYcmItk3CKbJPE/Rk4/aXSCo4b0F
+iXPphh8BJPZVvQ2cLpPaGvcse5qjIhF9ODb2HEK3myMwuJVi7teURy8mPlS23Li/
+8gRCNu/stjMlkic7d3dqV0LwaG8+Df1W2wzxsT7IkxN/Z+o=
+-----END CERTIFICATE-----
diff --git a/examples/webenginewidgets/clientcertificate/resources/server.qrc b/examples/webenginewidgets/clientcertificate/resources/server.qrc
new file mode 100644
index 000000000..502afa9cc
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/resources/server.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/resources">
+ <file>server.key</file>
+ <file>server.pem</file>
+ <file>ca.pem</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/clientcertificate/server.cpp b/examples/webenginewidgets/clientcertificate/server.cpp
new file mode 100644
index 000000000..ee83dab8a
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/server.cpp
@@ -0,0 +1,99 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qtimer.h>
+#include <QtNetwork/qsslconfiguration.h>
+#include <QtNetwork/qsslkey.h>
+#include <QtNetwork/qsslserver.h>
+
+struct Request : public QObject
+{
+ QByteArray m_data;
+};
+
+static const QByteArray http_ok(QByteArrayLiteral(
+ "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"));
+static const QByteArray html_start(QByteArrayLiteral("<html><style>"
+ "div {"
+ "height: 400px;"
+ "width: 200px;"
+ "position: fixed;"
+ "top: 50%;"
+ "left: 50%;"
+ "margin-top: -100px;"
+ "margin-left: -200px;"
+ "}</style><body><div>"));
+static const QByteArray html_end(QByteArrayLiteral("</div></body></html>"));
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QCoreApplication app(argc, argv);
+
+ QSslServer server;
+ QSslConfiguration configuration(QSslConfiguration::defaultConfiguration());
+ configuration.setPeerVerifyMode(QSslSocket::VerifyPeer);
+
+ QFile keyFile(":/resources/server.key");
+ keyFile.open(QIODevice::ReadOnly);
+
+ QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ configuration.setPrivateKey(key);
+
+ QList<QSslCertificate> localCerts = QSslCertificate::fromPath(":/resources/server.pem");
+ configuration.setLocalCertificateChain(localCerts);
+
+ QList<QSslCertificate> caCerts = QSslCertificate::fromPath(":resources/ca.pem");
+ configuration.addCaCertificates(caCerts);
+
+ server.setSslConfiguration(configuration);
+
+ if (!server.listen(QHostAddress::LocalHost, 5555))
+ qFatal("Could not start server on localhost:5555");
+ else
+ qInfo("Server started on localhost:5555");
+
+ QObject::connect(&server, &QTcpServer::pendingConnectionAvailable, [&server]() {
+ QTcpSocket *socket = server.nextPendingConnection();
+ Q_ASSERT(socket);
+
+ QPointer<Request> request(new Request);
+
+ QObject::connect(socket, &QAbstractSocket::disconnected, socket,
+ [socket, request]() mutable {
+ delete request;
+ socket->deleteLater();
+ });
+
+ QObject::connect(socket, &QTcpSocket::readyRead, socket, [socket, request]() mutable {
+ request->m_data.append(socket->readAll());
+
+ if (!request->m_data.endsWith("\r\n\r\n"))
+ return;
+
+ socket->write(http_ok);
+ socket->write(html_start);
+
+ if (request->m_data.startsWith("GET / ")) {
+ socket->write("<p>ACCESS GRANTED !</p>");
+ socket->write("<p>You reached the place, where no one has gone before.</p>");
+ socket->write("<button onclick=\"window.location.href='/exit'\">Exit</button>");
+ } else if (request->m_data.startsWith("GET /exit ")) {
+ socket->write("<p>BYE !</p>");
+ socket->write("<p>Have good day ...</p>");
+ QTimer::singleShot(0, &QCoreApplication::quit);
+ } else {
+ socket->write("<p>There is nothing to see here.</p>");
+ }
+
+ socket->write(html_end);
+ delete request;
+ socket->disconnectFromHost();
+ });
+ });
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/clientcertificate/server.pro b/examples/webenginewidgets/clientcertificate/server.pro
new file mode 100644
index 000000000..b8fda1717
--- /dev/null
+++ b/examples/webenginewidgets/clientcertificate/server.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+QT += core network
+CONFIG += console
+
+SOURCES += server.cpp
+
+RESOURCES += resources/server.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/clientcertificate/server
+INSTALLS += target
diff --git a/examples/webenginewidgets/contentmanipulation/CMakeLists.txt b/examples/webenginewidgets/contentmanipulation/CMakeLists.txt
index ae93a7a7e..f0b9e9638 100644
--- a/examples/webenginewidgets/contentmanipulation/CMakeLists.txt
+++ b/examples/webenginewidgets/contentmanipulation/CMakeLists.txt
@@ -1,37 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(contentmanipulation LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/contentmanipulation")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(contentmanipulation
main.cpp
mainwindow.cpp mainwindow.h
)
+
set_target_properties(contentmanipulation PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(contentmanipulation PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-
# Resources:
set(jquery_resource_files
"jquery.min.js"
diff --git a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
index 66a1252dc..ae91affe5 100644
--- a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
+++ b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/contentmanipulation
+ \examplecategory {Web Technologies}
\title WebEngine Content Manipulation Example
\ingroup webengine-widgetexamples
\brief Demonstrates how to load and manipulate web content.
diff --git a/examples/webenginewidgets/contentmanipulation/main.cpp b/examples/webenginewidgets/contentmanipulation/main.cpp
index b53fdef47..d096a71b2 100644
--- a/examples/webenginewidgets/contentmanipulation/main.cpp
+++ b/examples/webenginewidgets/contentmanipulation/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include "mainwindow.h"
diff --git a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
index 154a37747..3990be2b8 100644
--- a/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include <QtWebEngineWidgets>
diff --git a/examples/webenginewidgets/contentmanipulation/mainwindow.h b/examples/webenginewidgets/contentmanipulation/mainwindow.h
index 66512f969..c50fccacb 100644
--- a/examples/webenginewidgets/contentmanipulation/mainwindow.h
+++ b/examples/webenginewidgets/contentmanipulation/mainwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
diff --git a/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json b/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json
index 4cb51436e..35d9cf0d7 100644
--- a/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json
+++ b/examples/webenginewidgets/cookiebrowser/3rdparty/qt_attribution.json
@@ -12,13 +12,13 @@
"LicenseId": "urn:dje:license:public-domain",
"License": "Public Domain",
"LicenseFile": "COPYING",
- "Copyright": "Ulisse Perusin <uli.peru@gmail.com>
-Steven Garrity <sgarrity@silverorange.com>
-Lapo Calamandrei <calamandrei@gmail.com>
-Ryan Collier <rcollier@novell.com>
-Rodney Dawes <dobey@novell.com>
-Andreas Nilsson <nisses.mail@home.se>
-Tuomas Kuosmanen <tigert@tigert.com>
-Garrett LeSage <garrett@novell.com>
-Jakub Steiner <jimmac@novell.com>"
+ "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
+ "Steven Garrity <sgarrity@silverorange.com>",
+ "Lapo Calamandrei <calamandrei@gmail.com>",
+ "Ryan Collier <rcollier@novell.com>",
+ "Rodney Dawes <dobey@novell.com>",
+ "Andreas Nilsson <nisses.mail@home.se>",
+ "Tuomas Kuosmanen <tigert@tigert.com>",
+ "Garrett LeSage <garrett@novell.com>",
+ "Jakub Steiner <jimmac@novell.com>"]
}
diff --git a/examples/webenginewidgets/cookiebrowser/CMakeLists.txt b/examples/webenginewidgets/cookiebrowser/CMakeLists.txt
index e94ecae7a..828fb95e8 100644
--- a/examples/webenginewidgets/cookiebrowser/CMakeLists.txt
+++ b/examples/webenginewidgets/cookiebrowser/CMakeLists.txt
@@ -1,21 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(cookiebrowser LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/cookiebrowser")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(cookiebrowser
cookiedialog.ui
@@ -23,17 +21,18 @@ qt_add_executable(cookiebrowser
main.cpp
mainwindow.cpp mainwindow.h mainwindow.ui
)
+
set_target_properties(cookiebrowser PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(cookiebrowser PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-
# Resources:
set(cookiebrowser_resource_files
"3rdparty/view-refresh.png"
diff --git a/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc b/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc
index 316e11a9b..adc302779 100644
--- a/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc
+++ b/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2015 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/cookiebrowser
+ \examplecategory {Web Technologies}
\title WebEngine Cookie Browser Example
\ingroup webengine-widgetexamples
\brief A cookie browser based on \QWE Widgets.
diff --git a/examples/webenginewidgets/cookiebrowser/main.cpp b/examples/webenginewidgets/cookiebrowser/main.cpp
index b3fe71840..5722b69a4 100644
--- a/examples/webenginewidgets/cookiebrowser/main.cpp
+++ b/examples/webenginewidgets/cookiebrowser/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QApplication>
diff --git a/examples/webenginewidgets/cookiebrowser/mainwindow.cpp b/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
index 66e6988d8..67454a9f1 100644
--- a/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
+++ b/examples/webenginewidgets/cookiebrowser/mainwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QWebEngineCookieStore>
@@ -106,8 +59,9 @@ CookieWidget::CookieWidget(const QNetworkCookie &cookie, QWidget *parent): QWidg
void CookieWidget::setHighlighted(bool enabled)
{
+ m_isHighlighted = enabled;
QPalette p = palette();
- p.setColor(backgroundRole(), enabled ? QColor(0xF0, 0xF8, 0xFF) : Qt::white);
+ p.setColor(backgroundRole(), enabled ? p.alternateBase().color() : p.base().color());
setPalette(p);
}
@@ -159,9 +113,18 @@ void MainWindow::handleCookieAdded(const QNetworkCookie &cookie)
return;
CookieWidget *widget = new CookieWidget(cookie);
- widget->setHighlighted(m_cookies.count() % 2);
m_cookies.append(cookie);
- m_layout->insertWidget(0,widget);
+ // Check whether the first widget in the layout is highlighted.
+ // if it is highlighted, then do not highlight the new item.
+ CookieWidget *firstWidget = m_layout->count()
+ ? qobject_cast<CookieWidget *>(m_layout->itemAt(0)->widget())
+ : nullptr;
+ if (firstWidget) {
+ widget->setHighlighted(!firstWidget->isHighlighted());
+ } else {
+ widget->setHighlighted(false);
+ }
+ m_layout->insertWidget(0, widget);
connect(widget, &CookieWidget::deleteClicked, [this, cookie, widget]() {
m_store->deleteCookie(cookie);
diff --git a/examples/webenginewidgets/cookiebrowser/mainwindow.h b/examples/webenginewidgets/cookiebrowser/mainwindow.h
index b6aee1c24..da0d438ca 100644
--- a/examples/webenginewidgets/cookiebrowser/mainwindow.h
+++ b/examples/webenginewidgets/cookiebrowser/mainwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
@@ -76,9 +29,13 @@ class CookieWidget : public QWidget, public Ui_CookieWidget
public:
CookieWidget(const QNetworkCookie &cookie, QWidget *parent = nullptr);
void setHighlighted(bool enabled);
+ bool isHighlighted() { return m_isHighlighted; }
signals:
void deleteClicked();
void viewClicked();
+
+private:
+ bool m_isHighlighted = false;
};
class MainWindow : public QMainWindow, public Ui_MainWindow
diff --git a/examples/webenginewidgets/html2pdf/CMakeLists.txt b/examples/webenginewidgets/html2pdf/CMakeLists.txt
index 80567e88f..0386d3d83 100644
--- a/examples/webenginewidgets/html2pdf/CMakeLists.txt
+++ b/examples/webenginewidgets/html2pdf/CMakeLists.txt
@@ -1,29 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(html2pdf LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/html2pdf")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(html2pdf
html2pdf.cpp
)
+
set_target_properties(html2pdf PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(html2pdf PUBLIC
Qt::Core
Qt::Gui
diff --git a/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc b/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc
index c60bc6d0b..7199a812c 100644
--- a/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc
+++ b/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/html2pdf
+ \examplecategory {Web Technologies}
\title WebEngine Widgets Html2Pdf Example
\ingroup webengine-widgetexamples
\brief Converts web pages to PDF documents using \QWE.
diff --git a/examples/webenginewidgets/html2pdf/html2pdf.cpp b/examples/webenginewidgets/html2pdf/html2pdf.cpp
index 1b52d69b1..1c9e5f607 100644
--- a/examples/webenginewidgets/html2pdf/html2pdf.cpp
+++ b/examples/webenginewidgets/html2pdf/html2pdf.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include <QCommandLineParser>
@@ -55,9 +8,7 @@
#include <QWebEngineView>
#include <functional>
-
-using namespace std;
-using namespace std::placeholders;
+#include <utility>
class Html2PdfConverter : public QObject
{
@@ -77,8 +28,8 @@ private:
};
Html2PdfConverter::Html2PdfConverter(QString inputPath, QString outputPath)
- : m_inputPath(move(inputPath))
- , m_outputPath(move(outputPath))
+ : m_inputPath(std::move(inputPath))
+ , m_outputPath(std::move(outputPath))
, m_view(new QWebEngineView)
{
connect(m_view.data(), &QWebEngineView::loadFinished,
diff --git a/examples/webenginewidgets/maps/CMakeLists.txt b/examples/webenginewidgets/maps/CMakeLists.txt
index 01eb96e70..93d9634f8 100644
--- a/examples/webenginewidgets/maps/CMakeLists.txt
+++ b/examples/webenginewidgets/maps/CMakeLists.txt
@@ -1,36 +1,54 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(maps LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/maps")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(maps
main.cpp
mainwindow.cpp mainwindow.h
)
+
set_target_properties(maps PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginewidgets.maps"
)
+
target_link_libraries(maps PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
+if (APPLE)
+ set_target_properties(maps PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist"
+ )
+
+ if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ # Need to sign application for location permissions to work
+ if(QT_FEATURE_debug_and_release)
+ set(exe_path "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/")
+ else()
+ unset(exe_path)
+ endif()
+ add_custom_command(TARGET maps
+ POST_BUILD COMMAND codesign --force -s - ${exe_path}maps.app
+ )
+ endif()
+endif()
+
install(TARGETS maps
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
diff --git a/examples/webenginewidgets/maps/Info.cmake.macos.plist b/examples/webenginewidgets/maps/Info.cmake.macos.plist
new file mode 100644
index 000000000..82336b25a
--- /dev/null
+++ b/examples/webenginewidgets/maps/Info.cmake.macos.plist
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>NSLocationUsageDescription</key>
+ <string>The maps demo would like to access your location for demo purposes.</string>
+
+</dict>
+</plist>
diff --git a/examples/webenginewidgets/maps/doc/src/maps.qdoc b/examples/webenginewidgets/maps/doc/src/maps.qdoc
index 75923c8f5..0175f8b65 100644
--- a/examples/webenginewidgets/maps/doc/src/maps.qdoc
+++ b/examples/webenginewidgets/maps/doc/src/maps.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/maps
+ \examplecategory {Web Technologies}
\title WebEngine Widgets Maps Example
\ingroup webengine-widgetexamples
\brief Demonstrates how to handle geolocation requests.
@@ -39,13 +16,19 @@
The \l {https://www.w3.org/TR/geolocation-API/}{Geolocation API} is a
JavaScript API that web applications can use to determine the user's
physical location to show on a map, for example. As \QWE relies on the
- \e {Qt Location} module to power this API, a viable location backend is
+ \e {Qt Positioning} module to power this API, a viable location backend is
needed for the target platform.
To avoid accidentally sending location information to third parties
geolocation requests are denied by default. This example demonstrates the
steps an application must take in order to start accepting these requests.
+ \note On Windows 11, enable settings to grant the application access to
+ Windows location services. In the Settings App under
+ \uicontrol {Privacy & Security} > \uicontrol {Location}, enable \uicontrol
+ {Location services}, \uicontrol {Let apps access your location} and \uicontrol
+ {Let desktop apps access your location}.
+
\include examples-run.qdocinc
\section1 The Code
diff --git a/examples/webenginewidgets/maps/main.cpp b/examples/webenginewidgets/maps/main.cpp
index 4a0fedb7b..550546130 100644
--- a/examples/webenginewidgets/maps/main.cpp
+++ b/examples/webenginewidgets/maps/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QApplication>
diff --git a/examples/webenginewidgets/maps/mainwindow.cpp b/examples/webenginewidgets/maps/mainwindow.cpp
index 3098bd72e..0d2b49911 100644
--- a/examples/webenginewidgets/maps/mainwindow.cpp
+++ b/examples/webenginewidgets/maps/mainwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
diff --git a/examples/webenginewidgets/maps/mainwindow.h b/examples/webenginewidgets/maps/mainwindow.h
index 6401c2087..3c8450296 100644
--- a/examples/webenginewidgets/maps/mainwindow.h
+++ b/examples/webenginewidgets/maps/mainwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
diff --git a/examples/webenginewidgets/markdowneditor/CMakeLists.txt b/examples/webenginewidgets/markdowneditor/CMakeLists.txt
deleted file mode 100644
index 3852b93d4..000000000
--- a/examples/webenginewidgets/markdowneditor/CMakeLists.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(markdowneditor LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/markdowneditor")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
-find_package(Qt6 COMPONENTS WebChannel)
-
-qt_add_executable(markdowneditor
- document.cpp document.h
- main.cpp
- mainwindow.cpp mainwindow.h mainwindow.ui
- previewpage.cpp previewpage.h
-)
-set_target_properties(markdowneditor PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(markdowneditor PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebChannel
- Qt::WebEngineWidgets
-)
-
-
-# Resources:
-set(markdowneditor_resource_files
- "resources/3rdparty/markdown.css"
- "resources/3rdparty/marked.js"
- "resources/default.md"
- "resources/index.html"
-)
-
-qt_add_resources(markdowneditor "markdowneditor"
- PREFIX
- "/"
- BASE
- "resources"
- FILES
- ${markdowneditor_resource_files}
-)
-
-install(TARGETS markdowneditor
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png b/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
deleted file mode 100644
index 9f456c4db..000000000
--- a/examples/webenginewidgets/markdowneditor/doc/images/markdowneditor-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
deleted file mode 100644
index 53464194c..000000000
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ /dev/null
@@ -1,183 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginewidgets/markdowneditor
- \title WebEngine 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 PreviewPage
-
- The constructor first calls \c setupUi to construct the widgets and menu
- actions according to the UI file. The text editor font is set to one
- with a fixed character width, and the QWebEngineView widget is told not
- to show a context menu.
-
- \printto connect
-
- Here the constructor 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 corresponding 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{https://bitbucket.org/kevinburke/markdowncss/src/master/}{markdown.css} is
- a markdown-friendly stylesheet created by Kevin Burke.
- \l{https://github.com/chjj/marked}{marked.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.
-
- \section1 Files and Attributions
-
- The example bundles the following code with third-party licenses:
-
- \table
- \row
- \li \l{markdowneditor-marked}{Marked}
- \li MIT License
- \row
- \li \l{markdowneditor-markdowncss}{Markdown.css}
- \li Apache License 2.0
- \endtable
-*/
-
diff --git a/examples/webenginewidgets/markdowneditor/document.cpp b/examples/webenginewidgets/markdowneditor/document.cpp
deleted file mode 100644
index 20e6b6be9..000000000
--- a/examples/webenginewidgets/markdowneditor/document.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
deleted file mode 100644
index 785ce228f..000000000
--- a/examples/webenginewidgets/markdowneditor/document.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 FINAL)
-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
deleted file mode 100644
index 059e9e64c..000000000
--- a/examples/webenginewidgets/markdowneditor/main.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- 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
deleted file mode 100644
index af5a6955b..000000000
--- a/examples/webenginewidgets/markdowneditor/mainwindow.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QFontDatabase>
-#include <QMessageBox>
-#include <QStatusBar>
-#include <QTextStream>
-#include <QWebChannel>
-
-MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
-{
- ui->setupUi(this);
- ui->editor->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
- ui->preview->setContextMenuPolicy(Qt::NoContextMenu);
-
- 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, &QWidget::close);
-
- 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;
-}
-
-void MainWindow::openFile(const QString &path)
-{
- 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());
- statusBar()->showMessage(tr("Opened %1").arg(QDir::toNativeSeparators(path)));
-}
-
-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;
- }
-
- QFileDialog dialog(this, tr("Open MarkDown File"));
- dialog.setMimeTypeFilters({"text/markdown"});
- dialog.setAcceptMode(QFileDialog::AcceptOpen);
- if (dialog.exec() == QDialog::Accepted)
- openFile(dialog.selectedFiles().constFirst());
-}
-
-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);
-
- statusBar()->showMessage(tr("Wrote %1").arg(QDir::toNativeSeparators(m_filePath)));
-}
-
-void MainWindow::onFileSaveAs()
-{
- QFileDialog dialog(this, tr("Save MarkDown File"));
- dialog.setMimeTypeFilters({"text/markdown"});
- dialog.setAcceptMode(QFileDialog::AcceptSave);
- dialog.setDefaultSuffix("md");
- if (dialog.exec() != QDialog::Accepted)
- return;
-
- m_filePath = dialog.selectedFiles().constFirst();
- onFileSave();
-}
-
-void MainWindow::closeEvent(QCloseEvent *e)
-{
- if (isModified()) {
- QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
- tr("You have unsaved changes. Do you want to exit anyway?"));
- if (button != QMessageBox::Yes)
- e->ignore();
- }
-}
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
deleted file mode 100644
index fc18dde29..000000000
--- a/examples/webenginewidgets/markdowneditor/mainwindow.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 = nullptr);
- ~MainWindow();
-
- void openFile(const QString &path);
-
-protected:
- void closeEvent(QCloseEvent *e) override;
-
-private slots:
- void onFileNew();
- void onFileOpen();
- void onFileSave();
- void onFileSaveAs();
-
-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
deleted file mode 100644
index 36ab352b7..000000000
--- a/examples/webenginewidgets/markdowneditor/mainwindow.ui
+++ /dev/null
@@ -1,115 +0,0 @@
-<?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
deleted file mode 100644
index 099edf4b5..000000000
--- a/examples/webenginewidgets/markdowneditor/markdowneditor.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-TEMPLATE = app
-
-QT += webenginewidgets webchannel
-
-HEADERS += \
- mainwindow.h \
- previewpage.h \
- document.h
-
-SOURCES = \
- main.cpp \
- mainwindow.cpp \
- previewpage.cpp \
- document.cpp
-
-RESOURCES = \
- resources/markdowneditor.qrc
-
-# Disable Qt Quick compiler because the example doesn't use QML, but more importantly so that
-# the source code of the .js files is not removed from the embedded qrc file.
-CONFIG -= qtquickcompiler
-
-FORMS += \
- mainwindow.ui
-
-DISTFILES += \
- resources/3rdparty/MARKDOWN-LICENSE.txt \
- resources/3rdparty/MARKED-LICENSE.txt
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/markdowneditor
-INSTALLS += target
diff --git a/examples/webenginewidgets/markdowneditor/previewpage.cpp b/examples/webenginewidgets/markdowneditor/previewpage.cpp
deleted file mode 100644
index 1d81d700c..000000000
--- a/examples/webenginewidgets/markdowneditor/previewpage.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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
deleted file mode 100644
index 2e7cfaeab..000000000
--- a/examples/webenginewidgets/markdowneditor/previewpage.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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:
- using QWebEnginePage::QWebEnginePage;
-
-protected:
- bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override;
-};
-
-#endif // PREVIEWPAGE_H
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt
deleted file mode 100644
index 23c52cc43..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Copyright 2011 Kevin Burke unless otherwise noted.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Some content is copyrighted by Twitter, Inc., and also released under an
-Apache License; these sections are noted in the source.
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt
deleted file mode 100644
index 8e3ba0e0a..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011-2018, 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/resources/3rdparty/markdown.css b/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css
deleted file mode 100644
index 24fc2ffe2..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css
+++ /dev/null
@@ -1,260 +0,0 @@
-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/3rdparty/marked.js b/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js
deleted file mode 100644
index 33c02d9cf..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.js
+++ /dev/null
@@ -1,1514 +0,0 @@
-/**
- * marked - a markdown parser
- * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/markedjs/marked
- */
-
-;(function(root) {
-'use strict';
-
-/**
- * Block-Level Grammar
- */
-
-var block = {
- newline: /^\n+/,
- code: /^( {4}[^\n]+\n*)+/,
- fences: noop,
- hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
- heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
- nptable: noop,
- blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
- list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
- html: '^ {0,3}(?:' // optional indentation
- + '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
- + '|comment[^\\n]*(\\n+|$)' // (2)
- + '|<\\?[\\s\\S]*?\\?>\\n*' // (3)
- + '|<![A-Z][\\s\\S]*?>\\n*' // (4)
- + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*' // (5)
- + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)' // (6)
- + '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) open tag
- + '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) closing tag
- + ')',
- def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
- table: noop,
- lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
- paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,
- text: /^[^\n]+/
-};
-
-block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
-block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
-block.def = edit(block.def)
- .replace('label', block._label)
- .replace('title', block._title)
- .getRegex();
-
-block.bullet = /(?:[*+-]|\d+\.)/;
-block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
-block.item = edit(block.item, 'gm')
- .replace(/bull/g, block.bullet)
- .getRegex();
-
-block.list = edit(block.list)
- .replace(/bull/g, block.bullet)
- .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
- .replace('def', '\\n+(?=' + block.def.source + ')')
- .getRegex();
-
-block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
- + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
- + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
- + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
- + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
- + '|track|ul';
-block._comment = /<!--(?!-?>)[\s\S]*?-->/;
-block.html = edit(block.html, 'i')
- .replace('comment', block._comment)
- .replace('tag', block._tag)
- .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
- .getRegex();
-
-block.paragraph = edit(block.paragraph)
- .replace('hr', block.hr)
- .replace('heading', block.heading)
- .replace('lheading', block.lheading)
- .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
- .getRegex();
-
-block.blockquote = edit(block.blockquote)
- .replace('paragraph', block.paragraph)
- .getRegex();
-
-/**
- * Normal Block Grammar
- */
-
-block.normal = merge({}, block);
-
-/**
- * GFM Block Grammar
- */
-
-block.gfm = merge({}, block.normal, {
- fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,
- paragraph: /^/,
- heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
-});
-
-block.gfm.paragraph = edit(block.paragraph)
- .replace('(?!', '(?!'
- + block.gfm.fences.source.replace('\\1', '\\2') + '|'
- + block.list.source.replace('\\1', '\\3') + '|')
- .getRegex();
-
-/**
- * GFM + Tables Block Grammar
- */
-
-block.tables = merge({}, block.gfm, {
- nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
- table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
-});
-
-/**
- * Pedantic grammar
- */
-
-block.pedantic = merge({}, block.normal, {
- html: edit(
- '^ *(?:comment *(?:\\n|\\s*$)'
- + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
- + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
- .replace('comment', block._comment)
- .replace(/tag/g, '(?!(?:'
- + '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')
- .getRegex(),
- def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/
-});
-
-/**
- * Block Lexer
- */
-
-function Lexer(options) {
- this.tokens = [];
- this.tokens.links = {};
- this.options = options || marked.defaults;
- this.rules = block.normal;
-
- if (this.options.pedantic) {
- this.rules = block.pedantic;
- } else if (this.options.gfm) {
- if (this.options.tables) {
- this.rules = block.tables;
- } else {
- this.rules = block.gfm;
- }
- }
-}
-
-/**
- * Expose Block Rules
- */
-
-Lexer.rules = block;
-
-/**
- * Static Lex Method
- */
-
-Lexer.lex = function(src, options) {
- var lexer = new Lexer(options);
- return lexer.lex(src);
-};
-
-/**
- * Preprocessing
- */
-
-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);
-};
-
-/**
- * Lexing
- */
-
-Lexer.prototype.token = function(src, top) {
- src = src.replace(/^ +$/gm, '');
- var next,
- loose,
- cap,
- bull,
- b,
- item,
- space,
- i,
- tag,
- l,
- isordered,
- istask,
- ischecked;
-
- while (src) {
- // newline
- if (cap = this.rules.newline.exec(src)) {
- src = src.substring(cap[0].length);
- if (cap[0].length > 1) {
- this.tokens.push({
- type: 'space'
- });
- }
- }
-
- // code
- 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;
- }
-
- // fences (gfm)
- 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;
- }
-
- // heading
- 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;
- }
-
- // table no leading pipe (gfm)
- if (top && (cap = this.rules.nptable.exec(src))) {
- item = {
- type: 'table',
- header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
- align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
- cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
- };
-
- if (item.header.length === item.align.length) {
- src = src.substring(cap[0].length);
-
- 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] = splitCells(item.cells[i], item.header.length);
- }
-
- this.tokens.push(item);
-
- continue;
- }
- }
-
- // hr
- if (cap = this.rules.hr.exec(src)) {
- src = src.substring(cap[0].length);
- this.tokens.push({
- type: 'hr'
- });
- continue;
- }
-
- // blockquote
- if (cap = this.rules.blockquote.exec(src)) {
- src = src.substring(cap[0].length);
-
- this.tokens.push({
- type: 'blockquote_start'
- });
-
- cap = cap[0].replace(/^ *> ?/gm, '');
-
- // Pass `top` to keep the current
- // "toplevel" state. This is exactly
- // how markdown.pl works.
- this.token(cap, top);
-
- this.tokens.push({
- type: 'blockquote_end'
- });
-
- continue;
- }
-
- // list
- if (cap = this.rules.list.exec(src)) {
- src = src.substring(cap[0].length);
- bull = cap[2];
- isordered = bull.length > 1;
-
- this.tokens.push({
- type: 'list_start',
- ordered: isordered,
- start: isordered ? +bull : ''
- });
-
- // Get each top-level item.
- cap = cap[0].match(this.rules.item);
-
- next = false;
- l = cap.length;
- i = 0;
-
- for (; i < l; i++) {
- item = cap[i];
-
- // Remove the list item's bullet
- // so it is seen as the next token.
- space = item.length;
- item = item.replace(/^ *([*+-]|\d+\.) +/, '');
-
- // Outdent whatever the
- // list item contains. Hacky.
- if (~item.indexOf('\n ')) {
- space -= item.length;
- item = !this.options.pedantic
- ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
- : item.replace(/^ {1,4}/gm, '');
- }
-
- // Determine whether the next list item belongs here.
- // Backpedal if it does not belong in this list.
- 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;
- }
- }
-
- // Determine whether item is loose or not.
- // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
- // for discount behavior.
- loose = next || /\n\n(?!\s*$)/.test(item);
- if (i !== l - 1) {
- next = item.charAt(item.length - 1) === '\n';
- if (!loose) loose = next;
- }
-
- // Check for task list items
- istask = /^\[[ xX]\] /.test(item);
- ischecked = undefined;
- if (istask) {
- ischecked = item[1] !== ' ';
- item = item.replace(/^\[[ xX]\] +/, '');
- }
-
- this.tokens.push({
- type: loose
- ? 'loose_item_start'
- : 'list_item_start',
- task: istask,
- checked: ischecked
- });
-
- // Recurse.
- this.token(item, false);
-
- this.tokens.push({
- type: 'list_item_end'
- });
- }
-
- this.tokens.push({
- type: 'list_end'
- });
-
- continue;
- }
-
- // html
- 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;
- }
-
- // def
- if (top && (cap = this.rules.def.exec(src))) {
- src = src.substring(cap[0].length);
- if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);
- tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
- if (!this.tokens.links[tag]) {
- this.tokens.links[tag] = {
- href: cap[2],
- title: cap[3]
- };
- }
- continue;
- }
-
- // table (gfm)
- if (top && (cap = this.rules.table.exec(src))) {
- item = {
- type: 'table',
- header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
- align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
- cells: cap[3] ? cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') : []
- };
-
- if (item.header.length === item.align.length) {
- src = src.substring(cap[0].length);
-
- 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] = splitCells(
- item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
- item.header.length);
- }
-
- this.tokens.push(item);
-
- continue;
- }
- }
-
- // lheading
- 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;
- }
-
- // top-level paragraph
- 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;
- }
-
- // text
- if (cap = this.rules.text.exec(src)) {
- // Top-level should never reach here.
- 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;
-};
-
-/**
- * Inline-Level Grammar
- */
-
-var inline = {
- escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
- autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
- url: noop,
- tag: '^comment'
- + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
- + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
- + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
- + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
- + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
- link: /^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,
- reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
- nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
- strong: /^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,
- em: /^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,
- code: /^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,
- br: /^ {2,}\n(?!\s*$)/,
- del: noop,
- text: /^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/
-};
-
-inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
-
-inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
-inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
-inline.autolink = edit(inline.autolink)
- .replace('scheme', inline._scheme)
- .replace('email', inline._email)
- .getRegex();
-
-inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
-
-inline.tag = edit(inline.tag)
- .replace('comment', block._comment)
- .replace('attribute', inline._attribute)
- .getRegex();
-
-inline._label = /(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/;
-inline._href = /\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/;
-inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
-
-inline.link = edit(inline.link)
- .replace('label', inline._label)
- .replace('href', inline._href)
- .replace('title', inline._title)
- .getRegex();
-
-inline.reflink = edit(inline.reflink)
- .replace('label', inline._label)
- .getRegex();
-
-/**
- * Normal Inline Grammar
- */
-
-inline.normal = merge({}, inline);
-
-/**
- * Pedantic Inline Grammar
- */
-
-inline.pedantic = merge({}, inline.normal, {
- strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
- em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
- link: edit(/^!?\[(label)\]\((.*?)\)/)
- .replace('label', inline._label)
- .getRegex(),
- reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
- .replace('label', inline._label)
- .getRegex()
-});
-
-/**
- * GFM Inline Grammar
- */
-
-inline.gfm = merge({}, inline.normal, {
- escape: edit(inline.escape).replace('])', '~|])').getRegex(),
- url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/)
- .replace('email', inline._email)
- .getRegex(),
- _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
- del: /^~~(?=\S)([\s\S]*?\S)~~/,
- text: edit(inline.text)
- .replace(']|', '~]|')
- .replace('|', '|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&\'*+/=?^_`{\\|}~-]+@|')
- .getRegex()
-});
-
-/**
- * GFM + Line Breaks Inline Grammar
- */
-
-inline.breaks = merge({}, inline.gfm, {
- br: edit(inline.br).replace('{2,}', '*').getRegex(),
- text: edit(inline.gfm.text).replace('{2,}', '*').getRegex()
-});
-
-/**
- * Inline Lexer & Compiler
- */
-
-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.pedantic) {
- this.rules = inline.pedantic;
- } else if (this.options.gfm) {
- if (this.options.breaks) {
- this.rules = inline.breaks;
- } else {
- this.rules = inline.gfm;
- }
- }
-}
-
-/**
- * Expose Inline Rules
- */
-
-InlineLexer.rules = inline;
-
-/**
- * Static Lexing/Compiling Method
- */
-
-InlineLexer.output = function(src, links, options) {
- var inline = new InlineLexer(links, options);
- return inline.output(src);
-};
-
-/**
- * Lexing/Compiling
- */
-
-InlineLexer.prototype.output = function(src) {
- var out = '',
- link,
- text,
- href,
- title,
- cap;
-
- while (src) {
- // escape
- if (cap = this.rules.escape.exec(src)) {
- src = src.substring(cap[0].length);
- out += cap[1];
- continue;
- }
-
- // autolink
- if (cap = this.rules.autolink.exec(src)) {
- src = src.substring(cap[0].length);
- if (cap[2] === '@') {
- text = escape(this.mangle(cap[1]));
- href = 'mailto:' + text;
- } else {
- text = escape(cap[1]);
- href = text;
- }
- out += this.renderer.link(href, null, text);
- continue;
- }
-
- // url (gfm)
- if (!this.inLink && (cap = this.rules.url.exec(src))) {
- cap[0] = this.rules._backpedal.exec(cap[0])[0];
- src = src.substring(cap[0].length);
- if (cap[2] === '@') {
- text = escape(cap[0]);
- href = 'mailto:' + text;
- } else {
- text = escape(cap[0]);
- if (cap[1] === 'www.') {
- href = 'http://' + text;
- } else {
- href = text;
- }
- }
- out += this.renderer.link(href, null, text);
- continue;
- }
-
- // tag
- 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;
- }
-
- // link
- if (cap = this.rules.link.exec(src)) {
- src = src.substring(cap[0].length);
- this.inLink = true;
- href = cap[2];
- if (this.options.pedantic) {
- link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
-
- if (link) {
- href = link[1];
- title = link[3];
- } else {
- title = '';
- }
- } else {
- title = cap[3] ? cap[3].slice(1, -1) : '';
- }
- href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
- out += this.outputLink(cap, {
- href: InlineLexer.escapes(href),
- title: InlineLexer.escapes(title)
- });
- this.inLink = false;
- continue;
- }
-
- // reflink, nolink
- 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;
- }
-
- // strong
- if (cap = this.rules.strong.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.strong(this.output(cap[4] || cap[3] || cap[2] || cap[1]));
- continue;
- }
-
- // em
- if (cap = this.rules.em.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.em(this.output(cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]));
- continue;
- }
-
- // code
- if (cap = this.rules.code.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.codespan(escape(cap[2].trim(), true));
- continue;
- }
-
- // br
- if (cap = this.rules.br.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.br();
- continue;
- }
-
- // del (gfm)
- if (cap = this.rules.del.exec(src)) {
- src = src.substring(cap[0].length);
- out += this.renderer.del(this.output(cap[1]));
- continue;
- }
-
- // text
- 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.escapes = function(text) {
- return text ? text.replace(InlineLexer.rules._escapes, '$1') : text;
-}
-
-/**
- * Compile Link
- */
-
-InlineLexer.prototype.outputLink = function(cap, link) {
- var href = 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]));
-};
-
-/**
- * Smartypants Transformations
- */
-
-InlineLexer.prototype.smartypants = function(text) {
- if (!this.options.smartypants) return text;
- return text
- // em-dashes
- .replace(/---/g, '\u2014')
- // en-dashes
- .replace(/--/g, '\u2013')
- // opening singles
- .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
- // closing singles & apostrophes
- .replace(/'/g, '\u2019')
- // opening doubles
- .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
- // closing doubles
- .replace(/"/g, '\u201d')
- // ellipses
- .replace(/\.{3}/g, '\u2026');
-};
-
-/**
- * Mangle Links
- */
-
-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() > 0.5) {
- ch = 'x' + ch.toString(16);
- }
- out += '&#' + ch + ';';
- }
-
- return out;
-};
-
-/**
- * Renderer
- */
-
-function Renderer(options) {
- this.options = options || marked.defaults;
-}
-
-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))
- + '</code></pre>';
- }
-
- return '<pre><code class="'
- + this.options.langPrefix
- + escape(lang, true)
- + '">'
- + (escaped ? code : escape(code, true))
- + '</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) {
- if (this.options.headerIds) {
- return '<h'
- + level
- + ' id="'
- + this.options.headerPrefix
- + raw.toLowerCase().replace(/[^\w]+/g, '-')
- + '">'
- + text
- + '</h'
- + level
- + '>\n';
- }
- // ignore IDs
- return '<h' + level + '>' + text + '</h' + level + '>\n';
-};
-
-Renderer.prototype.hr = function() {
- return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
-};
-
-Renderer.prototype.list = function(body, ordered, start) {
- var type = ordered ? 'ol' : 'ul',
- startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
- return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
-};
-
-Renderer.prototype.listitem = function(text) {
- return '<li>' + text + '</li>\n';
-};
-
-Renderer.prototype.checkbox = function(checked) {
- return '<input '
- + (checked ? 'checked="" ' : '')
- + 'disabled="" type="checkbox"'
- + (this.options.xhtml ? ' /' : '')
- + '> ';
-}
-
-Renderer.prototype.paragraph = function(text) {
- return '<p>' + text + '</p>\n';
-};
-
-Renderer.prototype.table = function(header, body) {
- if (body) body = '<tbody>' + body + '</tbody>';
-
- return '<table>\n'
- + '<thead>\n'
- + header
- + '</thead>\n'
- + body
- + '</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 + ' align="' + flags.align + '">'
- : '<' + type + '>';
- return tag + content + '</' + type + '>\n';
-};
-
-// span level renderer
-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 text;
- }
- if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
- return text;
- }
- }
- if (this.options.baseUrl && !originIndependentUrl.test(href)) {
- href = resolveUrl(this.options.baseUrl, href);
- }
- try {
- href = encodeURI(href).replace(/%25/g, '%');
- } catch (e) {
- return text;
- }
- var out = '<a href="' + escape(href) + '"';
- if (title) {
- out += ' title="' + title + '"';
- }
- out += '>' + text + '</a>';
- return out;
-};
-
-Renderer.prototype.image = function(href, title, text) {
- if (this.options.baseUrl && !originIndependentUrl.test(href)) {
- href = resolveUrl(this.options.baseUrl, href);
- }
- 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;
-};
-
-/**
- * TextRenderer
- * returns only the textual part of the token
- */
-
-function TextRenderer() {}
-
-// no need for block level renderers
-
-TextRenderer.prototype.strong =
-TextRenderer.prototype.em =
-TextRenderer.prototype.codespan =
-TextRenderer.prototype.del =
-TextRenderer.prototype.text = function (text) {
- return text;
-}
-
-TextRenderer.prototype.link =
-TextRenderer.prototype.image = function(href, title, text) {
- return '' + text;
-}
-
-TextRenderer.prototype.br = function() {
- return '';
-}
-
-/**
- * Parsing & Compiling
- */
-
-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;
-}
-
-/**
- * Static Parse Method
- */
-
-Parser.parse = function(src, options) {
- var parser = new Parser(options);
- return parser.parse(src);
-};
-
-/**
- * Parse Loop
- */
-
-Parser.prototype.parse = function(src) {
- this.inline = new InlineLexer(src.links, this.options);
- // use an InlineLexer with a TextRenderer to extract pure text
- this.inlineText = new InlineLexer(
- src.links,
- merge({}, this.options, {renderer: new TextRenderer()})
- );
- this.tokens = src.reverse();
-
- var out = '';
- while (this.next()) {
- out += this.tok();
- }
-
- return out;
-};
-
-/**
- * Next Token
- */
-
-Parser.prototype.next = function() {
- return this.token = this.tokens.pop();
-};
-
-/**
- * Preview Next Token
- */
-
-Parser.prototype.peek = function() {
- return this.tokens[this.tokens.length - 1] || 0;
-};
-
-/**
- * Parse Text Tokens
- */
-
-Parser.prototype.parseText = function() {
- var body = this.token.text;
-
- while (this.peek().type === 'text') {
- body += '\n' + this.next().text;
- }
-
- return this.inline.output(body);
-};
-
-/**
- * Parse Current Token
- */
-
-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,
- unescape(this.inlineText.output(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,
- j;
-
- // header
- cell = '';
- for (i = 0; i < this.token.header.length; 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': {
- body = '';
-
- while (this.next().type !== 'blockquote_end') {
- body += this.tok();
- }
-
- return this.renderer.blockquote(body);
- }
- case 'list_start': {
- body = '';
- var ordered = this.token.ordered,
- start = this.token.start;
-
- while (this.next().type !== 'list_end') {
- body += this.tok();
- }
-
- return this.renderer.list(body, ordered, start);
- }
- case 'list_item_start': {
- body = '';
-
- if (this.token.task) {
- body += this.renderer.checkbox(this.token.checked);
- }
-
- 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': {
- body = '';
-
- while (this.next().type !== 'list_item_end') {
- body += this.tok();
- }
-
- return this.renderer.listitem(body);
- }
- case 'html': {
- // TODO parse inline content if parameter markdown=1
- return this.renderer.html(this.token.text);
- }
- case 'paragraph': {
- return this.renderer.paragraph(this.inline.output(this.token.text));
- }
- case 'text': {
- return this.renderer.paragraph(this.parseText());
- }
- }
-};
-
-/**
- * Helpers
- */
-
-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) {
- // explicitly match decimal, hex, and named HTML entities
- return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, 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 edit(regex, opt) {
- regex = regex.source || regex;
- opt = opt || '';
- return {
- replace: function(name, val) {
- val = val.source || val;
- val = val.replace(/(^|[^\[])\^/g, '$1');
- regex = regex.replace(name, val);
- return this;
- },
- getRegex: function() {
- return new RegExp(regex, opt);
- }
- };
-}
-
-function resolveUrl(base, href) {
- if (!baseUrls[' ' + base]) {
- // we can ignore everything in base after the last slash of its path component,
- // but we might need to add _that_
- // https://tools.ietf.org/html/rfc3986#section-3
- if (/^[^:]+:\/*[^/]*$/.test(base)) {
- baseUrls[' ' + base] = base + '/';
- } else {
- baseUrls[' ' + base] = base.replace(/[^/]*$/, '');
- }
- }
- base = baseUrls[' ' + base];
-
- if (href.slice(0, 2) === '//') {
- return base.replace(/:[\s\S]*/, ':') + href;
- } else if (href.charAt(0) === '/') {
- return base.replace(/(:\/*[^/]*)[\s\S]*/, '$1') + href;
- } else {
- return base + href;
- }
-}
-var baseUrls = {};
-var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
-
-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 splitCells(tableRow, count) {
- var cells = tableRow.replace(/([^\\])\|/g, '$1 |').split(/ +\| */),
- i = 0;
-
- if (cells.length > count) {
- cells.splice(count);
- } else {
- while (cells.length < count) cells.push('');
- }
-
- for (; i < cells.length; i++) {
- cells[i] = cells[i].replace(/\\\|/g, '|');
- }
- return cells;
-}
-
-/**
- * Marked
- */
-
-function marked(src, opt, callback) {
- // throw error in case of non string input
- if (typeof src === 'undefined' || src === null) {
- throw new Error('marked(): input parameter is undefined or null');
- }
- if (typeof src !== 'string') {
- throw new Error('marked(): input parameter is of type '
- + Object.prototype.toString.call(src) + ', string expected');
- }
-
- 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/markedjs/marked.';
- if ((opt || marked.defaults).silent) {
- return '<p>An error occurred:</p><pre>'
- + escape(e.message + '', true)
- + '</pre>';
- }
- throw e;
- }
-}
-
-/**
- * Options
- */
-
-marked.options =
-marked.setOptions = function(opt) {
- merge(marked.defaults, opt);
- return marked;
-};
-
-marked.getDefaults = function () {
- return {
- baseUrl: null,
- breaks: false,
- gfm: true,
- headerIds: true,
- headerPrefix: '',
- highlight: null,
- langPrefix: 'language-',
- mangle: true,
- pedantic: false,
- renderer: new Renderer(),
- sanitize: false,
- sanitizer: null,
- silent: false,
- smartLists: false,
- smartypants: false,
- tables: true,
- xhtml: false
- };
-}
-
-marked.defaults = marked.getDefaults();
-
-/**
- * Expose
- */
-
-marked.Parser = Parser;
-marked.parser = Parser.parse;
-
-marked.Renderer = Renderer;
-marked.TextRenderer = TextRenderer;
-
-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 {
- root.marked = marked;
-}
-})(this || (typeof window !== 'undefined' ? window : global));
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json b/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json
deleted file mode 100644
index d51ac744b..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json
+++ /dev/null
@@ -1,34 +0,0 @@
-[
- {
- "Id": "markdowneditor-marked",
- "Name": "Marked (WebEngine Markdown Editor example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "Marked is used in the WebEngine MarkDown Editor example",
- "QtParts": [ "examples" ],
- "Files": "marked.js",
- "Description": "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
- "Homepage": "https://github.com/chjj/marked",
- "Version": "0.4.0",
- "DownloadLocation": "https://github.com/markedjs/marked/blob/0.4.0/lib/marked.js",
- "Copyright": "Copyright (c) 2011-2018, Christopher Jeffrey",
- "License": "MIT License",
- "LicenseId": "MIT",
- "LicenseFile": "MARKED-LICENSE.txt"
- },
- {
- "Id": "markdowneditor-markdowncss",
- "Name": "Markdown.css (WebEngine Markdown Editor example)",
- "QDocModule": "qtwebengine",
- "QtUsage": "markdown.css is used in the WebEngine MarkDown Editor example",
- "QtParts": [ "examples" ],
- "Files": "markdown.css",
- "Description": "Markdown.css is better default styling for your Markdown files.",
- "Version": "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
- "DownloadLocation": "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
- "Copyright": "Copyright 2011 Kevin Burke
- Copyright Twitter Inc.",
- "License": "Apache License 2.0",
- "LicenseId": "Apache-2.0",
- "LicenseFile": "MARKDOWN-LICENSE.txt"
- }
-]
diff --git a/examples/webenginewidgets/markdowneditor/resources/default.md b/examples/webenginewidgets/markdowneditor/resources/default.md
deleted file mode 100644
index af835fa4d..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/default.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## WebEngine 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](https://kevinburke.bitbucket.io/markdowncss/)
-was created by _Kevin Burke_.
diff --git a/examples/webenginewidgets/markdowneditor/resources/index.html b/examples/webenginewidgets/markdowneditor/resources/index.html
deleted file mode 100644
index 289a2110b..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/index.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!doctype html>
-<html lang="en">
-<meta charset="utf-8">
-<head>
- <link rel="stylesheet" type="text/css" href="3rdparty/markdown.css">
- <script src="3rdparty/marked.js"></script>
- <script src="qrc:/qtwebchannel/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/markdowneditor.qrc b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
deleted file mode 100644
index bc738f1cf..000000000
--- a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>default.md</file>
- <file>index.html</file>
- <file>3rdparty/markdown.css</file>
- <file>3rdparty/marked.js</file>
- </qresource>
-</RCC>
diff --git a/examples/webenginewidgets/minimal/CMakeLists.txt b/examples/webenginewidgets/minimal/CMakeLists.txt
deleted file mode 100644
index 6c8c44e98..000000000
--- a/examples/webenginewidgets/minimal/CMakeLists.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(minimal LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/minimal-widgets")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
-
-qt_add_executable(minimal-widgets
- main.cpp
-)
-set_target_properties(minimal-widgets PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(minimal-widgets PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineWidgets
-)
-
-install(TARGETS minimal-widgets
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/minimal/doc/images/minimal-example.png b/examples/webenginewidgets/minimal/doc/images/minimal-example.png
deleted file mode 100644
index 18ac9b177..000000000
--- a/examples/webenginewidgets/minimal/doc/images/minimal-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
deleted file mode 100644
index 9a0ee4593..000000000
--- a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginewidgets/minimal
- \title WebEngine Widgets Minimal Example
- \ingroup webengine-widgetexamples
- \brief Displays a web page using \QWE Widgets.
-
- \image minimal-example.png
-
- \e {WebEngine Widgets Minimal Example} demonstrates how to use
- \l{QWebEngineView} to render a web page. It shows the minimum amount of code
- needed to load and display an HTML page, and can be used as a basis for
- further experimentation.
-
- \include examples-run.qdocinc
-
- \section1 The Code
-
- We first define a \c commandLineUrlArgument function that returns the URL to open.
- This is either the first positional argument given on the command line, or
- \c https://www.qt.io as a fallback.
-
- \quotefromfile webenginewidgets/minimal/main.cpp
- \skipto #include
-
- \printto int main
-
- In the \c main function we first set the
- \l{QCoreApplication::organizationName} property. This affects the locations
- where \QWE stores persistent and cached data (see also
- \l{QWebEngineProfile::cachePath} and
- \l{QWebEngineProfile::persistentStoragePath}).
-
- Next, we instantiate a QApplication and a QWebEngineView. The URL
- to load is taken from \c commandLineUrlArgument and
- loaded by calling \l QWebEngineView::setUrl. The view widget is
- given a reasonable default size, and shown.
- Finally, QApplication::exec() launches the main event loop.
-
- \printuntil }
-
- \section1 Requirements
-
- The example requires a working internet connection to render
- the \l{Qt Homepage}.
- An optional system proxy should be picked up automatically.
- However, for proxies that require a username or password,
- you need to connect to
- QWebEnginePage::proxyAuthenticationRequired.
-
- \l{Qt WebEngine Widgets} uses the \l{Qt Quick Scene Graph} to compose the
- page. Therefore, OpenGL support is required.
-*/
diff --git a/examples/webenginewidgets/minimal/main.cpp b/examples/webenginewidgets/minimal/main.cpp
deleted file mode 100644
index a2c5e4873..000000000
--- a/examples/webenginewidgets/minimal/main.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QApplication>
-#include <QWebEngineView>
-
-QUrl commandLineUrlArgument()
-{
- const QStringList args = QCoreApplication::arguments();
- for (const QString &arg : args.mid(1)) {
- if (!arg.startsWith(QLatin1Char('-')))
- return QUrl::fromUserInput(arg);
- }
- return QUrl(QStringLiteral("https://www.qt.io"));
-}
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
- QApplication app(argc, argv);
-
- QWebEngineView view;
- view.setUrl(commandLineUrlArgument());
- view.resize(1024, 750);
- view.show();
-
- return app.exec();
-}
diff --git a/examples/webenginewidgets/notifications/CMakeLists.txt b/examples/webenginewidgets/notifications/CMakeLists.txt
index 6e152cf6c..8cca0ab31 100644
--- a/examples/webenginewidgets/notifications/CMakeLists.txt
+++ b/examples/webenginewidgets/notifications/CMakeLists.txt
@@ -1,37 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(notifications LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/notifications")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(notifications
main.cpp
notificationpopup.h
)
+
set_target_properties(notifications PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(notifications PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-
# Resources:
set(data_resource_files
"data/icon.png"
diff --git a/examples/webenginewidgets/notifications/doc/src/notifications.qdoc b/examples/webenginewidgets/notifications/doc/src/notifications.qdoc
index ec932f90c..f4fe1818f 100644
--- a/examples/webenginewidgets/notifications/doc/src/notifications.qdoc
+++ b/examples/webenginewidgets/notifications/doc/src/notifications.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/notifications
+ \examplecategory {Web Technologies}
\title WebEngine Notifications Example
\ingroup webengine-widgetexamples
\brief Demonstrates how to pass HTML5 web notifications to users.
diff --git a/examples/webenginewidgets/notifications/main.cpp b/examples/webenginewidgets/notifications/main.cpp
index 9a797376c..c754aff3f 100644
--- a/examples/webenginewidgets/notifications/main.cpp
+++ b/examples/webenginewidgets/notifications/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "notificationpopup.h"
diff --git a/examples/webenginewidgets/notifications/notificationpopup.h b/examples/webenginewidgets/notifications/notificationpopup.h
index d211c7996..57912f204 100644
--- a/examples/webenginewidgets/notifications/notificationpopup.h
+++ b/examples/webenginewidgets/notifications/notificationpopup.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#pragma once
diff --git a/examples/webenginewidgets/printme/CMakeLists.txt b/examples/webenginewidgets/printme/CMakeLists.txt
index ada0bf250..2d071903c 100644
--- a/examples/webenginewidgets/printme/CMakeLists.txt
+++ b/examples/webenginewidgets/printme/CMakeLists.txt
@@ -1,31 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(printme LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/printme")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
-find_package(Qt6 COMPONENTS PrintSupport)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui PrintSupport WebEngineWidgets)
qt_add_executable(printme
main.cpp
printhandler.cpp printhandler.h
)
+
set_target_properties(printme PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(printme PUBLIC
Qt::Core
Qt::Gui
@@ -33,10 +31,8 @@ target_link_libraries(printme PUBLIC
Qt::WebEngineWidgets
)
-
# Resources:
set(data_resource_files
- "data/icon.svg"
"data/index.html"
"data/style.css"
)
diff --git a/examples/webenginewidgets/printme/data/data.qrc b/examples/webenginewidgets/printme/data/data.qrc
index a9c76cc7e..b5e0b1fe0 100644
--- a/examples/webenginewidgets/printme/data/data.qrc
+++ b/examples/webenginewidgets/printme/data/data.qrc
@@ -2,6 +2,5 @@
<qresource prefix="/">
<file>index.html</file>
<file>style.css</file>
- <file>icon.svg</file>
</qresource>
</RCC>
diff --git a/examples/webenginewidgets/printme/data/icon.svg b/examples/webenginewidgets/printme/data/icon.svg
deleted file mode 100644
index b90ff26dd..000000000
--- a/examples/webenginewidgets/printme/data/icon.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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/printme/data/index.html b/examples/webenginewidgets/printme/data/index.html
index cf286e85a..865152c1d 100644
--- a/examples/webenginewidgets/printme/data/index.html
+++ b/examples/webenginewidgets/printme/data/index.html
@@ -12,13 +12,13 @@
</head>
<body>
<form class="form">
- <img class="logo" src="icon.svg" alt="qtwebengine">
<div class="header">
<h1>Hello Paper World!</h1>
<h2>Press Ctrl+p to print with print preview</h2>
<h2>Press Ctrl+Shift+p to print without print preview</h2>
<h2>Click the button to print using JavaScript</h2>
<p class="button" onclick="printNow()">Print Now</p>
+ </div>
</form>
</body>
</html>
diff --git a/examples/webenginewidgets/printme/data/style.css b/examples/webenginewidgets/printme/data/style.css
index cf6a2b7bf..af8b70fda 100644
--- a/examples/webenginewidgets/printme/data/style.css
+++ b/examples/webenginewidgets/printme/data/style.css
@@ -1,72 +1,74 @@
+@import url('https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap');
+* {
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+}
+
html,body {
- height:100%;
- width:100%;
- margin:0;
+ height: 100%;
+ width: 100%;
}
+
body {
- display:flex;
-}
- .logo {
- width: 75px;
- height: 75px;
- float: left;
- margin: 20px 20px 0px 20px;
- -webkit-animation:spin 8s linear infinite;
-}
- @-webkit-keyframes spin {
- 100% {
- -webkit-transform: rotate(360deg);
- }
+ display: flex;
}
+
.header {
display: inline
}
+
.form {
- width: 480px;
- height: 170px;
- background: -webkit-linear-gradient(bottom, #ddd, #fff);
- border: 1px solid #999;
- border-radius: 12px;
+ width: 50%;
+ background: #fff;
+ border: 0.5px solid #999;
+ border-radius: 8px;
color: #46a;
- font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
- font-size: 14px;
- font-style: italic;
- font-weight: bold;
+ font-family: 'Titillium Web', sans-serif;
+ font-size: 1rem;
margin: auto;
- padding: 10px;
+ padding: 1.5rem;
position: relative;
- line-height: 26px;
text-decoration: none;
- -webkit-box-shadow: 0px 0px 5px #444;
}
- h1 {
- padding-left:40px;
- color: #46a2da;
+
+h1 {
+ color: #00414A;
+ font-size: 2.5rem;
+ font-weight: 700;
+ margin-top: -0.85rem;
+ margin-bottom: 2rem;
}
- h2 {
- color: #80c342;
- font-size: 13px;
- margin-top: -20px;
-}
- span {
- margin-left: 20px;
+
+h2 {
+ color: #00414A;
+ font-size: 1.125rem;
+ font-weight: 400;
+ font-style: italic;
+ margin-bottom: 1rem;
}
+
.button{
- display: inline-block;
- background: #46a2da;
- width: 100px;
- height: 30px;
- padding: 0px;
- text-align: center;
- font-weight: bold;
- color: #ffffff;
- text-decoration: none;
- border: 1px solid #999;
- margin-left: 190px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0.4444em 0.8889em;
+ height: 2.4em;
+ cursor: pointer;
+ background: #00414A;
+ color: #fff;
+ border-radius: 4px;
+ margin-top: 2rem;
+ font-family: 'Titillium Web', sans-serif;
+ font-size: 1.125rem;
+ font-weight: 400;
+ transition: color 300ms ease-out, border 300ms ease-out;
}
+
.button:hover {
- background-color: #46a200
+ background: #19545C;
}
+
.button:active {
- background-color: #3e8e41;
+ background-color: #19545C;
}
diff --git a/examples/webenginewidgets/printme/doc/images/printme-example.png b/examples/webenginewidgets/printme/doc/images/printme-example.png
index a636972fd..dac4e61e6 100644
--- a/examples/webenginewidgets/printme/doc/images/printme-example.png
+++ b/examples/webenginewidgets/printme/doc/images/printme-example.png
Binary files differ
diff --git a/examples/webenginewidgets/printme/doc/src/printme.qdoc b/examples/webenginewidgets/printme/doc/src/printme.qdoc
index f17fae1a8..91aecf6de 100644
--- a/examples/webenginewidgets/printme/doc/src/printme.qdoc
+++ b/examples/webenginewidgets/printme/doc/src/printme.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \example webenginewidgets/printme
+ \example webenginewidgets/printme
+ \examplecategory {Web Technologies}
\title WebEngine Widgets PrintMe Example
\ingroup webengine-widgetexamples
\brief Demonstrates how to print web pages using Qt WebEngine Widgets.
@@ -78,9 +55,11 @@
Now we can implement the \c{PrintHandler::printDocument()} slot, which is
called in response to the \l{QPrintPreviewDialog::paintRequested} signal.
To do actual painting on a printer, we call the \l QWebEngineView::print()
- function. Because this call is asynchronous, we need to use
- a local event loop. We begin the local event loop by calling
- \l{QEventLoop::exec()}.
+ function. Printing is an async operation in Chromium, but not in Qt, so we
+ run a local event loop using \l{QEventLoop::exec()} to make sure printing
+ is done before returning. User input is blocked, since clicking on a button
+ while we're waiting for the print to finish can mess up the internal state
+ and cause a crash.
\quotefromfile webenginewidgets/printme/printhandler.cpp
\skipto PrintHandler::printDocument(
@@ -89,7 +68,8 @@
To get notified about the result of printing job, we implement
\c{PrintHandler::printFinished()} slot as handler of
\l QWebEngineView::printFinished() signal. We check for \c{success} and
- report any errors that occurred.
+ report any errors that occurred. Finally, we call \l{QEventLoop::quit()}
+ to exit out of the local event loop.
\quotefromfile webenginewidgets/printme/printhandler.cpp
\skipto PrintHandler::printFinished(
diff --git a/examples/webenginewidgets/printme/main.cpp b/examples/webenginewidgets/printme/main.cpp
index 588026eb2..46f44ccb6 100644
--- a/examples/webenginewidgets/printme/main.cpp
+++ b/examples/webenginewidgets/printme/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "printhandler.h"
#include <QApplication>
diff --git a/examples/webenginewidgets/printme/printhandler.cpp b/examples/webenginewidgets/printme/printhandler.cpp
index 283a6657c..9f8f6ee0b 100644
--- a/examples/webenginewidgets/printme/printhandler.cpp
+++ b/examples/webenginewidgets/printme/printhandler.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "printhandler.h"
#include <QPrintDialog>
@@ -79,7 +32,9 @@ void PrintHandler::print()
void PrintHandler::printDocument(QPrinter *printer)
{
m_view->print(printer);
- m_waitForResult.exec();
+ // User input in the print preview dialog while we're waiting on a print task
+ // can mess up the internal state and cause a crash.
+ m_waitForResult.exec(QEventLoop::ExcludeUserInputEvents);
}
void PrintHandler::printFinished(bool success)
diff --git a/examples/webenginewidgets/printme/printhandler.h b/examples/webenginewidgets/printme/printhandler.h
index ca5d0b03b..ab9a8c3a4 100644
--- a/examples/webenginewidgets/printme/printhandler.h
+++ b/examples/webenginewidgets/printme/printhandler.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PRINTHANDLER_H
#define PRINTHANDLER_H
diff --git a/examples/webenginewidgets/push-notifications/CMakeLists.txt b/examples/webenginewidgets/push-notifications/CMakeLists.txt
new file mode 100644
index 000000000..3328c2ce9
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/CMakeLists.txt
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(notifications LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/push-notifications")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
+
+qt_add_executable(push-notifications
+ main.cpp
+ notificationpopup.h
+)
+
+set_target_properties(push-notifications PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(push-notifications PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+)
+
+qt_add_resources(push-notifications "data"
+ PREFIX
+ "/"
+ BASE
+ "data"
+ FILES
+ "data/icon.png"
+)
+
+install(TARGETS push-notifications
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/webenginewidgets/push-notifications/content/index.html b/examples/webenginewidgets/push-notifications/content/index.html
new file mode 100644
index 000000000..cce3055cd
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/index.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Push Notification Using Node and FCM</title>
+ <link rel="stylesheet" href="style.css">
+</head>
+<body>
+ <h1>Push Notification Using NodeJS and QtWebEngine</h1>
+ <div id="app">
+ <div id="ping-setup">
+ <form>
+ <div>
+ Ping Me Every [sec]:
+ </div>
+ <div class="ping-input">
+ <input type="number" name="seconds" min="0" max="3600" required="">
+ </div><button>Ping Me</button>
+ </form>
+ </div>
+ <div id="ping-clear">
+ <div id="ping-text"></div><button id="ping-clear-button">Clear</button>
+ </div>
+ </div>
+ <script src="ping.js"></script>
+</body>
+</html>
diff --git a/examples/webenginewidgets/push-notifications/content/ping.js b/examples/webenginewidgets/push-notifications/content/ping.js
new file mode 100644
index 000000000..285a57019
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/ping.js
@@ -0,0 +1,84 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+const publicVapidKey =
+ "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg";
+
+async function setup(delay)
+{
+ console.log('>> register service worker...');
+ const register = await navigator.serviceWorker.register('/worker.js', { scope : '/' });
+ console.log('>> service worker registered...');
+
+ console.log('>> subscribe push subscription to FCM');
+ var subscription = await register.pushManager.subscribe(
+ { userVisibleOnly : true, applicationServerKey : publicVapidKey });
+ console.log('>> subscription created...');
+
+ console.log('>> subscribe to push service...');
+ await fetch('/subscribe', {
+ method : 'POST',
+ body : JSON.stringify(subscription),
+ headers : { 'content-type' : 'application/json', 'ping-time' : delay }
+ });
+ console.log('>> push subscription created...')
+}
+
+async function clear()
+{
+ const register = await navigator.serviceWorker.getRegistration();
+ var subscription = await register.pushManager.getSubscription();
+ console.log('>> unsubscribe to push service...');
+ await fetch('/unsubscribe', {
+ method : 'POST',
+ body : JSON.stringify(subscription),
+ headers : { 'content-type' : 'application/json' }
+ });
+ console.log('>> push unsubscription removed...')
+
+ console.log('>> unsubscribe push subscription to FCM');
+ await subscription.unsubscribe();
+ console.log('>> subscription removed...');
+}
+
+function displaySetup(delay = null)
+{
+ const pingSetup = document.getElementById('ping-setup');
+ const pingClear = document.getElementById('ping-clear');
+ const pingText = document.getElementById('ping-text');
+ if (delay) {
+ pingClear.style.display = 'block';
+ pingSetup.style.display = 'none';
+ pingText.innerHTML = 'Ping Me Every ' + delay + ' seconds';
+ } else {
+ pingClear.style.display = 'none';
+ pingSetup.style.display = 'block';
+ pingText.innerHTML = "";
+ }
+}
+
+function handleSetupPing(event)
+{
+ event.preventDefault();
+
+ const seconds = document.forms[0].seconds.value;
+ document.forms[0].reset();
+
+ // check for service worker support
+ if ('serviceWorker' in navigator) {
+ setup(seconds).catch(err => console.error(err));
+ }
+
+ displaySetup(seconds);
+};
+
+function handleClearPing(event)
+{
+ event.preventDefault();
+ clear();
+ displaySetup();
+};
+
+document.forms[0].addEventListener('submit', handleSetupPing);
+const clearButton = document.getElementById('ping-clear-button');
+clearButton.addEventListener('click', handleClearPing);
diff --git a/examples/webenginewidgets/push-notifications/content/style.css b/examples/webenginewidgets/push-notifications/content/style.css
new file mode 100644
index 000000000..8176462a2
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/style.css
@@ -0,0 +1,29 @@
+body {
+ font-family: monaco;
+ height: 100vh;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ display: flex;
+}
+#ping-clear,
+#ping-setup {
+ font-size: 32px;
+ text-align: center;
+}
+.form-inputs{
+ margin-top: 20px;
+}
+input {
+ width: 100px;
+ height: 30px;
+}
+button {
+ font-size: 16px;
+}
+#ping-text {
+ margin-bottom: 30px;
+}
+#ping-clear {
+ display: none;
+}
diff --git a/examples/webenginewidgets/push-notifications/content/worker.js b/examples/webenginewidgets/push-notifications/content/worker.js
new file mode 100644
index 000000000..ed660a6e9
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/content/worker.js
@@ -0,0 +1,7 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+self.addEventListener('push', event => {
+ const data = event.data.json();
+ self.registration.showNotification(data.title, { body : data.text });
+});
diff --git a/examples/webenginewidgets/webui/webui.qrc b/examples/webenginewidgets/push-notifications/data/data.qrc
index 6ddf01fa2..619648d1b 100644
--- a/examples/webenginewidgets/webui/webui.qrc
+++ b/examples/webenginewidgets/push-notifications/data/data.qrc
@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/">
- <file>about.html</file>
+ <file>icon.png</file>
</qresource>
</RCC>
diff --git a/examples/webenginewidgets/push-notifications/data/icon.png b/examples/webenginewidgets/push-notifications/data/icon.png
new file mode 100644
index 000000000..4c3870c06
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/data/icon.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/notification.png b/examples/webenginewidgets/push-notifications/doc/images/notification.png
new file mode 100644
index 000000000..ec5c67457
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/notification.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/permissions.png b/examples/webenginewidgets/push-notifications/doc/images/permissions.png
new file mode 100644
index 000000000..dedb6e472
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/permissions.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png b/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png
new file mode 100644
index 000000000..c5ba5f589
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/push-notifications.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/images/website.png b/examples/webenginewidgets/push-notifications/doc/images/website.png
new file mode 100644
index 000000000..10a4a6150
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/images/website.png
Binary files differ
diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc
new file mode 100644
index 000000000..05ccf3e8b
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc
@@ -0,0 +1,203 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+
+\example webenginewidgets/push-notifications
+\examplecategory {Web Technologies}
+\title WebEngine Push Notifications Example
+\ingroup webengine-widgetexamples
+\brief Demonstrates how to subscribe to and unsubscribe from push notifications.
+
+In this example we are going to send push notifications from a web push service to the user.
+This is the typical scenario where messages are sent from the application server i.e. website
+back-end through a 3rd-party push service, to finally arrive at the user's browser in form of
+notifications. To demonstrate this flow, we will implement a simple push service server
+application, to which the user can subscribe to receive \e ping messages.
+
+As already mentioned, in such a workflow there are three different parties involved:
+
+\list
+ \li the user's web browser where they receive push notifications
+ \li 3rd-party push service, which is defined by a subscription endpoint and is a part
+ of a browser's push service implementation
+ \li application server, which will store user's subscriptions and initiate push messages
+ using a subscription endpoint
+\endlist
+
+The user visits a website, where a JavaScript web application uses the JavaScript Push API
+to create a push notification subscription. The user is then asked to grant a permission
+to receive and display push notifications. Once accepted, the Push API establishes a push channel
+with a 3rd-party push service, which in case of QtWebEngine is \l {https://firebase.google.com}
+{Firebase Cloud Messaging (FCM)}. The unique push subscription is created that
+includes the subscription endpoint URL. The browser then sends a subscription message
+to the application server forwarding the endpoint setup. The application server can now
+use the subscription endpoint to send notifications to the browser. The browser push service
+implementation will deliver a push message. However, to show it, a service worker must
+be registered. As the service worker runs in the background, it allows displaying notifications
+even if a website, which has installed it, is no longer opened.
+
+\image push-notifications.png
+
+Let's go more into implementation details. We start with implementing our custom
+push service using NodeJS with two modules:
+
+\list
+ \li \l {https://github.com/web-push-libs/web-push} {web-push} - provides the web-push protocol
+ implementation
+ \li \l {https://github.com/expressjs/express} {express} - provides the web application framework
+\endlist
+
+Let's initialize a new project and install the required modules in the root directory of this
+example:
+
+\snippet /push-notifications/commands 0
+
+These commands should create package.js, which defines the start command:
+
+\snippet /push-notifications/commands 1
+
+Now let's move on to the push service back-end implementation in server.js.
+
+We start by including the required modules and doing basic \e express framework setup, which
+we use to create our custom push server. For simplicity we are going to handle only one
+subscription at a time. To do that we need to create \e VAPID keys which we are going to
+generate with \e web-push libs. The public key is going to be used by the front-end and authenticate
+to the service.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto const express
+\printto add subscribe route
+
+\note We are not going to cover the encryption of messages in this example.
+
+To generate keys, we can use the tool shipped with \e web-push lib, that is installed by
+\c npm in our example's root directory.
+
+\snippet /push-notifications/commands 2
+
+Now we add two \c routes to the push server. One to \c subscribe and one to \c unsubscribe,
+so that our front-end can send an HTTP POST request to handle the push subscription.
+In the subscribe request we will get \c subscription in the request body and we also retrieve
+the custom header \c ping-time that defines how often the ping messages should be pushed to
+the user. We keep around the \c subscription to be able to send push notifications later.
+As a confirmation, we send the 201 status code and schedule the first push notification based on
+the \c ping-time value. The \c unsubscribe request simply removes a subscription.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto add subscribe route
+\printto function sendNotification
+
+The \c sendNotication() function sends push messages using the web-push lib. We create the payload
+with the message we want to present to a user and schedule the next push message.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto function sendNotification
+\printto server.listen
+
+In the end we start the server to listen on the given port.
+
+\quotefromfile webenginewidgets/push-notifications/server.js
+\skipto server.listen
+\printline started
+
+Let's move now to our front-end. We create a simple page index.html, where the user can enter how
+often they want to receive ping notification messages. We will have two buttons:
+\e {Ping Me} to subscribe for push notifications and \e Clear to unsubscribe.
+In the end we load ping.js, which we cover next.
+
+\quotefromfile webenginewidgets/push-notifications/content/index.html
+\skipto <body>
+\printuntil </body>
+
+The last piece is creating the logic for the push subscription within the front-end. Here we have two
+functions, \c setup and \c clear, to handle subscriptions. When the user clicks on the \e {Ping Me}
+button, \c setup is called. To be able to receive notifications, the service worker is needed.
+This way the user can leave the website and still get notified as the service worker works
+in the background and handles incoming messages. To achieve that, we have to first register
+one with:
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipto const register
+\printline worker.js
+
+The call to \c cpushManager.subscribe() will trigger a permission prompt, which is displayed to the
+user. If the permission is granted, the push subscription is returned. It includes a URL endpoint
+that allows sending notifications to the browser, where the registered service worker waits for
+push messages.
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipto var subscription
+\printto console.log
+
+As mentioned the subscription is created for FCM and should be now sent to our custom server
+with an HTTP POST request. In addition, we add to the post request the HTTP header with the
+\c ping-time the user entered on our website.
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipto await fetch
+\printto console.log
+
+The function \c clear call unsubscribes first from our push server by sending an HTTP POST request
+and later from the 3rd-party push service (FCM).
+
+\quotefromfile webenginewidgets/push-notifications/content/ping.js
+\skipuntil async function clear()
+\skipuntil {
+\printto console.log
+\dots
+\skipto await fetch
+\printto console.log
+\dots
+\skipto await subscription
+\printto console.log
+
+The rest of code in ping.js is just boilerplate code to read a user provided value
+and call \c setup() or \c clear().
+
+As the last part of the front-end let's look inside a service worker script, where we simply
+register an event listener for \e push events.
+
+\quotefromfile webenginewidgets/push-notifications/content/worker.js
+\skipto self
+\printuntil });
+\printuntil });
+
+When a push event comes we simply use the Notification JavaScript API to display a notification.
+
+\note QtWebEngine Notification Example shows how to provide your own handler and customize
+the look and feel of a notification message.
+
+Having the implementation in place, we can start the server on localhost at the port 5000.
+To do that, we can simply enter in the console in the project's root directory:
+
+\snippet /push-notifications/commands 3
+
+Now we can look into the \e push-notification browser application, which is based on
+\l {WebEngine Notifications Example}:
+
+\quotefromfile webenginewidgets/push-notifications/main.cpp
+\skipto main
+\printuntil app.exec
+\printuntil }
+
+This application simply opens the page at \c http:\\localhost:5000. We are not going into detail
+about how to open a notification as it is documented \l {WebEngine Notifications Example}{here}.
+However, you need to modify the application in two ways. First, \c QWebEngineProfile cannot be
+set to \e off-the-record because push messaging would be disabled. Therefore, as you can see
+above, \c QWebEngineProfile is initialized with the name. Second, you need to enable push
+messaging with the call QWebEngineProfile::setPushServiceEnabled for the created \c profile.
+
+When the application runs it displays:
+
+\image website.png
+
+After granting the permission we can send our ping request:
+
+\image permissions.png
+
+We should see the coming push notification:
+
+\image notification.png
+
+*/
diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel
new file mode 100644
index 000000000..048a55911
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qmodel
@@ -0,0 +1,837 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<qmt>
+ <project>
+ <uid>{9fd14f7e-7b67-4e13-9980-ef8fbe24b780}</uid>
+ <root-package>
+ <instance>
+ <MPackage>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{a26e0efd-1b21-4fba-96ce-a607bbcdb4f7}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push_notifications</name>
+ <children>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{6b1a06e9-960b-4a10-872e-5504d8c0b127}</uid>
+ <target>
+ <instance type="MCanvasDiagram">
+ <MCanvasDiagram>
+ <base-MDiagram>
+ <MDiagram>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{6b1a06e9-960b-4a10-872e-5504d8c0b127}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push_notifications</name>
+ </MObject>
+ </base-MObject>
+ <elements>
+ <qlist>
+ <item>
+ <instance type="DBoundary">
+ <DBoundary>
+ <base-DElement>
+ <DElement>
+ <uid>{d50762f2-c7f4-4d52-9592-8bcc07274ba1}</uid>
+ </DElement>
+ </base-DElement>
+ <text>Browser / User Agent</text>
+ <pos>x:415;y:390</pos>
+ <rect>x:-105;y:-125;w:210;h:250</rect>
+ </DBoundary>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{121189af-36df-4efa-b451-3f1f85ef339f}</object>
+ <name>JavaScript Web Application</name>
+ <pos>x:410;y:395</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{8bde1815-304a-41f6-8528-c754dc3d1eda}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{13c69399-5587-4169-a012-8d86216139fd}</object>
+ <name>Push Manager API</name>
+ <pos>x:410;y:320</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</object>
+ <name>Service Worker</name>
+ <pos>x:410;y:470</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{0a7b0146-d34b-4c39-a1af-df15a1b4108d}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d}</object>
+ <a>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</a>
+ <b>{8bde1815-304a-41f6-8528-c754dc3d1eda}</b>
+ <name>subscribe</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{e7d4a675-ddbd-41aa-a802-32221a56dae2}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{afae2401-ea81-4514-aa80-da53d61a8516}</object>
+ <a>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</a>
+ <b>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</b>
+ <name>register</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{998e7d36-3416-4b2f-843a-a437449f09f1}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</object>
+ <name>Firebase Cloud Messaging </name>
+ <pos>x:770;y:320</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <visual-role>6</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{28c1fccd-c50e-458c-865d-4ba41d55690b}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{d9959769-74a4-40ad-bf00-904c12a67309}</object>
+ <a>{8bde1815-304a-41f6-8528-c754dc3d1eda}</a>
+ <b>{998e7d36-3416-4b2f-843a-a437449f09f1}</b>
+ <name>create subscription</name>
+ </DRelation>
+ </base-DRelation>
+ <direction>2</direction>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{ba581e41-cc00-4129-adae-0a1208bb3222}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</object>
+ <name>Push Application Server</name>
+ <pos>x:770;y:390</pos>
+ <rect>x:-75;y:-15;w:150;h:30</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>6</visual-role>
+ </DObject>
+ </base-DObject>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{e796d1cc-f574-45db-a440-7e47d7560d71}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{373c492c-0b9a-4032-9ff4-b3a7cc442883}</object>
+ <a>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</a>
+ <b>{ba581e41-cc00-4129-adae-0a1208bb3222}</b>
+ <name>subscribe with endpoint</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{6332f8ae-ef9d-4c15-9fbf-d6ee06ba3f84}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{94241d64-4e88-4855-8e78-365be237108b}</object>
+ <a>{ba581e41-cc00-4129-adae-0a1208bb3222}</a>
+ <b>{998e7d36-3416-4b2f-843a-a437449f09f1}</b>
+ <name>push notification</name>
+ <points>
+ <qlist>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:770;y:335</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ </qlist>
+ </points>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DItem">
+ <DItem>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{582af542-5f2d-4660-a6d0-a3bd983d9682}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{00b8f12d-e08b-426a-83b8-83fea8907fab}</object>
+ <name>User</name>
+ <pos>x:185;y:395</pos>
+ <rect>x:-10;y:-20;w:20;h:40</rect>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ <variety>actor</variety>
+ <shape-editable>false</shape-editable>
+ </DItem>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{66ca12e1-84a1-4247-82e5-ae6891f3f376}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{6d0ce78f-28e1-4a82-a443-59f4efcb8e66}</object>
+ <a>{582af542-5f2d-4660-a6d0-a3bd983d9682}</a>
+ <b>{cc80cad6-2e47-4913-aeb1-0c6f41de44bb}</b>
+ <name>subscribe</name>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{7657479a-a855-4d97-8c61-098690da9023}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{eef542f5-e2cf-40a8-92c9-9892f3d06e1f}</object>
+ <a>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</a>
+ <b>{582af542-5f2d-4660-a6d0-a3bd983d9682}</b>
+ <name>notify</name>
+ <points>
+ <qlist>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:340;y:430</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ </qlist>
+ </points>
+ </DRelation>
+ </base-DRelation>
+ </DDependency>
+ </instance>
+ </item>
+ <item>
+ <instance type="DDependency">
+ <DDependency>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{97f3e5b0-93ca-4351-98d6-ad88567979f7}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{963ad9f9-ecad-430f-8233-b7897fa630bd}</object>
+ <a>{75431119-9e8e-4e3e-a539-9d7bad6dbf81}</a>
+ <b>{998e7d36-3416-4b2f-843a-a437449f09f1}</b>
+ <name>push notification</name>
+ <points>
+ <qlist>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:535;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:590;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:615;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:670;y:470</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ <item>
+ <DRelation--IntermediatePoint>
+ <pos>x:670;y:365</pos>
+ </DRelation--IntermediatePoint>
+ </item>
+ </qlist>
+ </points>
+ </DRelation>
+ </base-DRelation>
+ <direction>1</direction>
+ </DDependency>
+ </instance>
+ </item>
+ </qlist>
+ </elements>
+ <last-modified>1665083804306</last-modified>
+ <toolbarid>UseCases</toolbarid>
+ </MDiagram>
+ </base-MDiagram>
+ </MCanvasDiagram>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{121189af-36df-4efa-b451-3f1f85ef339f}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{121189af-36df-4efa-b451-3f1f85ef339f}</uid>
+ </MElement>
+ </base-MElement>
+ <name>JavaScript Web Application</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{648fd8d0-6f61-4cc9-b5ce-6c5b9057fe5d}</uid>
+ </MElement>
+ </base-MElement>
+ <name>subscribe</name>
+ <a>{121189af-36df-4efa-b451-3f1f85ef339f}</a>
+ <b>{13c69399-5587-4169-a012-8d86216139fd}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{afae2401-ea81-4514-aa80-da53d61a8516}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{afae2401-ea81-4514-aa80-da53d61a8516}</uid>
+ </MElement>
+ </base-MElement>
+ <name>register</name>
+ <a>{121189af-36df-4efa-b451-3f1f85ef339f}</a>
+ <b>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{373c492c-0b9a-4032-9ff4-b3a7cc442883}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{373c492c-0b9a-4032-9ff4-b3a7cc442883}</uid>
+ </MElement>
+ </base-MElement>
+ <name>subscribe with endpoint</name>
+ <a>{121189af-36df-4efa-b451-3f1f85ef339f}</a>
+ <b>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{13c69399-5587-4169-a012-8d86216139fd}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{13c69399-5587-4169-a012-8d86216139fd}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Push Manager API</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{d9959769-74a4-40ad-bf00-904c12a67309}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{d9959769-74a4-40ad-bf00-904c12a67309}</uid>
+ </MElement>
+ </base-MElement>
+ <name>create subscription</name>
+ <a>{13c69399-5587-4169-a012-8d86216139fd}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ <direction>2</direction>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Service Worker</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{bfebbc32-3541-4c1a-b3c6-a3652f700767}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{bfebbc32-3541-4c1a-b3c6-a3652f700767}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push notification</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ <direction>1</direction>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{89d5f886-1913-4bb7-be32-cdd5cb61eebc}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{89d5f886-1913-4bb7-be32-cdd5cb61eebc}</uid>
+ </MElement>
+ </base-MElement>
+ <name>notify</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{00b8f12d-e08b-426a-83b8-83fea8907fab}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{eef542f5-e2cf-40a8-92c9-9892f3d06e1f}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{eef542f5-e2cf-40a8-92c9-9892f3d06e1f}</uid>
+ </MElement>
+ </base-MElement>
+ <name>notify</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{00b8f12d-e08b-426a-83b8-83fea8907fab}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{963ad9f9-ecad-430f-8233-b7897fa630bd}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{963ad9f9-ecad-430f-8233-b7897fa630bd}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push notification</name>
+ <a>{3f1676be-d3a4-4751-8bcb-400b11c88ada}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ <direction>1</direction>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Firebase Cloud Messaging </name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{560fb941-261e-4f45-8909-2106283fdb3e}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{560fb941-261e-4f45-8909-2106283fdb3e}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</a>
+ <b>{13c69399-5587-4169-a012-8d86216139fd}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</uid>
+ </MElement>
+ </base-MElement>
+ <name>Push Application Server</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{94241d64-4e88-4855-8e78-365be237108b}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{94241d64-4e88-4855-8e78-365be237108b}</uid>
+ </MElement>
+ </base-MElement>
+ <name>push notification</name>
+ <a>{13d79379-1727-46a3-947c-e3f2f6eb3a87}</a>
+ <b>{5a7b90ea-801e-43ea-a0b5-edaa59761b5b}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{00b8f12d-e08b-426a-83b8-83fea8907fab}</uid>
+ <target>
+ <instance type="MItem">
+ <MItem>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{00b8f12d-e08b-426a-83b8-83fea8907fab}</uid>
+ </MElement>
+ </base-MElement>
+ <name>User</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{6d0ce78f-28e1-4a82-a443-59f4efcb8e66}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{6d0ce78f-28e1-4a82-a443-59f4efcb8e66}</uid>
+ </MElement>
+ </base-MElement>
+ <name>subscribe</name>
+ <a>{00b8f12d-e08b-426a-83b8-83fea8907fab}</a>
+ <b>{121189af-36df-4efa-b451-3f1f85ef339f}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ <variety-editable>false</variety-editable>
+ <variety>actor</variety>
+ </MItem>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </children>
+ </MObject>
+ </base-MObject>
+ </MPackage>
+ </instance>
+ </root-package>
+ </project>
+</qmt>
diff --git a/examples/webenginewidgets/push-notifications/main.cpp b/examples/webenginewidgets/push-notifications/main.cpp
new file mode 100644
index 000000000..18a862182
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/main.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "notificationpopup.h"
+
+#include <QApplication>
+#include <QWebEngineProfile>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QApplication app(argc, argv);
+
+ const QString name =
+ QString::fromLatin1("push-notifications.%1").arg(qWebEngineChromiumVersion());
+
+ QScopedPointer<QWebEngineProfile> profile(new QWebEngineProfile(name));
+ QWebEngineView view(profile.data());
+ auto popup = new NotificationPopup(&view);
+
+ QObject::connect(view.page(), &QWebEnginePage::featurePermissionRequested,
+ [&](const QUrl &origin, QWebEnginePage::Feature feature) {
+ if (feature != QWebEnginePage::Notifications)
+ return;
+
+ view.page()->setFeaturePermission(origin, feature,
+ QWebEnginePage::PermissionGrantedByUser);
+ });
+
+ profile->setPushServiceEnabled(true);
+ profile->setNotificationPresenter([&](std::unique_ptr<QWebEngineNotification> notification) {
+ popup->present(notification);
+ });
+
+ view.resize(640, 480);
+ view.setUrl(QUrl("http://localhost:5000"));
+ view.show();
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/push-notifications/notificationpopup.h b/examples/webenginewidgets/push-notifications/notificationpopup.h
new file mode 100644
index 000000000..cf53ded45
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/notificationpopup.h
@@ -0,0 +1,91 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#pragma once
+
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QMouseEvent>
+#include <QPushButton>
+#include <QSpacerItem>
+#include <QTimer>
+#include <QVBoxLayout>
+#include <QWebEngineNotification>
+
+#include <memory>
+
+class NotificationPopup : public QWidget
+{
+ Q_OBJECT
+
+ QLabel m_icon, m_title, m_message;
+ std::unique_ptr<QWebEngineNotification> notification;
+
+public:
+ NotificationPopup(QWidget *parent) : QWidget(parent)
+ {
+ setWindowFlags(Qt::ToolTip);
+ auto rootLayout = new QHBoxLayout(this);
+
+ rootLayout->addWidget(&m_icon);
+
+ auto bodyLayout = new QVBoxLayout;
+ rootLayout->addLayout(bodyLayout);
+
+ auto titleLayout = new QHBoxLayout;
+ bodyLayout->addLayout(titleLayout);
+
+ titleLayout->addWidget(&m_title);
+ titleLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
+
+ auto close = new QPushButton(tr("Close"));
+ titleLayout->addWidget(close);
+ connect(close, &QPushButton::clicked, this, &NotificationPopup::onClosed);
+
+ bodyLayout->addWidget(&m_message);
+ adjustSize();
+ }
+
+ void present(std::unique_ptr<QWebEngineNotification> &newNotification)
+ {
+ if (notification) {
+ notification->close();
+ notification.reset();
+ }
+
+ notification.swap(newNotification);
+
+ m_title.setText("<b>" + notification->title() + "</b>");
+ m_message.setText(notification->message());
+ m_icon.setPixmap(QPixmap(":/icon.png").scaledToHeight(m_icon.height()));
+
+ show();
+ notification->show();
+
+ connect(notification.get(), &QWebEngineNotification::closed, this,
+ &NotificationPopup::onClosed);
+ QTimer::singleShot(10000, notification.get(), [&]() { onClosed(); });
+
+ // position our popup in the right corner of its parent widget
+ move(parentWidget()->mapToGlobal(parentWidget()->rect().bottomRight()
+ - QPoint(width() + 10, height() + 10)));
+ }
+
+protected slots:
+ void onClosed()
+ {
+ hide();
+ notification->close();
+ notification.reset();
+ }
+
+protected:
+ void mouseReleaseEvent(QMouseEvent *event) override
+ {
+ QWidget::mouseReleaseEvent(event);
+ if (notification && event->button() == Qt::LeftButton) {
+ notification->click();
+ onClosed();
+ }
+ }
+};
diff --git a/examples/webenginewidgets/push-notifications/push-notifications.pro b/examples/webenginewidgets/push-notifications/push-notifications.pro
new file mode 100644
index 000000000..5ffb85fd7
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/push-notifications.pro
@@ -0,0 +1,10 @@
+QT += webenginewidgets
+
+HEADERS = notificationpopup.h
+
+SOURCES = main.cpp
+
+RESOURCES = data/data.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/push-notifications
+INSTALLS += target
diff --git a/examples/webenginewidgets/push-notifications/server.js b/examples/webenginewidgets/push-notifications/server.js
new file mode 100644
index 000000000..fc7deb08a
--- /dev/null
+++ b/examples/webenginewidgets/push-notifications/server.js
@@ -0,0 +1,65 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+const express = require('express');
+const webpush = require('web-push');
+
+// setup server
+const port = 5000;
+const server = express();
+server.use(express.json());
+server.use(express.static('content'));
+
+// we support only one subscription at the time
+var subscription = null;
+
+// setup vapid keys
+const vapidKeys = {
+ publicKey :
+ "BNO4fIv439RpvbReeABNlDNiiBD2Maykn7EVnwsPseH7-P5hjnzZLEfnejXVP7Zt6MFoKqKeHm4nV9BHvbgoRPg",
+ privateKey : "HqhrzsRfG5-SB3j45lyUmV7cYZuy-71r2Bb0tgaOefk"
+};
+
+// set vapid keys for webpush libs
+webpush.setVapidDetails('mailto:push@qt.io', vapidKeys.publicKey, vapidKeys.privateKey);
+
+// add subscribe route
+server.post('/subscribe', (req, res) => {
+
+ // subscription request
+ subscription = req.body;
+ const delay = req.headers['ping-time'];
+ console.log('Got subscription with endpoint: ' + subscription.endpoint);
+ console.log('Ping delay is at: ' + delay);
+
+ // confirm resource created
+ res.status(201).json({});
+
+ // schedule notification
+ setTimeout(() => { sendNotification(delay) }, delay * 1000);
+});
+
+// add unsubscribe route
+server.post('/unsubscribe', (req, res) => {
+ console.log('Got unsubscribe with endpoint: ' + req.body.endpoint);
+ subscription = null;
+ res.status(201).json({});
+});
+
+function sendNotification(delay)
+{
+ if (!subscription)
+ return;
+
+ // create payload text
+ const payload = JSON.stringify({ title : 'Ping !', text : 'Visit qt.io', url : 'www.qt.io' });
+
+ // send notification
+ console.log('Sending notification !');
+ webpush.sendNotification(subscription, payload).catch(err => console.error(err));
+
+ // schedule next notification
+ setTimeout(() => { sendNotification(delay) }, delay * 1000);
+}
+
+server.listen(port, () => console.log(`Push server started at port ${port}`));
diff --git a/examples/webenginewidgets/recipebrowser/CMakeLists.txt b/examples/webenginewidgets/recipebrowser/CMakeLists.txt
new file mode 100644
index 000000000..ef858616e
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/CMakeLists.txt
@@ -0,0 +1,76 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(recipebrowser LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/recipebrowser")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
+
+qt_add_executable(recipebrowser
+ main.cpp
+ mainwindow.cpp mainwindow.h mainwindow.ui
+ stylesheetdialog.cpp stylesheetdialog.h stylesheetdialog.ui
+ document.cpp document.h
+)
+
+set_target_properties(recipebrowser PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(recipebrowser PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+)
+
+# Resources:
+set(recipebrowser_resource_files
+ "assets/3rdparty/markdown.css"
+ "assets/3rdparty/marked.js"
+ "assets/custom.css"
+ "assets/custom.js"
+ "assets/pages/burger.html"
+ "assets/pages/cupcakes.html"
+ "assets/pages/images/burger.jpg"
+ "assets/pages/images/cupcakes.jpg"
+ "assets/pages/images/pasta.jpg"
+ "assets/pages/images/pizza.jpg"
+ "assets/pages/images/skewers.jpg"
+ "assets/pages/images/soup.jpg"
+ "assets/pages/images/steak.jpg"
+ "assets/pages/pasta.html"
+ "assets/pages/pizza.html"
+ "assets/pages/skewers.html"
+ "assets/pages/soup.html"
+ "assets/pages/steak.html"
+ "assets/icons/edit.svg"
+ "assets/icons/stylesheets.svg"
+ "assets/icons/add.svg"
+ "assets/icons/remove.svg"
+ "assets/icons/view.svg"
+)
+
+qt_add_resources(recipebrowser "recipebrowser"
+ PREFIX
+ "/"
+ BASE
+ "assets"
+ FILES
+ ${recipebrowser_resource_files}
+)
+
+install(TARGETS recipebrowser
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKDOWN-LICENSE.txt
index 23c52cc43..23c52cc43 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKDOWN-LICENSE.txt
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKED-LICENSE.txt
index 8e3ba0e0a..8e3ba0e0a 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/MARKED-LICENSE.txt
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/markdown.css b/examples/webenginewidgets/recipebrowser/assets/3rdparty/markdown.css
index 24fc2ffe2..24fc2ffe2 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/markdown.css
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/markdown.css
diff --git a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/marked.js b/examples/webenginewidgets/recipebrowser/assets/3rdparty/marked.js
index 33c02d9cf..33c02d9cf 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/assets/3rdparty/marked.js
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/marked.js
diff --git a/examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json b/examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json
new file mode 100644
index 000000000..f8b0fd023
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/3rdparty/qt_attribution.json
@@ -0,0 +1,34 @@
+[
+ {
+ "Id" : "recipebrowser-marked",
+ "Name" : "Marked (WebEngine Recipe Browser example)",
+ "QDocModule" : "qtwebengine",
+ "QtUsage" : "Marked is used in the WebEngine Recipe Browser example",
+ "QtParts" : ["examples"],
+ "Files" : "marked.js",
+ "Description" :
+ "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
+ "Homepage" : "https://github.com/chjj/marked",
+ "Version" : "0.4.0",
+ "DownloadLocation" : "https://github.com/markedjs/marked/blob/0.4.0/lib/marked.js",
+ "Copyright" : "Copyright (c) 2011-2018, Christopher Jeffrey",
+ "License" : "MIT License",
+ "LicenseId" : "MIT",
+ "LicenseFile" : "MARKED-LICENSE.txt"
+ },
+ {
+ "Id" : "recipebrowser-markdowncss",
+ "Name" : "Markdown.css (WebEngine Recipe Browser example)",
+ "QDocModule" : "qtwebengine",
+ "QtUsage" : "markdown.css is used in the WebEngine Recipe Browser example",
+ "QtParts" : ["examples"],
+ "Files" : "markdown.css",
+ "Description" : "Markdown.css is better default styling for your Markdown files.",
+ "Version" : "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
+ "DownloadLocation" : "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
+ "Copyright" : "Copyright 2011 Kevin Burke Copyright Twitter Inc.",
+ "License" : "Apache License 2.0",
+ "LicenseId" : "Apache-2.0",
+ "LicenseFile" : "MARKDOWN-LICENSE.txt"
+ }
+ ]
diff --git a/examples/webenginewidgets/recipebrowser/assets/custom.css b/examples/webenginewidgets/recipebrowser/assets/custom.css
new file mode 100644
index 000000000..cc1106af3
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/custom.css
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+body {
+ padding-top: 0;
+ margin-top: 0;
+}
+
+#content {
+ display: none;
+}
+
+img {
+ width: 100%;
+ height: 100%;
+}
+
+li {
+ margin-left: 25px;
+}
+
+ol li {
+ margin-bottom: 10px;
+}
+
+* {
+ max-width: 960px !important;
+}
diff --git a/examples/webenginewidgets/recipebrowser/assets/custom.js b/examples/webenginewidgets/recipebrowser/assets/custom.js
new file mode 100644
index 000000000..34470164e
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/custom.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+marked.setOptions({
+ renderer : new marked.Renderer(),
+ gfm : true,
+ tables : true,
+ breaks : false,
+ pedantic : false,
+ sanitize : false,
+ smartLists : true,
+ smartypants : false
+});
diff --git a/examples/webenginewidgets/recipebrowser/assets/icons/add.svg b/examples/webenginewidgets/recipebrowser/assets/icons/add.svg
new file mode 100644
index 000000000..b5ecf9ae2
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/icons/add.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11 15C11 15.5523 11.4477 16 12 16C12.5523 16 13 15.5523 13 15V13H15C15.5523 13 16 12.5523 16 12C16 11.4477 15.5523 11 15 11H13V9C13 8.44772 12.5523 8 12 8C11.4477 8 11 8.44772 11 9V11H9C8.44772 11 8 11.4477 8 12C8 12.5523 8.44772 13 9 13H11V15Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/webenginewidgets/recipebrowser/assets/icons/edit.svg b/examples/webenginewidgets/recipebrowser/assets/icons/edit.svg
new file mode 100644
index 000000000..fe61445dc
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/icons/edit.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2 5C2 3.34315 3.34315 2 5 2H11C11.5523 2 12 2.44772 12 3C12 3.55228 11.5523 4 11 4H5C4.44772 4 4 4.44772 4 5V19C4 19.5523 4.44772 20 5 20H19C19.5523 20 20 19.5523 20 19V13.125C20 12.5727 20.4477 12.125 21 12.125C21.5523 12.125 22 12.5727 22 13.125V19C22 20.6569 20.6569 22 19 22H5C3.34315 22 2 20.6569 2 19V5Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M19.1974 4C18.9845 4 18.7803 4.08457 18.6298 4.23509L18.1941 4.6708L19.3116 5.82359L19.7649 5.37021C19.9155 5.21969 20 5.01553 20 4.80265C20 4.58978 19.9155 4.38562 19.7649 4.23509C19.6144 4.08457 19.4102 4 19.1974 4ZM17.8972 7.23797L16.7797 6.08518L10.7528 12.1121L10.3744 13.6256L11.8879 13.2473L17.8972 7.23797ZM17.2156 2.82088C17.7412 2.29528 18.4541 2 19.1974 2C19.9407 2 20.6535 2.29528 21.1791 2.82088C21.7047 3.34648 22 4.05934 22 4.80265C22 5.54596 21.7047 6.25883 21.1791 6.78443L13.1062 14.8573C12.9781 14.9855 12.8175 15.0764 12.6417 15.1204L9.24256 15.9701C8.90178 16.0553 8.54129 15.9555 8.29291 15.7071C8.04453 15.4587 7.94468 15.0982 8.02988 14.7575L8.87966 11.3583C8.92362 11.1825 9.01453 11.0219 9.14269 10.8938L17.2156 2.82088Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/webenginewidgets/recipebrowser/assets/icons/remove.svg b/examples/webenginewidgets/recipebrowser/assets/icons/remove.svg
new file mode 100644
index 000000000..3a5a420ac
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/icons/remove.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8 12C8 11.4477 8.44772 11 9 11H15C15.5523 11 16 11.4477 16 12C16 12.5523 15.5523 13 15 13H9C8.44772 13 8 12.5523 8 12Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/webenginewidgets/recipebrowser/assets/icons/stylesheets.svg b/examples/webenginewidgets/recipebrowser/assets/icons/stylesheets.svg
new file mode 100644
index 000000000..e108265b7
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/icons/stylesheets.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" fill="#0D0D0D"/>
+<path d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22V2Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/webenginewidgets/recipebrowser/assets/icons/view.svg b/examples/webenginewidgets/recipebrowser/assets/icons/view.svg
new file mode 100644
index 000000000..d2c0c474d
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/assets/icons/view.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.08086 11.6061C2.99143 9.48143 5.39011 4 12 4C15.2544 4 17.4247 5.25776 18.9399 6.87988C20.1459 8.17094 20.9403 9.71187 21.5334 10.8623C21.657 11.102 21.7719 11.3248 21.8799 11.5249L22.1676 12.0576L21.8289 12.5595C21.6963 12.7559 21.5424 13 21.3672 13.2781C20.7396 14.2738 19.8378 15.7048 18.6548 16.9413C17.1043 18.5619 14.9479 20 12 20C9.06156 20 6.9144 18.6096 5.36163 17.0026C4.11775 15.7152 3.19708 14.2194 2.55058 13.1691C2.40657 12.9351 2.27617 12.7233 2.15883 12.5408L1.8717 12.0941L2.08086 11.6061ZM4.12801 11.9149C4.18383 12.0048 4.24056 12.0967 4.29832 12.1903C4.94628 13.2397 5.72401 14.4993 6.79992 15.6128C8.10869 16.9673 9.76922 18 12 18C14.2213 18 15.8899 16.9381 17.2097 15.5587C18.2362 14.4858 18.9795 13.3089 19.6021 12.323C19.6836 12.194 19.7631 12.0682 19.8408 11.9464C19.7982 11.8645 19.7554 11.782 19.7124 11.6989C19.1185 10.5529 18.4761 9.31319 17.4784 8.24512C16.308 6.99224 14.6533 6 12 6C7.15387 6 5.13812 9.64957 4.12801 11.9149Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10ZM8 12C8 9.79086 9.79086 8 12 8C14.2091 8 16 9.79086 16 12C16 14.2091 14.2091 16 12 16C9.79086 16 8 14.2091 8 12Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/burger.html b/examples/webenginewidgets/recipebrowser/assets/pages/burger.html
index 6651cc0f0..99497959f 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/burger.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/burger.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Insanity Burger</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -68,8 +71,24 @@ give it a minute to go gorgeous and sloppy.
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/cupcakes.html b/examples/webenginewidgets/recipebrowser/assets/pages/cupcakes.html
index 4791c7ffa..e8e14a9b6 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/cupcakes.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/cupcakes.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Cupcakes</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -46,8 +49,25 @@ Cupcakes
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/burger.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/burger.jpg
index edc0c65de..edc0c65de 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/burger.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/burger.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/cupcakes.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/cupcakes.jpg
index cce52ba23..cce52ba23 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/cupcakes.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/cupcakes.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/pasta.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/pasta.jpg
index 7ac924b79..7ac924b79 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/pasta.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/pasta.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/pizza.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/pizza.jpg
index 8d8f756af..8d8f756af 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/pizza.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/pizza.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/skewers.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/skewers.jpg
index 6bb2f1172..6bb2f1172 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/skewers.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/skewers.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/soup.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/soup.jpg
index fc9dff906..fc9dff906 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/soup.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/soup.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/images/steak.jpg b/examples/webenginewidgets/recipebrowser/assets/pages/images/steak.jpg
index 240b72eb4..240b72eb4 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/images/steak.jpg
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/images/steak.jpg
Binary files differ
diff --git a/examples/webenginequick/recipebrowser/resources/pages/pasta.html b/examples/webenginewidgets/recipebrowser/assets/pages/pasta.html
index 41ed1a756..c2b3d840a 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/pasta.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/pasta.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Pasta</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -49,8 +52,25 @@ Pasta
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/pizza.html b/examples/webenginewidgets/recipebrowser/assets/pages/pizza.html
index 348d809e8..7e390a373 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/pizza.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/pizza.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Pizza Diavola</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -40,8 +43,25 @@ Pizza Diavola
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/skewers.html b/examples/webenginewidgets/recipebrowser/assets/pages/skewers.html
index aca4c4859..db2df5472 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/skewers.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/skewers.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Grilled skewers</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -46,8 +49,24 @@ Grilled skewers
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/soup.html b/examples/webenginewidgets/recipebrowser/assets/pages/soup.html
index 1b7027e5d..ea51fc8a5 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/soup.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/soup.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Soup</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -34,8 +37,25 @@ Soup
**Enjoy!**
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginequick/recipebrowser/resources/pages/steak.html b/examples/webenginewidgets/recipebrowser/assets/pages/steak.html
index a56313e27..26391b409 100644
--- a/examples/webenginequick/recipebrowser/resources/pages/steak.html
+++ b/examples/webenginewidgets/recipebrowser/assets/pages/steak.html
@@ -3,8 +3,11 @@
<head>
<meta charset="utf-8">
<title>Grilled steak and rice</title>
- <link rel="stylesheet" type="text/css" href="assets/3rdparty/markdown.css">
- <link rel="stylesheet" type="text/css" href="assets/custom.css">
+ <link rel="stylesheet" type="text/css" href="../3rdparty/markdown.css">
+ <link rel="stylesheet" type="text/css" href="../custom.css">
+ <script src="../3rdparty/marked.js"></script>
+ <script src="../custom.js"></script>
+ <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder"></div>
@@ -60,8 +63,24 @@ Grilled steak and rice
</div><!--End of content-->
- <script src="assets/3rdparty/marked.js"></script>
- <script src="assets/custom.js"></script>
+ <script>
+ 'use strict';
+
+ var jsContent = document.getElementById('content');
+ var placeholder = document.getElementById('placeholder');
+
+ var updateText = function(text) {
+ placeholder.innerHTML = marked.parse(text);
+ }
+
+ new QWebChannel(qt.webChannelTransport,
+ function(channel) {
+ var content = channel.objects.content;
+ content.setInitialText(jsContent.innerHTML);
+ content.textChanged.connect(updateText);
+ }
+ );
+ </script>
</body>
</html>
diff --git a/examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webp b/examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webp
new file mode 100644
index 000000000..7e711c661
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/doc/images/recipebrowser.webp
Binary files differ
diff --git a/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc
new file mode 100644
index 000000000..0400fcecc
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc
@@ -0,0 +1,197 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example webenginewidgets/recipebrowser
+ \title Recipe Browser
+ \meta tag {widgets, webengine, webchannel, webenginescript}
+ \ingroup webengine-widgetexamples
+ \brief Injecting custom stylsheets into web pages and providing a rich text preview
+ tool for a custom markup language.
+ \examplecategory {Web Technologies}
+
+ \image recipebrowser.webp
+
+ \e {Recipe Browser} is a small hybrid web browser application. It demonstrates how to
+ use the \l{Qt WebEngine Widgets C++ Classes} {Qt WebEngine C++ classes} to combine
+ C++ and JavaScript logic in the following ways.
+
+ \list
+ \li Running arbitrary JavaScript code via \c QWebEnginePage::runJavaScript() to
+ inject custom CSS stylesheets
+ \li Using QWebEngineScript and QWebEngineScriptCollection to persist the JavaScript
+ code and inject it to every page
+ \li Using QWebChannel to interact with and provide a rich text preview for a custom
+ markup language
+ \endlist
+
+ \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 Recipe Browser main window is split into a navigation on the left and
+ a preview area on the right. The preview area on the right switches to an
+ editor when the user clicks the Edit button on the top left of the main window.
+ The editor supports the Markdown syntax and is implemented by using
+ QPlainTextEdit. The document is rendered as rich text in the preview area,
+ once the user clicks the View button,to which the Edit button transforms to.
+ This rendering is implemented by using QWebEngineView. To render the text,
+ a JavaScript library inside the web engine converts the Markdown text to HTML.
+ The preview is updated from the editor through QWebChannel.
+
+ \include examples-run.qdocinc
+
+ \section1 Exposing Document Text
+
+ To render the current Markdown text it needs to be exposed to the web engine through
+ QWebChannel. To achieve this it has to be part of 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/recipebrowser/document.h
+ \skipto class Document
+ \printto #endif
+
+ The \c Document class wraps a QString \c m_currentText 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/recipebrowser/document.cpp
+ \skipto Document::setText(const QString &text)
+ \printuntil /^\}/
+
+ Additionally, the \c Document class keeps track of the current recipe via
+ \c m_currentPage. We call the recipes pages here, because each recipe has
+ its distinct HTML document that contains the initial text content.
+ Furthermore, \c m_textCollection is a QMap<QString, QString> that contains
+ the key/value pairs \{page, text\}, so that changes made to the text content
+ of a page is persisted between navigation. Nevertheless, we do not write the
+ modified text contents to the drive, but instead we persist them between
+ application start and shutdown via QSettings.
+
+ \section1 Creating the Main Window
+
+ The \c MainWindow class inherits the QMainWindow class:
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.h
+ \skipto class MainWindow :
+ \printto endif
+
+ The class declares private slots that match the two buttons on the
+ top left, over the navigation list view. Additionally, helper
+ methods for custom CSS stylesheets are declared.
+
+ 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_isEditMode is a boolean that toggles between the editor and the
+ preview area.
+ \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/recipebrowser/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. The text editor font is set to one
+ with a fixed character width, and the QWebEngineView widget is told not
+ to show a context menu. Furthermore, the editor is hidden away.
+
+ \printto ui->recipes
+
+ Here the \c clicked signals of QPushButton are connected to respective functions
+ that show the stylesheets dialog or toggle between edit and view mode, that is,
+ hide and show the editor and preview area respectively.
+
+ \printto m_content.setTextEdit
+
+ Here the navigation QListWidget on the left is setup with the 7 recipes.
+ Also, the currentItemChanged signal of QListWidget is connected to a lambda
+ that loads the new, current recipe page and updates the page in \c m_content.
+
+ \printto connect
+
+ Next, the pointer to the ui editor, a QPlainTextEdit, is passed to \c m_content to ensure that
+ calls to \c Document::setInitialText() work properly.
+
+ \printto QSettings
+
+ 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 ui->recipes
+
+ By using QSettings we persist stylesheets between application runs. If there
+ should be no stylesheets configured, for example, because the user deleted all of them
+ in a previous run, we load default ones.
+
+ \printto }
+
+ Finally, we set the currently selected list item to the first contained in the
+ navigation list widget. This triggers the previously mentioned
+ QListWidget::currentItemChanged signal and navigates to the page of the list item.
+
+ \section1 Working With Stylesheets
+
+ We use JavaScript to create and append CSS elements to the documents.
+ After declaring the script source, QWebEnginePage::runJavaScript() can run it
+ immediately and apply newly created styles on the current content of the web view.
+ Encapsulating the script into a QWebEngineScript and adding it to the script collection
+ of QWebEnginePage makes its effect permanent.
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.cpp
+ \skipto MainWindow::insertStyleSheet
+ \printuntil /^\}/
+
+ Removing stylesheets can be done similarly:
+
+ \quotefromfile webenginewidgets/recipebrowser/mainwindow.cpp
+ \skipto MainWindow::removeStyleSheet
+ \printuntil /^\}/
+
+ \section1 Creating a recipe file
+
+ \quotefile webenginewidgets/recipebrowser/assets/pages/burger.html
+
+ All the different recipe pages are set up the same way.
+
+ In the \c <head> part they
+ include two CSS files: \c markdown.css, that styles the markdown, and
+ custom.css, that does some further styling but most importantly hides the
+ \c <div> with id \e content, as this \c <div> only contains the unmodified,
+ initial content text. Also, three JS scripts are included. \c marked.js
+ is responsible for parsing the markdown and transforming it into HTML.
+ \c custom.js does some configuration of \c marked.js, and \c qwebchannel.js
+ exposes the QWebChannel JavaScript API.
+
+ In the body there are two \c <div> elements. The \c <div> with id \e placeholder
+ gets the markdown text injected that is rendered and visible. The \c <div> with id
+ \e content is hidden by \c custom.css and only contains the original, unmodified
+ text content of the recipe.
+
+ Finally, on the bottom of each recipe HTML file is a script that is responsible for
+ the communication between the C++ and JavaScript side via QWebChannel. The original,
+ unmodified text content inside the \c <div> with id \e content is passed to the C++
+ side and a callback is setup that is invoked when the \c textChanged signal of
+ \c m_content is emitted. The callback then updates the contents of the \c <div>
+ \e placeholder with the parsed markdown.
+
+ \section1 Files and Attributions
+
+ The example bundles the following code with third-party licenses:
+ \table
+ \row
+ \li \l{recipebrowser-marked}{Marked}
+ \li MIT License
+ \row
+ \li \l{recipebrowser-markdowncss}{Markdown.css}
+ \li Apache License 2.0
+ \endtable
+*/
diff --git a/examples/webenginewidgets/recipebrowser/document.cpp b/examples/webenginewidgets/recipebrowser/document.cpp
new file mode 100644
index 000000000..c991e14f8
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/document.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "document.h"
+
+#include <QSettings>
+
+Document::Document(QObject *parent) : QObject(parent)
+{
+ QSettings settings;
+ settings.beginGroup("textCollection");
+ QStringList pageTexts = settings.allKeys();
+ for (const QString &name : std::as_const(pageTexts)) {
+ QString pageText = settings.value(name).value<QString>();
+ if (!pageText.isEmpty())
+ m_textCollection.insert(name, pageText);
+ }
+ settings.endGroup();
+}
+
+void Document::setTextEdit(QPlainTextEdit *textEdit)
+{
+ m_textEdit = textEdit;
+}
+
+void Document::setCurrentPage(const QString &page)
+{
+ m_currentPage = page;
+}
+
+void Document::setInitialText(const QString &text)
+{
+ m_textEdit->setPlainText(m_textCollection.value(m_currentPage, text));
+}
+
+void Document::setText(const QString &text)
+{
+ if (text == m_currentText)
+ return;
+ m_currentText = text;
+ emit textChanged(m_currentText);
+
+ QSettings settings;
+ settings.beginGroup("textCollection");
+ settings.setValue(m_currentPage, text);
+ m_textCollection.insert(m_currentPage, text);
+ settings.endGroup();
+}
diff --git a/examples/webenginewidgets/recipebrowser/document.h b/examples/webenginewidgets/recipebrowser/document.h
new file mode 100644
index 000000000..f6b537eb8
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/document.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef DOCUMENT_H
+#define DOCUMENT_H
+
+#include <QObject>
+#include <QString>
+#include <QPlainTextEdit>
+
+class Document : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text MEMBER m_currentText NOTIFY textChanged FINAL)
+public:
+ explicit Document(QObject *parent = nullptr);
+
+ void setTextEdit(QPlainTextEdit *textEdit);
+ void setCurrentPage(const QString &page);
+
+public slots:
+ void setInitialText(const QString &text);
+ void setText(const QString &text);
+
+signals:
+ void textChanged(const QString &text);
+
+private:
+ QPlainTextEdit *m_textEdit;
+
+ QString m_currentText;
+ QString m_currentPage;
+ QMap<QString, QString> m_textCollection;
+};
+
+#endif // DOCUMENT_H
diff --git a/examples/webenginewidgets/recipebrowser/main.cpp b/examples/webenginewidgets/recipebrowser/main.cpp
new file mode 100644
index 000000000..b0b42d16b
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/main.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include "stylesheetdialog.h"
+#include <QApplication>
+#include <QUrl>
+
+int main(int argc, char *argv[])
+{
+ qRegisterMetaType<StyleSheet>("StyleSheet");
+
+ QCoreApplication::setOrganizationName("QtExamples");
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
diff --git a/examples/webenginewidgets/recipebrowser/mainwindow.cpp b/examples/webenginewidgets/recipebrowser/mainwindow.cpp
new file mode 100644
index 000000000..7eedab480
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/mainwindow.cpp
@@ -0,0 +1,154 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include "stylesheetdialog.h"
+#include "ui_mainwindow.h"
+
+#include <QWebChannel>
+
+static QMap<QString, QString> defaultStyleSheets = {
+ { "Upside down", "body { -webkit-transform: rotate(180deg); }" },
+ { "Darkmode",
+ "body { color: #FFF; background-color: #000 }"
+ "h1, h2, h3, h4, h5 { color: #FFF }" }
+};
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent), ui(new Ui::MainWindow), m_isEditMode(false)
+{
+ ui->setupUi(this);
+ ui->textEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
+ ui->textEdit->hide();
+ ui->webEngineView->setContextMenuPolicy(Qt::NoContextMenu);
+
+ connect(ui->stylesheetsButton, &QPushButton::clicked, this, &MainWindow::showStyleSheetsDialog);
+ connect(ui->editViewButton, &QPushButton::clicked, this, &MainWindow::toggleEditView);
+
+ ui->recipes->insertItem(0, "Burger");
+ ui->recipes->insertItem(1, "Cupcakes");
+ ui->recipes->insertItem(2, "Pasta");
+ ui->recipes->insertItem(3, "Pizza");
+ ui->recipes->insertItem(4, "Skewers");
+ ui->recipes->insertItem(5, "Soup");
+ ui->recipes->insertItem(6, "Steak");
+ connect(ui->recipes, &QListWidget::currentItemChanged, this,
+ [this](QListWidgetItem *current, QListWidgetItem * /* previous */) {
+ const QString page = current->text().toLower();
+ const QString url = QStringLiteral("qrc:/pages/") + page + QStringLiteral(".html");
+ ui->webEngineView->setUrl(QUrl(url));
+ m_content.setCurrentPage(page);
+ });
+
+ m_content.setTextEdit(ui->textEdit);
+
+ connect(ui->textEdit, &QPlainTextEdit::textChanged, this,
+ [this]() { m_content.setText(ui->textEdit->toPlainText()); });
+
+ QWebChannel *channel = new QWebChannel(this);
+ channel->registerObject(QStringLiteral("content"), &m_content);
+ ui->webEngineView->page()->setWebChannel(channel);
+
+ QSettings settings;
+ settings.beginGroup("styleSheets");
+ QStringList styleSheets = settings.allKeys();
+ if (styleSheets.empty()) {
+ // Add back default style sheets if the user cleared them out
+ loadDefaultStyleSheets();
+ } else {
+ for (const auto &name : std::as_const(styleSheets)) {
+ StyleSheet styleSheet = settings.value(name).value<StyleSheet>();
+ if (styleSheet.second)
+ insertStyleSheet(name, styleSheet.first, false);
+ }
+ }
+ settings.endGroup();
+
+ ui->recipes->setCurrentItem(ui->recipes->item(0));
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::insertStyleSheet(const QString &name, const QString &source, bool immediately)
+{
+ QWebEngineScript script;
+ QString s = QString::fromLatin1("(function() {"
+ " css = document.createElement('style');"
+ " css.type = 'text/css';"
+ " css.id = '%1';"
+ " document.head.appendChild(css);"
+ " css.innerText = '%2';"
+ "})()")
+ .arg(name, source.simplified());
+ if (immediately)
+ ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
+
+ script.setName(name);
+ script.setSourceCode(s);
+ script.setInjectionPoint(QWebEngineScript::DocumentReady);
+ script.setRunsOnSubFrames(true);
+ script.setWorldId(QWebEngineScript::ApplicationWorld);
+ ui->webEngineView->page()->scripts().insert(script);
+}
+
+void MainWindow::removeStyleSheet(const QString &name, bool immediately)
+{
+ QString s = QString::fromLatin1("(function() {"
+ " var element = document.getElementById('%1');"
+ " element.outerHTML = '';"
+ " delete element;"
+ "})()")
+ .arg(name);
+ if (immediately)
+ ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
+
+ const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
+ if (!scripts.isEmpty())
+ ui->webEngineView->page()->scripts().remove(scripts.first());
+}
+
+bool MainWindow::hasStyleSheet(const QString &name)
+{
+ const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
+ return !scripts.isEmpty();
+}
+
+void MainWindow::loadDefaultStyleSheets()
+{
+ QSettings settings;
+ settings.beginGroup("styleSheets");
+
+ for (auto it = defaultStyleSheets.constBegin(); it != defaultStyleSheets.constEnd(); ++it) {
+ settings.setValue(it.key(), QVariant::fromValue(qMakePair(it.value(), false)));
+ }
+
+ settings.endGroup();
+}
+
+void MainWindow::showStyleSheetsDialog()
+{
+ StylesheetDialog *dialog = new StylesheetDialog(this);
+ dialog->show();
+}
+
+void MainWindow::toggleEditView()
+{
+ m_isEditMode = !m_isEditMode;
+
+ if (m_isEditMode) {
+ ui->webEngineView->hide();
+ ui->textEdit->show();
+
+ ui->editViewButton->setText(QStringLiteral("View"));
+ ui->editViewButton->setIcon(QIcon(":/icons/view.svg"));
+ } else {
+ ui->textEdit->hide();
+ ui->webEngineView->show();
+
+ ui->editViewButton->setText(QStringLiteral("Edit"));
+ ui->editViewButton->setIcon(QIcon(":/icons/edit.svg"));
+ }
+}
diff --git a/examples/webenginewidgets/recipebrowser/mainwindow.h b/examples/webenginewidgets/recipebrowser/mainwindow.h
new file mode 100644
index 000000000..959c82af8
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/mainwindow.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "document.h"
+#include <QMainWindow>
+#include <QSettings>
+#include <QWebEngineScriptCollection>
+#include <QWebEngineView>
+#include <QPlainTextEdit>
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class MainWindow;
+}
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+
+ void insertStyleSheet(const QString &name, const QString &source, bool immediately);
+ void removeStyleSheet(const QString &name, bool immediately);
+ bool hasStyleSheet(const QString &name);
+ void loadDefaultStyleSheets();
+
+private slots:
+ void showStyleSheetsDialog();
+ void toggleEditView();
+
+private:
+ Ui::MainWindow *ui;
+
+ bool m_isEditMode;
+ Document m_content;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/recipebrowser/mainwindow.ui b/examples/webenginewidgets/recipebrowser/mainwindow.ui
new file mode 100644
index 000000000..9c2539fd5
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/mainwindow.ui
@@ -0,0 +1,116 @@
+<?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>713</width>
+ <height>455</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Recipe Browser</string>
+ </property>
+ <property name="unifiedTitleAndToolBarOnMac">
+ <bool>false</bool>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="navigation">
+ <item>
+ <layout class="QHBoxLayout" name="navigationBar">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Recipes</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="editViewButton">
+ <property name="text">
+ <string>Edit</string>
+ </property>
+ <property name="icon">
+ <iconset resource="recipebrowser.qrc">
+ <normaloff>:/icons/edit.svg</normaloff>:/icons/edit.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stylesheetsButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Stylesheets</string>
+ </property>
+ <property name="icon">
+ <iconset resource="recipebrowser.qrc">
+ <normaloff>:/icons/stylesheets.svg</normaloff>:/icons/stylesheets.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="recipes">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QWebEngineView" name="webEngineView" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="textEdit"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>QWebEngineView</class>
+ <extends>QWidget</extends>
+ <header>qwebengineview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="recipebrowser.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.pro b/examples/webenginewidgets/recipebrowser/recipebrowser.pro
index a9ff54400..8f8895b52 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.pro
+++ b/examples/webenginewidgets/recipebrowser/recipebrowser.pro
@@ -1,22 +1,24 @@
TEMPLATE = app
-TARGET = stylesheetbrowser
+TARGET = recipebrowser
QT += webenginewidgets
HEADERS += \
mainwindow.h \
- stylesheetdialog.h
+ stylesheetdialog.h \
+ document.h
SOURCES += \
main.cpp \
mainwindow.cpp \
- stylesheetdialog.cpp
+ stylesheetdialog.cpp \
+ document.cpp
FORMS += \
mainwindow.ui \
stylesheetdialog.ui
-RESOURCES += stylesheetbrowser.qrc
+RESOURCES += recipebrowser.qrc
# install
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/stylesheetbrowser
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/recipebrowser
INSTALLS += target
diff --git a/examples/webenginewidgets/recipebrowser/recipebrowser.qrc b/examples/webenginewidgets/recipebrowser/recipebrowser.qrc
new file mode 100644
index 000000000..c1eb909a7
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/recipebrowser.qrc
@@ -0,0 +1,27 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="3rdparty/markdown.css">assets/3rdparty/markdown.css</file>
+ <file alias="3rdparty/marked.js">assets/3rdparty/marked.js</file>
+ <file alias="custom.js">assets/custom.js</file>
+ <file alias="custom.css">assets/custom.css</file>
+ <file alias="pages/images/burger.jpg">assets/pages/images/burger.jpg</file>
+ <file alias="pages/images/cupcakes.jpg">assets/pages/images/cupcakes.jpg</file>
+ <file alias="pages/images/pasta.jpg">assets/pages/images/pasta.jpg</file>
+ <file alias="pages/images/pizza.jpg">assets/pages/images/pizza.jpg</file>
+ <file alias="pages/images/skewers.jpg">assets/pages/images/skewers.jpg</file>
+ <file alias="pages/images/soup.jpg">assets/pages/images/soup.jpg</file>
+ <file alias="pages/images/steak.jpg">assets/pages/images/steak.jpg</file>
+ <file alias="pages/burger.html">assets/pages/burger.html</file>
+ <file alias="pages/cupcakes.html">assets/pages/cupcakes.html</file>
+ <file alias="pages/pasta.html">assets/pages/pasta.html</file>
+ <file alias="pages/pizza.html">assets/pages/pizza.html</file>
+ <file alias="pages/skewers.html">assets/pages/skewers.html</file>
+ <file alias="pages/soup.html">assets/pages/soup.html</file>
+ <file alias="pages/steak.html">assets/pages/steak.html</file>
+ <file alias="icons/edit.svg">assets/icons/edit.svg</file>
+ <file alias="icons/stylesheets.svg">assets/icons/stylesheets.svg</file>
+ <file alias="icons/add.svg">assets/icons/add.svg</file>
+ <file alias="icons/remove.svg">assets/icons/remove.svg</file>
+ <file alias="icons/view.svg">assets/icons/view.svg</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.cpp b/examples/webenginewidgets/recipebrowser/stylesheetdialog.cpp
index 7351ab75f..2137617c3 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.cpp
+++ b/examples/webenginewidgets/recipebrowser/stylesheetdialog.cpp
@@ -1,65 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include "stylesheetdialog.h"
#include "ui_stylesheetdialog.h"
-StylesheetDialog::StylesheetDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::StylesheetDialog)
+StylesheetDialog::StylesheetDialog(QWidget *parent) : QDialog(parent), ui(new Ui::StylesheetDialog)
{
ui->setupUi(this);
- connect(ui->styleSheetList, &QListWidget::currentItemChanged, this, &StylesheetDialog::currentStyleSheetChanged);
- connect(ui->styleSheetList, &QListWidget::itemClicked, this, &StylesheetDialog::listItemClicked);
+ connect(ui->styleSheetList, &QListWidget::currentItemChanged, this,
+ &StylesheetDialog::currentStyleSheetChanged);
+ connect(ui->styleSheetList, &QListWidget::itemClicked, this,
+ &StylesheetDialog::listItemClicked);
connect(ui->fileNameEdit, &QLineEdit::textChanged, this, &StylesheetDialog::fileNameChanged);
connect(ui->addButton, &QPushButton::clicked, this, &StylesheetDialog::addButtonClicked);
@@ -67,8 +20,8 @@ StylesheetDialog::StylesheetDialog(QWidget *parent) :
QSettings settings;
settings.beginGroup("styleSheets");
- for (auto name : settings.allKeys()) {
- QListWidgetItem *listItem = new QListWidgetItem(name, ui->styleSheetList);
+ for (const auto &name : settings.allKeys()) {
+ QListWidgetItem *listItem = new QListWidgetItem(name, ui->styleSheetList);
listItem->setFlags(listItem->flags() | Qt::ItemIsUserCheckable);
bool checked = settings.value(name).value<StyleSheet>().second;
listItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
@@ -106,9 +59,8 @@ void StylesheetDialog::listItemClicked(QListWidgetItem *item)
{
MainWindow *window = static_cast<MainWindow *>(parent());
const QString name = item->text();
- bool checkedStateChanged =
- (item->checkState() == Qt::Checked && !window->hasStyleSheet(name)) ||
- (item->checkState() == Qt::Unchecked && window->hasStyleSheet(name));
+ bool checkedStateChanged = (item->checkState() == Qt::Checked && !window->hasStyleSheet(name))
+ || (item->checkState() == Qt::Unchecked && window->hasStyleSheet(name));
if (!checkedStateChanged)
return;
@@ -143,7 +95,7 @@ void StylesheetDialog::addButtonClicked()
if (name.isEmpty() || source.isEmpty())
return;
- QListWidgetItem *listItem = new QListWidgetItem(ui->fileNameEdit->text(), ui->styleSheetList);
+ QListWidgetItem *listItem = new QListWidgetItem(ui->fileNameEdit->text(), ui->styleSheetList);
listItem->setFlags(listItem->flags() | Qt::ItemIsUserCheckable);
listItem->setCheckState(Qt::Checked);
diff --git a/examples/webenginewidgets/recipebrowser/stylesheetdialog.h b/examples/webenginewidgets/recipebrowser/stylesheetdialog.h
new file mode 100644
index 000000000..ca1b4ae99
--- /dev/null
+++ b/examples/webenginewidgets/recipebrowser/stylesheetdialog.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef STYLESHEETDIALOG_H
+#define STYLESHEETDIALOG_H
+
+#include <QDialog>
+#include <QListWidgetItem>
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class StylesheetDialog;
+}
+QT_END_NAMESPACE
+
+typedef QPair<QString, bool> StyleSheet; // <source, isEnabled>
+Q_DECLARE_METATYPE(StyleSheet);
+
+class StylesheetDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit StylesheetDialog(QWidget *parent = 0);
+ ~StylesheetDialog();
+
+private slots:
+ void currentStyleSheetChanged(QListWidgetItem *current, QListWidgetItem *previous);
+ void listItemClicked(QListWidgetItem *item);
+ void fileNameChanged(const QString &text);
+
+ void addButtonClicked();
+ void removeButtonClicked();
+
+private:
+ Ui::StylesheetDialog *ui;
+};
+
+#endif // STYLESHEETDIALOG_H
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.ui b/examples/webenginewidgets/recipebrowser/stylesheetdialog.ui
index 19db267e8..6ef389195 100644
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.ui
+++ b/examples/webenginewidgets/recipebrowser/stylesheetdialog.ui
@@ -68,6 +68,10 @@
<property name="text">
<string>Add</string>
</property>
+ <property name="icon">
+ <iconset resource="recipebrowser.qrc">
+ <normaloff>:/icons/add.svg</normaloff>:/icons/add.svg</iconset>
+ </property>
</widget>
</item>
<item>
@@ -75,6 +79,10 @@
<property name="text">
<string>Remove</string>
</property>
+ <property name="icon">
+ <iconset resource="recipebrowser.qrc">
+ <normaloff>:/icons/remove.svg</normaloff>:/icons/remove.svg</iconset>
+ </property>
</widget>
</item>
</layout>
@@ -84,7 +92,9 @@
</item>
</layout>
</widget>
- <resources/>
+ <resources>
+ <include location="recipebrowser.qrc"/>
+ </resources>
<connections>
<connection>
<sender>buttonBox</sender>
diff --git a/examples/webenginewidgets/simplebrowser/CMakeLists.txt b/examples/webenginewidgets/simplebrowser/CMakeLists.txt
index ee11c02d1..cbaffa6d9 100644
--- a/examples/webenginewidgets/simplebrowser/CMakeLists.txt
+++ b/examples/webenginewidgets/simplebrowser/CMakeLists.txt
@@ -1,21 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(simplebrowser LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/simplebrowser")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(simplebrowser
browser.cpp browser.h
@@ -29,18 +27,28 @@ qt_add_executable(simplebrowser
webpage.cpp webpage.h
webpopupwindow.cpp webpopupwindow.h
webview.cpp webview.h
+ webauthdialog.cpp webauthdialog.h webauthdialog.ui
)
+
+if(WIN32)
+ set_property(
+ TARGET simplebrowser
+ APPEND PROPERTY
+ SOURCES simplebrowser.exe.manifest)
+endif()
+
set_target_properties(simplebrowser PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginewidgets.simplebrowser"
)
+
target_link_libraries(simplebrowser PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-
# Resources:
set(simplebrowser_resource_files
"data/AppLogoColor.png"
@@ -55,6 +63,7 @@ qt_add_resources(simplebrowser "simplebrowser"
FILES
${simplebrowser_resource_files}
)
+
set(simplebrowser1_resource_files
"data/3rdparty/dialog-error.png"
"data/3rdparty/edit-clear.png"
@@ -75,6 +84,24 @@ qt_add_resources(simplebrowser "simplebrowser1"
${simplebrowser1_resource_files}
)
+if (APPLE)
+ set_target_properties(simplebrowser PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist"
+ )
+
+ if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ # Need to sign application for location permissions to work
+ if(QT_FEATURE_debug_and_release)
+ set(exe_path "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/")
+ else()
+ unset(exe_path)
+ endif()
+ add_custom_command(TARGET simplebrowser
+ POST_BUILD COMMAND codesign --force -s - ${exe_path}simplebrowser.app
+ )
+ endif()
+endif()
+
install(TARGETS simplebrowser
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
diff --git a/examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist b/examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist
new file mode 100644
index 000000000..7abb7e01a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>NSLocationUsageDescription</key>
+ <string>Simple Browser would like to give web sites access to your location for demo purposes.</string>
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Simple Browser would like to give web sites access to your computer's microphone for demo purposes.</string>
+ <key>NSCameraUsageDescription</key>
+ <string>Simple Browser would like to give web sites access to your computer's camera for demo purposes.</string>
+</dict>
+</plist>
diff --git a/examples/webenginewidgets/simplebrowser/browser.cpp b/examples/webenginewidgets/simplebrowser/browser.cpp
index c3f66cb38..fd68246d0 100644
--- a/examples/webenginewidgets/simplebrowser/browser.cpp
+++ b/examples/webenginewidgets/simplebrowser/browser.cpp
@@ -1,58 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "browser.h"
#include "browserwindow.h"
#include <QWebEngineSettings>
+using namespace Qt::StringLiterals;
+
Browser::Browser()
{
// Quit application if the download manager window is the only remaining window
@@ -63,13 +18,16 @@ Browser::Browser()
&m_downloadManagerWidget, &DownloadManagerWidget::downloadRequested);
}
-BrowserWindow *Browser::createWindow(bool offTheRecord)
+BrowserWindow *Browser::createHiddenWindow(bool offTheRecord)
{
if (!offTheRecord && !m_profile) {
- m_profile.reset(new QWebEngineProfile(
- QString::fromLatin1("simplebrowser.%1").arg(qWebEngineChromiumVersion())));
+ const QString name = u"simplebrowser."_s + QLatin1StringView(qWebEngineChromiumVersion());
+ m_profile.reset(new QWebEngineProfile(name));
m_profile->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
m_profile->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true);
+ m_profile->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
+ m_profile->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, false);
+ m_profile->settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
QObject::connect(m_profile.get(), &QWebEngineProfile::downloadRequested,
&m_downloadManagerWidget, &DownloadManagerWidget::downloadRequested);
}
@@ -79,6 +37,12 @@ BrowserWindow *Browser::createWindow(bool offTheRecord)
QObject::connect(mainWindow, &QObject::destroyed, [this, mainWindow]() {
m_windows.removeOne(mainWindow);
});
+ return mainWindow;
+}
+
+BrowserWindow *Browser::createWindow(bool offTheRecord)
+{
+ auto *mainWindow = createHiddenWindow(offTheRecord);
mainWindow->show();
return mainWindow;
}
diff --git a/examples/webenginewidgets/simplebrowser/browser.h b/examples/webenginewidgets/simplebrowser/browser.h
index 2296eda9a..dcee68c79 100644
--- a/examples/webenginewidgets/simplebrowser/browser.h
+++ b/examples/webenginewidgets/simplebrowser/browser.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BROWSER_H
#define BROWSER_H
@@ -65,6 +18,7 @@ public:
QList<BrowserWindow*> windows() { return m_windows; }
+ BrowserWindow *createHiddenWindow(bool offTheRecord = false);
BrowserWindow *createWindow(bool offTheRecord = false);
BrowserWindow *createDevToolsWindow();
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
index 26639117c..a5a83a2d3 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "browser.h"
#include "browserwindow.h"
@@ -68,18 +21,12 @@
#include <QWebEngineFindTextResult>
#include <QWebEngineProfile>
+using namespace Qt::StringLiterals;
+
BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool forDevTools)
: m_browser(browser)
, m_profile(profile)
, m_tabWidget(new TabWidget(profile, this))
- , m_progressBar(nullptr)
- , m_historyBackAction(nullptr)
- , m_historyForwardAction(nullptr)
- , m_stopAction(nullptr)
- , m_reloadAction(nullptr)
- , m_stopReloadAction(nullptr)
- , m_urlLineEdit(nullptr)
- , m_favAction(nullptr)
{
setAttribute(Qt::WA_DeleteOnClose, true);
setFocusPolicy(Qt::ClickFocus);
@@ -105,7 +52,7 @@ BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool
m_progressBar->setMaximumHeight(1);
m_progressBar->setTextVisible(false);
- m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}"));
+ m_progressBar->setStyleSheet(u"QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}"_s);
layout->addWidget(m_progressBar);
}
@@ -153,7 +100,11 @@ QSize BrowserWindow::sizeHint() const
QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget)
{
QMenu *fileMenu = new QMenu(tr("&File"));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
+ fileMenu->addAction(tr("&New Window"), QKeySequence::New, this, &BrowserWindow::handleNewWindowTriggered);
+#else
fileMenu->addAction(tr("&New Window"), this, &BrowserWindow::handleNewWindowTriggered, QKeySequence::New);
+#endif
fileMenu->addAction(tr("New &Incognito Window"), this, &BrowserWindow::handleNewIncognitoWindowTriggered);
QAction *newTabAction = new QAction(tr("New &Tab"), this);
@@ -164,7 +115,11 @@ QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget)
});
fileMenu->addAction(newTabAction);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
+ fileMenu->addAction(tr("&Open File..."), QKeySequence::Open, this, &BrowserWindow::handleFileOpenTriggered);
+#else
fileMenu->addAction(tr("&Open File..."), this, &BrowserWindow::handleFileOpenTriggered, QKeySequence::Open);
+#endif
fileMenu->addSeparator();
QAction *closeTabAction = new QAction(tr("&Close Tab"), this);
@@ -305,11 +260,19 @@ QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget)
previousTabAction->setShortcuts(shortcuts);
connect(previousTabAction, &QAction::triggered, tabWidget, &TabWidget::previousTab);
- connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction]() {
+ QAction *inspectorAction = new QAction(tr("Open inspector in new window"), this);
+ shortcuts.clear();
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_I));
+ inspectorAction->setShortcuts(shortcuts);
+ connect(inspectorAction, &QAction::triggered, [this]() { emit currentTab()->devToolsRequested(currentTab()->page()); });
+
+ connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction, inspectorAction]() {
menu->clear();
menu->addAction(nextTabAction);
menu->addAction(previousTabAction);
menu->addSeparator();
+ menu->addAction(inspectorAction);
+ menu->addSeparator();
QList<BrowserWindow*> windows = m_browser->windows();
int index(-1);
@@ -331,6 +294,20 @@ QMenu *BrowserWindow::createHelpMenu()
return helpMenu;
}
+static bool isBackspace(const QKeySequence &k)
+{
+ return (k[0].key() & Qt::Key_unknown) == Qt::Key_Backspace;
+}
+
+// Chromium already handles navigate on backspace when appropriate.
+static QList<QKeySequence> removeBackspace(QList<QKeySequence> keys)
+{
+ const auto it = std::find_if(keys.begin(), keys.end(), isBackspace);
+ if (it != keys.end())
+ keys.erase(it);
+ return keys;
+}
+
QToolBar *BrowserWindow::createToolBar()
{
QToolBar *navigationBar = new QToolBar(tr("Navigation"));
@@ -338,19 +315,13 @@ QToolBar *BrowserWindow::createToolBar()
navigationBar->toggleViewAction()->setEnabled(false);
m_historyBackAction = new QAction(this);
- QList<QKeySequence> backShortcuts = QKeySequence::keyBindings(QKeySequence::Back);
- for (auto it = backShortcuts.begin(); it != backShortcuts.end();) {
- // Chromium already handles navigate on backspace when appropriate.
- if ((*it)[0].key() == Qt::Key_Backspace)
- it = backShortcuts.erase(it);
- else
- ++it;
- }
+ auto backShortcuts = removeBackspace(QKeySequence::keyBindings(QKeySequence::Back));
// For some reason Qt doesn't bind the dedicated Back key to Back.
backShortcuts.append(QKeySequence(Qt::Key_Back));
m_historyBackAction->setShortcuts(backShortcuts);
m_historyBackAction->setIconVisibleInMenu(false);
- m_historyBackAction->setIcon(QIcon(QStringLiteral(":go-previous.png")));
+ m_historyBackAction->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::GoPrevious,
+ QIcon(":go-previous.png"_L1)));
m_historyBackAction->setToolTip(tr("Go back in history"));
connect(m_historyBackAction, &QAction::triggered, [this]() {
m_tabWidget->triggerWebPageAction(QWebEnginePage::Back);
@@ -358,17 +329,12 @@ QToolBar *BrowserWindow::createToolBar()
navigationBar->addAction(m_historyBackAction);
m_historyForwardAction = new QAction(this);
- QList<QKeySequence> fwdShortcuts = QKeySequence::keyBindings(QKeySequence::Forward);
- for (auto it = fwdShortcuts.begin(); it != fwdShortcuts.end();) {
- if (((*it)[0].key() & Qt::Key_unknown) == Qt::Key_Backspace)
- it = fwdShortcuts.erase(it);
- else
- ++it;
- }
+ auto fwdShortcuts = removeBackspace(QKeySequence::keyBindings(QKeySequence::Forward));
fwdShortcuts.append(QKeySequence(Qt::Key_Forward));
m_historyForwardAction->setShortcuts(fwdShortcuts);
m_historyForwardAction->setIconVisibleInMenu(false);
- m_historyForwardAction->setIcon(QIcon(QStringLiteral(":go-next.png")));
+ m_historyForwardAction->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::GoNext,
+ QIcon(":go-next.png"_L1)));
m_historyForwardAction->setToolTip(tr("Go forward in history"));
connect(m_historyForwardAction, &QAction::triggered, [this]() {
m_tabWidget->triggerWebPageAction(QWebEnginePage::Forward);
@@ -388,12 +354,11 @@ QToolBar *BrowserWindow::createToolBar()
navigationBar->addWidget(m_urlLineEdit);
auto downloadsAction = new QAction(this);
- downloadsAction->setIcon(QIcon(QStringLiteral(":go-bottom.png")));
+ downloadsAction->setIcon(QIcon(u":go-bottom.png"_s));
downloadsAction->setToolTip(tr("Show downloads"));
navigationBar->addAction(downloadsAction);
- connect(downloadsAction, &QAction::triggered, [this]() {
- m_browser->downloadManagerWidget().show();
- });
+ connect(downloadsAction, &QAction::triggered,
+ &m_browser->downloadManagerWidget(), &QWidget::show);
return navigationBar;
}
@@ -493,8 +458,10 @@ WebView *BrowserWindow::currentTab() const
void BrowserWindow::handleWebViewLoadProgress(int progress)
{
- static QIcon stopIcon(QStringLiteral(":process-stop.png"));
- static QIcon reloadIcon(QStringLiteral(":view-refresh.png"));
+ static QIcon stopIcon = QIcon::fromTheme(QIcon::ThemeIcon::ProcessStop,
+ QIcon(":process-stop.png"_L1));
+ static QIcon reloadIcon = QIcon::fromTheme(QIcon::ThemeIcon::ViewRefresh,
+ QIcon(":view-refresh.png"_L1));
if (0 < progress && progress < 100) {
m_stopReloadAction->setData(QWebEnginePage::Stop);
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h
index 11a655469..55eeb46c2 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.h
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BROWSERWINDOW_H
#define BROWSERWINDOW_H
@@ -69,7 +22,8 @@ class BrowserWindow : public QMainWindow
Q_OBJECT
public:
- BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool forDevTools = false);
+ explicit BrowserWindow(Browser *browser, QWebEngineProfile *profile,
+ bool forDevTools = false);
QSize sizeHint() const override;
TabWidget *tabWidget() const;
WebView *currentTab() const;
@@ -102,14 +56,14 @@ private:
Browser *m_browser;
QWebEngineProfile *m_profile;
TabWidget *m_tabWidget;
- QProgressBar *m_progressBar;
- QAction *m_historyBackAction;
- QAction *m_historyForwardAction;
- QAction *m_stopAction;
- QAction *m_reloadAction;
- QAction *m_stopReloadAction;
- QLineEdit *m_urlLineEdit;
- QAction *m_favAction;
+ QProgressBar *m_progressBar = nullptr;
+ QAction *m_historyBackAction = nullptr;
+ QAction *m_historyForwardAction = nullptr;
+ QAction *m_stopAction = nullptr;
+ QAction *m_reloadAction = nullptr;
+ QAction *m_stopReloadAction = nullptr;
+ QLineEdit *m_urlLineEdit = nullptr;
+ QAction *m_favAction = nullptr;
QString m_lastSearch;
};
diff --git a/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json b/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json
index d81f5bf23..fbc96416e 100644
--- a/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json
+++ b/examples/webenginewidgets/simplebrowser/data/3rdparty/qt_attribution.json
@@ -12,13 +12,13 @@
"LicenseId": "urn:dje:license:public-domain",
"License": "Public Domain",
"LicenseFile": "COPYING",
- "Copyright": "Ulisse Perusin <uli.peru@gmail.com>
-Steven Garrity <sgarrity@silverorange.com>
-Lapo Calamandrei <calamandrei@gmail.com>
-Ryan Collier <rcollier@novell.com>
-Rodney Dawes <dobey@novell.com>
-Andreas Nilsson <nisses.mail@home.se>
-Tuomas Kuosmanen <tigert@tigert.com>
-Garrett LeSage <garrett@novell.com>
-Jakub Steiner <jimmac@novell.com>"
+ "Copyright": ["Ulisse Perusin <uli.peru@gmail.com>",
+ "Steven Garrity <sgarrity@silverorange.com>",
+ "Lapo Calamandrei <calamandrei@gmail.com>",
+ "Ryan Collier <rcollier@novell.com>",
+ "Rodney Dawes <dobey@novell.com>",
+ "Andreas Nilsson <nisses.mail@home.se>",
+ "Tuomas Kuosmanen <tigert@tigert.com>",
+ "Garrett LeSage <garrett@novell.com>",
+ "Jakub Steiner <jimmac@novell.com>"]
}
diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
index b10c6d4f0..dd7a8b998 100644
--- a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
@@ -1,35 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/simplebrowser
\title WebEngine Widgets Simple Browser Example
\ingroup webengine-widgetexamples
\brief A simple browser based on \QWE Widgets.
+ \examplecategory {Web Technologies}
\image simplebrowser.png
@@ -91,6 +68,9 @@
\skipto main
\printuntil }
+ To suppress flicker when switching the window to OpenGL rendering, we call
+ show after the first browser tab has been added.
+
\section1 Creating Tabs
The \c BrowserWindow constructor initializes all the necessary user interface
@@ -280,6 +260,8 @@
\skipto /^class Browser$/
\printuntil public:
\dots
+ \skipto createHiddenWindow
+ \printline createHiddenWindow
\skipto createWindow
\printline createWindow
\skipto private:
@@ -295,7 +277,7 @@
\quotefromfile webenginewidgets/simplebrowser/browser.cpp
- \skipto Browser::createWindow
+ \skipto Browser::createHiddenWindow
\printuntil m_profile.reset
\dots
@@ -340,6 +322,37 @@
finished or when an error occurs. See \c downloadmanagerwidget.cpp for an
example of how these signals can be handled.
+ \section1 Managing WebAuth/FIDO UX Requests
+
+ WebAuth UX requests are associated with \l QWebEnginePage. Whenever an authenticator
+ requires user interaction, a UX request is triggered on the QWebEnginePage and
+ the \l QWebEnginePage::webAuthUxRequested signal is emitted with
+ \l QWebEngineWebAuthUxRequest, which in this example is forwarded
+ to \c WebView::handleAuthenticatorRequired:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto connect(page, &QWebEnginePage::webAuthUxRequested
+ \printline connect(page, &QWebEnginePage::webAuthUxRequested
+
+ This method creates a WebAuth UX dialog and initiates the UX request flow.
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto void WebView::handleWebAuthUxRequested(QWebEngineWebAuthUxRequest *request)
+ \printuntil /^\}/
+
+ The \l QWebEngineWebAuthUxRequest object periodically emits the \l
+ {QWebEngineWebAuthUxRequest::}{stateChanged} signal to notify potential
+ observers of the current WebAuth UX states. The observers update the WebAuth
+ dialog accordingly. See \c webview.cpp and \c webauthdialog.cpp for an example
+ of how these signals can be handled.
+
+ \section1 Signing Requirement for macOS
+
+ To allow web sites access to the location, camera, and microphone when running
+ \e {Simple Browser} on macOS, the application needs to be signed. This is
+ done automatically when building, but you need to set up a valid signing identity
+ for the build environment.
+
\section1 Files and Attributions
The example uses icons from the Tango Icon Library:
diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
index cdd3a414a..fdddc4fb0 100644
--- a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "downloadmanagerwidget.h"
@@ -60,7 +13,6 @@
DownloadManagerWidget::DownloadManagerWidget(QWidget *parent)
: QWidget(parent)
- , m_numDownloads(0)
{
setupUi(this);
}
diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
index 221cd261f..67df492b9 100644
--- a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef DOWNLOADMANAGERWIDGET_H
#define DOWNLOADMANAGERWIDGET_H
@@ -77,7 +30,7 @@ private:
void add(DownloadWidget *downloadWidget);
void remove(DownloadWidget *downloadWidget);
- int m_numDownloads;
+ int m_numDownloads = 0;
};
#endif // DOWNLOADMANAGERWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
index 1ce97e0e9..2fb65e1a8 100644
--- a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "downloadwidget.h"
@@ -54,6 +7,8 @@
#include <QUrl>
#include <QWebEngineDownloadRequest>
+using namespace Qt::StringLiterals;
+
DownloadWidget::DownloadWidget(QWebEngineDownloadRequest *download, QWidget *parent)
: QFrame(parent)
, m_download(download)
@@ -85,12 +40,11 @@ inline QString DownloadWidget::withUnit(qreal bytes)
{
if (bytes < (1 << 10))
return tr("%L1 B").arg(bytes);
- else if (bytes < (1 << 20))
+ if (bytes < (1 << 20))
return tr("%L1 KiB").arg(bytes / (1 << 10), 0, 'f', 2);
- else if (bytes < (1 << 30))
+ if (bytes < (1 << 30))
return tr("%L1 MiB").arg(bytes / (1 << 20), 0, 'f', 2);
- else
- return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
+ return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
}
void DownloadWidget::updateWidget()
@@ -110,16 +64,14 @@ void DownloadWidget::updateWidget()
m_progressBar->setDisabled(false);
m_progressBar->setFormat(
tr("%p% - %1 of %2 downloaded - %3/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(totalBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(totalBytes),
+ withUnit(bytesPerSecond)));
} else {
m_progressBar->setValue(0);
m_progressBar->setDisabled(false);
m_progressBar->setFormat(
tr("unknown size - %1 downloaded - %2/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
}
break;
case QWebEngineDownloadRequest::DownloadCompleted:
@@ -127,16 +79,14 @@ void DownloadWidget::updateWidget()
m_progressBar->setDisabled(true);
m_progressBar->setFormat(
tr("completed - %1 downloaded - %2/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
break;
case QWebEngineDownloadRequest::DownloadCancelled:
m_progressBar->setValue(0);
m_progressBar->setDisabled(true);
m_progressBar->setFormat(
tr("cancelled - %1 downloaded - %2/s")
- .arg(withUnit(receivedBytes))
- .arg(withUnit(bytesPerSecond)));
+ .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
break;
case QWebEngineDownloadRequest::DownloadInterrupted:
m_progressBar->setValue(0);
@@ -148,11 +98,13 @@ void DownloadWidget::updateWidget()
}
if (state == QWebEngineDownloadRequest::DownloadInProgress) {
- static QIcon cancelIcon(QStringLiteral(":process-stop.png"));
+ static QIcon cancelIcon(QIcon::fromTheme(QIcon::ThemeIcon::ProcessStop,
+ QIcon(":process-stop.png"_L1)));
m_cancelButton->setIcon(cancelIcon);
m_cancelButton->setToolTip(tr("Stop downloading"));
} else {
- static QIcon removeIcon(QStringLiteral(":edit-clear.png"));
+ static QIcon removeIcon(QIcon::fromTheme(QIcon::ThemeIcon::EditClear,
+ QIcon(":edit-clear.png"_L1)));
m_cancelButton->setIcon(removeIcon);
m_cancelButton->setToolTip(tr("Remove from list"));
}
diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.h b/examples/webenginewidgets/simplebrowser/downloadwidget.h
index c59b1b4b7..bf24d242c 100644
--- a/examples/webenginewidgets/simplebrowser/downloadwidget.h
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef DOWNLOADWIDGET_H
#define DOWNLOADWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
index 61acee4d1..ff4811eae 100644
--- a/examples/webenginewidgets/simplebrowser/main.cpp
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -1,68 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "browser.h"
#include "browserwindow.h"
#include "tabwidget.h"
#include <QApplication>
+#include <QLoggingCategory>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
+using namespace Qt::StringLiterals;
+
QUrl commandLineUrlArgument()
{
const QStringList args = QCoreApplication::arguments();
for (const QString &arg : args.mid(1)) {
- if (!arg.startsWith(QLatin1Char('-')))
+ if (!arg.startsWith(u'-'))
return QUrl::fromUserInput(arg);
}
- return QUrl(QStringLiteral("https://www.qt.io"));
+ return QUrl(u"chrome://qt"_s);
}
int main(int argc, char **argv)
@@ -70,16 +26,19 @@ int main(int argc, char **argv)
QCoreApplication::setOrganizationName("QtExamples");
QApplication app(argc, argv);
- app.setWindowIcon(QIcon(QStringLiteral(":AppLogoColor.png")));
+ app.setWindowIcon(QIcon(u":AppLogoColor.png"_s));
+ QLoggingCategory::setFilterRules(u"qt.webenginecontext.debug=true"_s);
QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true);
+ QWebEngineProfile::defaultProfile()->settings()->setAttribute(
+ QWebEngineSettings::ScreenCaptureEnabled, true);
QUrl url = commandLineUrlArgument();
Browser browser;
- BrowserWindow *window = browser.createWindow();
+ BrowserWindow *window = browser.createHiddenWindow();
window->tabWidget()->setUrl(url);
-
+ window->show();
return app.exec();
}
diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.exe.manifest b/examples/webenginewidgets/simplebrowser/simplebrowser.exe.manifest
new file mode 100644
index 000000000..acc401776
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/simplebrowser.exe.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!--The ID below indicates application support for Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!--The ID below indicates application support for Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!--The ID below indicates application support for Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!--The ID below indicates application support for Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!--The ID below indicates application support for Windows 10/11 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+</compatibility>
+</assembly>
diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.pro b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
index 7584cfb01..8598d237a 100644
--- a/examples/webenginewidgets/simplebrowser/simplebrowser.pro
+++ b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
@@ -10,7 +10,8 @@ HEADERS += \
tabwidget.h \
webpage.h \
webpopupwindow.h \
- webview.h
+ webview.h \
+ webauthdialog.h
SOURCES += \
browser.cpp \
@@ -21,13 +22,20 @@ SOURCES += \
tabwidget.cpp \
webpage.cpp \
webpopupwindow.cpp \
- webview.cpp
+ webview.cpp \
+ webauthdialog.cpp
+
+win32 {
+ CONFIG -= embed_manifest_exe
+ QMAKE_MANIFEST = $$PWD/simplebrowser.exe.manifest
+}
FORMS += \
certificateerrordialog.ui \
passworddialog.ui \
downloadmanagerwidget.ui \
- downloadwidget.ui
+ downloadwidget.ui \
+ webauthdialog.ui
RESOURCES += data/simplebrowser.qrc
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
index b706a3ab7..f9037a8e1 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "tabwidget.h"
#include "webpage.h"
@@ -56,6 +9,8 @@
#include <QTabBar>
#include <QWebEngineProfile>
+using namespace Qt::StringLiterals;
+
TabWidget::TabWidget(QWebEngineProfile *profile, QWidget *parent)
: QTabWidget(parent)
, m_profile(profile)
@@ -79,9 +34,9 @@ TabWidget::TabWidget(QWebEngineProfile *profile, QWidget *parent)
if (profile->isOffTheRecord()) {
QLabel *icon = new QLabel(this);
- QPixmap pixmap(QStringLiteral(":ninja.png"));
+ QPixmap pixmap(u":ninja.png"_s);
icon->setPixmap(pixmap.scaledToHeight(tabBar->height()));
- setStyleSheet(QStringLiteral("QTabWidget::tab-bar { left: %1px; }").
+ setStyleSheet(u"QTabWidget::tab-bar { left: %1px; }"_s.
arg(icon->pixmap().width()));
}
}
@@ -115,7 +70,11 @@ void TabWidget::handleCurrentChanged(int index)
void TabWidget::handleContextMenuRequested(const QPoint &pos)
{
QMenu menu;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
+ menu.addAction(tr("New &Tab"), QKeySequence::AddTab, this, &TabWidget::createTab);
+#else
menu.addAction(tr("New &Tab"), this, &TabWidget::createTab, QKeySequence::AddTab);
+#endif
int index = tabBar()->tabAt(pos);
if (index != -1) {
QAction *action = menu.addAction(tr("Clone Tab"));
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h
index 06f3db829..a1a893b62 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.h
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef TABWIDGET_H
#define TABWIDGET_H
@@ -66,7 +19,7 @@ class TabWidget : public QTabWidget
Q_OBJECT
public:
- TabWidget(QWebEngineProfile *profile, QWidget *parent = nullptr);
+ explicit TabWidget(QWebEngineProfile *profile, QWidget *parent = nullptr);
WebView *currentWebView() const;
diff --git a/examples/webenginewidgets/simplebrowser/webauthdialog.cpp b/examples/webenginewidgets/simplebrowser/webauthdialog.cpp
new file mode 100644
index 000000000..85d944db6
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webauthdialog.cpp
@@ -0,0 +1,294 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "webauthdialog.h"
+
+#include <QVBoxLayout>
+#include <QRadioButton>
+#include <QLineEdit>
+#include <QTextEdit>
+#include <QPushButton>
+#include <QWebEngineView>
+
+WebAuthDialog::WebAuthDialog(QWebEngineWebAuthUxRequest *request, QWidget *parent)
+ : QDialog(parent), uxRequest(request), uiWebAuthDialog(new Ui::WebAuthDialog)
+{
+ uiWebAuthDialog->setupUi(this);
+
+ buttonGroup = new QButtonGroup(this);
+ buttonGroup->setExclusive(true);
+
+ scrollArea = new QScrollArea(this);
+ selectAccountWidget = new QWidget(this);
+ scrollArea->setWidget(selectAccountWidget);
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ selectAccountWidget->resize(400, 150);
+ selectAccountLayout = new QVBoxLayout(selectAccountWidget);
+ uiWebAuthDialog->m_mainVerticalLayout->addWidget(scrollArea);
+ selectAccountLayout->setAlignment(Qt::AlignTop);
+
+ updateDisplay();
+
+ connect(uiWebAuthDialog->buttonBox, &QDialogButtonBox::rejected, this,
+ qOverload<>(&WebAuthDialog::onCancelRequest));
+
+ connect(uiWebAuthDialog->buttonBox, &QDialogButtonBox::accepted, this,
+ qOverload<>(&WebAuthDialog::onAcceptRequest));
+ QAbstractButton *button = uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry);
+ connect(button, &QAbstractButton::clicked, this, qOverload<>(&WebAuthDialog::onRetry));
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+}
+
+WebAuthDialog::~WebAuthDialog()
+{
+ QList<QAbstractButton *> buttons = buttonGroup->buttons();
+ auto itr = buttons.begin();
+ while (itr != buttons.end()) {
+ QAbstractButton *radioButton = *itr;
+ delete radioButton;
+ itr++;
+ }
+
+ if (buttonGroup) {
+ delete buttonGroup;
+ buttonGroup = nullptr;
+ }
+
+ if (uiWebAuthDialog) {
+ delete uiWebAuthDialog;
+ uiWebAuthDialog = nullptr;
+ }
+
+ // selectAccountWidget and it's children will get deleted when scroll area is destroyed
+ if (scrollArea) {
+ delete scrollArea;
+ scrollArea = nullptr;
+ }
+}
+
+void WebAuthDialog::updateDisplay()
+{
+ switch (uxRequest->state()) {
+ case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
+ setupSelectAccountUI();
+ break;
+ case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
+ setupCollectPinUI();
+ break;
+ case QWebEngineWebAuthUxRequest::WebAuthUxState::FinishTokenCollection:
+ setupFinishCollectTokenUI();
+ break;
+ case QWebEngineWebAuthUxRequest::WebAuthUxState::RequestFailed:
+ setupErrorUI();
+ break;
+ default:
+ break;
+ }
+ adjustSize();
+}
+
+void WebAuthDialog::setupSelectAccountUI()
+{
+ uiWebAuthDialog->m_headingLabel->setText(tr("Choose a Passkey"));
+ uiWebAuthDialog->m_description->setText(tr("Which passkey do you want to use for ")
+ + uxRequest->relyingPartyId() + tr("? "));
+ uiWebAuthDialog->m_pinGroupBox->setVisible(false);
+ uiWebAuthDialog->m_mainVerticalLayout->removeWidget(uiWebAuthDialog->m_pinGroupBox);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
+
+ clearSelectAccountButtons();
+ scrollArea->setVisible(true);
+ selectAccountWidget->resize(this->width(), this->height());
+ QStringList userNames = uxRequest->userNames();
+ // Create radio buttons for each name
+ for (const QString &name : userNames) {
+ QRadioButton *radioButton = new QRadioButton(name);
+ selectAccountLayout->addWidget(radioButton);
+ buttonGroup->addButton(radioButton);
+ }
+
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Ok"));
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Ok)->setVisible(true);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(true);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
+}
+
+void WebAuthDialog::setupFinishCollectTokenUI()
+{
+ clearSelectAccountButtons();
+ uiWebAuthDialog->m_headingLabel->setText(tr("Use your security key with")
+ + uxRequest->relyingPartyId());
+ uiWebAuthDialog->m_description->setText(
+ tr("Touch your security key again to complete the request."));
+ uiWebAuthDialog->m_pinGroupBox->setVisible(false);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
+ scrollArea->setVisible(false);
+}
+void WebAuthDialog::setupCollectPinUI()
+{
+ clearSelectAccountButtons();
+ uiWebAuthDialog->m_mainVerticalLayout->addWidget(uiWebAuthDialog->m_pinGroupBox);
+ uiWebAuthDialog->m_pinGroupBox->setVisible(true);
+ uiWebAuthDialog->m_confirmPinLabel->setVisible(false);
+ uiWebAuthDialog->m_confirmPinLineEdit->setVisible(false);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Next"));
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Ok)->setVisible(true);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(true);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
+ scrollArea->setVisible(false);
+
+ QWebEngineWebAuthPinRequest pinRequestInfo = uxRequest->pinRequest();
+
+ if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Challenge) {
+ uiWebAuthDialog->m_headingLabel->setText(tr("PIN Required"));
+ uiWebAuthDialog->m_description->setText(tr("Enter the PIN for your security key"));
+ uiWebAuthDialog->m_confirmPinLabel->setVisible(false);
+ uiWebAuthDialog->m_confirmPinLineEdit->setVisible(false);
+ } else {
+ if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Set) {
+ uiWebAuthDialog->m_headingLabel->setText(tr("New PIN Required"));
+ uiWebAuthDialog->m_description->setText(tr("Set new PIN for your security key"));
+ } else {
+ uiWebAuthDialog->m_headingLabel->setText(tr("Change PIN Required"));
+ uiWebAuthDialog->m_description->setText(tr("Change PIN for your security key"));
+ }
+ uiWebAuthDialog->m_confirmPinLabel->setVisible(true);
+ uiWebAuthDialog->m_confirmPinLineEdit->setVisible(true);
+ }
+
+ QString errorDetails;
+ switch (pinRequestInfo.error) {
+ case QWebEngineWebAuthUxRequest::PinEntryError::NoError:
+ break;
+ case QWebEngineWebAuthUxRequest::PinEntryError::InternalUvLocked:
+ errorDetails = tr("Internal User Verification Locked ");
+ break;
+ case QWebEngineWebAuthUxRequest::PinEntryError::WrongPin:
+ errorDetails = tr("Wrong PIN");
+ break;
+ case QWebEngineWebAuthUxRequest::PinEntryError::TooShort:
+ errorDetails = tr("Too Short");
+ break;
+ case QWebEngineWebAuthUxRequest::PinEntryError::InvalidCharacters:
+ errorDetails = tr("Invalid Characters");
+ break;
+ case QWebEngineWebAuthUxRequest::PinEntryError::SameAsCurrentPin:
+ errorDetails = tr("Same as current PIN");
+ break;
+ }
+ if (!errorDetails.isEmpty()) {
+ errorDetails += tr(" ") + QString::number(pinRequestInfo.remainingAttempts)
+ + tr(" attempts remaining");
+ }
+ uiWebAuthDialog->m_pinEntryErrorLabel->setText(errorDetails);
+}
+
+void WebAuthDialog::onCancelRequest()
+{
+ uxRequest->cancel();
+}
+
+void WebAuthDialog::onAcceptRequest()
+{
+ switch (uxRequest->state()) {
+ case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
+ if (buttonGroup->checkedButton()) {
+ uxRequest->setSelectedAccount(buttonGroup->checkedButton()->text());
+ }
+ break;
+ case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
+ uxRequest->setPin(uiWebAuthDialog->m_pinLineEdit->text());
+ break;
+ default:
+ break;
+ }
+}
+
+void WebAuthDialog::setupErrorUI()
+{
+ clearSelectAccountButtons();
+ QString errorDescription;
+ QString errorHeading = tr("Something went wrong");
+ bool isVisibleRetry = false;
+ switch (uxRequest->requestFailureReason()) {
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::Timeout:
+ errorDescription = tr("Request Timeout");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyNotRegistered:
+ errorDescription = tr("Key not registered");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyAlreadyRegistered:
+ errorDescription = tr("You already registered this device."
+ "Try again with device");
+ isVisibleRetry = true;
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::SoftPinBlock:
+ errorDescription =
+ tr("The security key is locked because the wrong PIN was entered too many times."
+ "To unlock it, remove and reinsert it.");
+ isVisibleRetry = true;
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::HardPinBlock:
+ errorDescription =
+ tr("The security key is locked because the wrong PIN was entered too many times."
+ " You'll need to reset the security key.");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorRemovedDuringPinEntry:
+ errorDescription =
+ tr("Authenticator removed during verification. Please reinsert and try again");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingResidentKeys:
+ errorDescription = tr("Authenticator doesn't have resident key support");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingUserVerification:
+ errorDescription = tr("Authenticator missing user verification");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingLargeBlob:
+ errorDescription = tr("Authenticator missing Large Blob support");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::NoCommonAlgorithms:
+ errorDescription = tr("Authenticator missing Large Blob support");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::StorageFull:
+ errorDescription = tr("Storage Full");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::UserConsentDenied:
+ errorDescription = tr("User consent denied");
+ break;
+ case QWebEngineWebAuthUxRequest::RequestFailureReason::WinUserCancelled:
+ errorDescription = tr("User Cancelled Request");
+ break;
+ }
+
+ uiWebAuthDialog->m_headingLabel->setText(errorHeading);
+ uiWebAuthDialog->m_description->setText(errorDescription);
+ uiWebAuthDialog->m_description->adjustSize();
+ uiWebAuthDialog->m_pinGroupBox->setVisible(false);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry)->setVisible(isVisibleRetry);
+ if (isVisibleRetry)
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Retry)->setFocus();
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(true);
+ uiWebAuthDialog->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Close"));
+ scrollArea->setVisible(false);
+}
+
+void WebAuthDialog::onRetry()
+{
+ uxRequest->retry();
+}
+
+void WebAuthDialog::clearSelectAccountButtons()
+{
+ QList<QAbstractButton *> buttons = buttonGroup->buttons();
+ auto itr = buttons.begin();
+ while (itr != buttons.end()) {
+ QAbstractButton *radioButton = *itr;
+ selectAccountLayout->removeWidget(radioButton);
+ buttonGroup->removeButton(radioButton);
+ delete radioButton;
+ itr++;
+ }
+}
diff --git a/examples/webenginewidgets/simplebrowser/webauthdialog.h b/examples/webenginewidgets/simplebrowser/webauthdialog.h
new file mode 100644
index 000000000..47832c1bb
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webauthdialog.h
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef WEBAUTHDIALOG_H
+#define WEBAUTHDIALOG_H
+
+#include <QDialog>
+#include <QButtonGroup>
+#include <QScrollArea>
+#include "ui_webauthdialog.h"
+#include "qwebenginewebauthuxrequest.h"
+
+class WebAuthDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ WebAuthDialog(QWebEngineWebAuthUxRequest *request, QWidget *parent = nullptr);
+ ~WebAuthDialog();
+
+ void updateDisplay();
+
+private:
+ QWebEngineWebAuthUxRequest *uxRequest;
+ QButtonGroup *buttonGroup = nullptr;
+ QScrollArea *scrollArea = nullptr;
+ QWidget *selectAccountWidget = nullptr;
+ QVBoxLayout *selectAccountLayout = nullptr;
+
+ void setupSelectAccountUI();
+ void setupCollectPinUI();
+ void setupFinishCollectTokenUI();
+ void setupErrorUI();
+ void onCancelRequest();
+ void onRetry();
+ void onAcceptRequest();
+ void clearSelectAccountButtons();
+
+ Ui::WebAuthDialog *uiWebAuthDialog;
+};
+
+#endif // WEBAUTHDIALOG_H
diff --git a/examples/webenginewidgets/simplebrowser/webauthdialog.ui b/examples/webenginewidgets/simplebrowser/webauthdialog.ui
new file mode 100644
index 000000000..c8a0456d6
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webauthdialog.ui
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WebAuthDialog</class>
+ <widget class="QDialog" name="WebAuthDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>563</width>
+ <height>397</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>320</y>
+ <width>471</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_headingLabel">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>20</y>
+ <width>321</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Heading</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_description">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>60</y>
+ <width>491</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QWidget" name="layoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>100</y>
+ <width>471</width>
+ <height>171</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="m_mainVerticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="m_pinGroupBox">
+ <property name="title">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <widget class="QLabel" name="m_pinLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>58</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PIN</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="m_pinLineEdit">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>20</y>
+ <width>113</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_confirmPinLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>81</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Confirm PIN</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="m_confirmPinLineEdit">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>50</y>
+ <width>113</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_pinEntryErrorLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>80</y>
+ <width>441</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp
index 985e83ca2..807cdf0ff 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.cpp
+++ b/examples/webenginewidgets/simplebrowser/webpage.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "browserwindow.h"
#include "tabwidget.h"
@@ -60,6 +13,8 @@ WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
{
connect(this, &QWebEnginePage::selectClientCertificate, this, &WebPage::handleSelectClientCertificate);
connect(this, &QWebEnginePage::certificateError, this, &WebPage::handleCertificateError);
+ connect(this, &QWebEnginePage::desktopMediaRequested, this,
+ &WebPage::handleDesktopMediaRequest);
}
void WebPage::handleCertificateError(QWebEngineCertificateError error)
@@ -69,31 +24,14 @@ void WebPage::handleCertificateError(QWebEngineCertificateError error)
[this, error]() mutable { emit createCertificateErrorDialog(error); });
}
-inline QString questionForFeature(QWebEnginePage::Feature feature)
-{
- switch (feature) {
- case QWebEnginePage::Geolocation:
- return WebPage::tr("Allow %1 to access your location information?");
- case QWebEnginePage::MediaAudioCapture:
- return WebPage::tr("Allow %1 to access your microphone?");
- case QWebEnginePage::MediaVideoCapture:
- return WebPage::tr("Allow %1 to access your webcam?");
- case QWebEnginePage::MediaAudioVideoCapture:
- return WebPage::tr("Allow %1 to access your microphone and webcam?");
- case QWebEnginePage::MouseLock:
- return WebPage::tr("Allow %1 to lock your mouse cursor?");
- case QWebEnginePage::DesktopVideoCapture:
- return WebPage::tr("Allow %1 to capture video of your desktop?");
- case QWebEnginePage::DesktopAudioVideoCapture:
- return WebPage::tr("Allow %1 to capture audio and video of your desktop?");
- case QWebEnginePage::Notifications:
- return WebPage::tr("Allow %1 to show notification on your desktop?");
- }
- return QString();
-}
-
void WebPage::handleSelectClientCertificate(QWebEngineClientCertificateSelection selection)
{
// Just select one.
selection.select(selection.certificates().at(0));
}
+
+void WebPage::handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request)
+{
+ // select the primary screen
+ request.selectScreen(request.screensModel()->index(0));
+}
diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h
index e01d1e1eb..56740f817 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.h
+++ b/examples/webenginewidgets/simplebrowser/webpage.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WEBPAGE_H
#define WEBPAGE_H
@@ -54,13 +7,14 @@
#include <QWebEnginePage>
#include <QWebEngineRegisterProtocolHandlerRequest>
#include <QWebEngineCertificateError>
+#include <QWebEngineDesktopMediaRequest>
class WebPage : public QWebEnginePage
{
Q_OBJECT
public:
- WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
+ explicit WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
signals:
void createCertificateErrorDialog(QWebEngineCertificateError error);
@@ -68,6 +22,7 @@ signals:
private slots:
void handleCertificateError(QWebEngineCertificateError error);
void handleSelectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection);
+ void handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request);
};
#endif // WEBPAGE_H
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
index 566723e1f..bed956fd0 100644
--- a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "webpage.h"
#include "webpopupwindow.h"
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.h b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
index 9cecb28a7..0726bf0c2 100644
--- a/examples/webenginewidgets/simplebrowser/webpopupwindow.h
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WEBPOPUPWINDOW_H
#define WEBPOPUPWINDOW_H
@@ -66,7 +19,7 @@ class WebPopupWindow : public QWidget
Q_OBJECT
public:
- WebPopupWindow(QWebEngineProfile *profile);
+ explicit WebPopupWindow(QWebEngineProfile *profile);
WebView *view() const;
private slots:
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index 31be9f34c..08e044f70 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "browser.h"
#include "browserwindow.h"
@@ -56,6 +9,7 @@
#include "webview.h"
#include "ui_certificateerrordialog.h"
#include "ui_passworddialog.h"
+#include "webauthdialog.h"
#include <QContextMenuEvent>
#include <QDebug>
#include <QMenu>
@@ -64,9 +18,10 @@
#include <QTimer>
#include <QStyle>
+using namespace Qt::StringLiterals;
+
WebView::WebView(QWidget *parent)
: QWebEngineView(parent)
- , m_loadProgress(100)
{
connect(this, &QWebEngineView::loadStarted, [this]() {
m_loadProgress = 0;
@@ -104,10 +59,18 @@ WebView::WebView(QWidget *parent)
tr("Render process exited with code: %1\n"
"Do you want to reload the page ?").arg(statusCode));
if (btn == QMessageBox::Yes)
- QTimer::singleShot(0, [this] { reload(); });
+ QTimer::singleShot(0, this, &WebView::reload);
});
}
+WebView::~WebView()
+{
+ if (m_imageAnimationGroup)
+ delete m_imageAnimationGroup;
+
+ m_imageAnimationGroup = nullptr;
+}
+
inline QString questionForFeature(QWebEnginePage::Feature feature)
{
switch (feature) {
@@ -127,6 +90,8 @@ inline QString questionForFeature(QWebEnginePage::Feature feature)
return QObject::tr("Allow %1 to capture audio and video of your desktop?");
case QWebEnginePage::Notifications:
return QObject::tr("Allow %1 to show notification on your desktop?");
+ case QWebEnginePage::ClipboardReadWrite:
+ return QObject::tr("Allow %1 to read from and write to the clipboard?");
}
return QString();
}
@@ -144,6 +109,12 @@ void WebView::setPage(WebPage *page)
&WebView::handleProxyAuthenticationRequired);
disconnect(oldPage, &QWebEnginePage::registerProtocolHandlerRequested, this,
&WebView::handleRegisterProtocolHandlerRequested);
+ disconnect(oldPage, &QWebEnginePage::webAuthUxRequested, this,
+ &WebView::handleWebAuthUxRequested);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+ disconnect(oldPage, &QWebEnginePage::fileSystemAccessRequested, this,
+ &WebView::handleFileSystemAccessRequested);
+#endif
}
createWebActionTrigger(page,QWebEnginePage::Forward);
createWebActionTrigger(page,QWebEnginePage::Back);
@@ -159,6 +130,11 @@ void WebView::setPage(WebPage *page)
&WebView::handleProxyAuthenticationRequired);
connect(page, &QWebEnginePage::registerProtocolHandlerRequested, this,
&WebView::handleRegisterProtocolHandlerRequested);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+ connect(page, &QWebEnginePage::fileSystemAccessRequested, this,
+ &WebView::handleFileSystemAccessRequested);
+#endif
+ connect(page, &QWebEnginePage::webAuthUxRequested, this, &WebView::handleWebAuthUxRequested);
}
int WebView::loadProgress() const
@@ -186,15 +162,17 @@ QIcon WebView::favIcon() const
return favIcon;
if (m_loadProgress < 0) {
- static QIcon errorIcon(QStringLiteral(":dialog-error.png"));
+ static QIcon errorIcon(u":dialog-error.png"_s);
return errorIcon;
- } else if (m_loadProgress < 100) {
- static QIcon loadingIcon(QStringLiteral(":view-refresh.png"));
+ }
+ if (m_loadProgress < 100) {
+ static QIcon loadingIcon = QIcon::fromTheme(QIcon::ThemeIcon::ViewRefresh,
+ QIcon(":view-refresh.png"_L1));
return loadingIcon;
- } else {
- static QIcon defaultIcon(QStringLiteral(":text-html.png"));
- return defaultIcon;
}
+
+ static QIcon defaultIcon(u":text-html.png"_s);
+ return defaultIcon;
}
QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type)
@@ -232,15 +210,54 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
if (viewSource == actions.cend())
menu->addSeparator();
- QAction *action = new QAction(menu);
- action->setText("Open inspector in new window");
+ QAction *action = menu->addAction("Open inspector in new window");
connect(action, &QAction::triggered, [this]() { emit devToolsRequested(page()); });
-
- QAction *before(inspectElement == actions.cend() ? nullptr : *inspectElement);
- menu->insertAction(before, action);
} else {
(*inspectElement)->setText(tr("Inspect element"));
}
+
+ // add conext menu for image policy
+ QMenu *editImageAnimation = new QMenu(tr("Image animation policy"));
+
+ m_imageAnimationGroup = new QActionGroup(editImageAnimation);
+ m_imageAnimationGroup->setExclusive(true);
+
+ QAction *disableImageAnimation =
+ editImageAnimation->addAction(tr("Disable all image animation"));
+ disableImageAnimation->setCheckable(true);
+ m_imageAnimationGroup->addAction(disableImageAnimation);
+ connect(disableImageAnimation, &QAction::triggered, [this]() {
+ handleImageAnimationPolicyChange(QWebEngineSettings::DisallowImageAnimation);
+ });
+ QAction *allowImageAnimationOnce =
+ editImageAnimation->addAction(tr("Allow animated images, but only once"));
+ allowImageAnimationOnce->setCheckable(true);
+ m_imageAnimationGroup->addAction(allowImageAnimationOnce);
+ connect(allowImageAnimationOnce, &QAction::triggered,
+ [this]() { handleImageAnimationPolicyChange(QWebEngineSettings::AnimateImageOnce); });
+ QAction *allowImageAnimation = editImageAnimation->addAction(tr("Allow all animated images"));
+ allowImageAnimation->setCheckable(true);
+ m_imageAnimationGroup->addAction(allowImageAnimation);
+ connect(allowImageAnimation, &QAction::triggered, [this]() {
+ handleImageAnimationPolicyChange(QWebEngineSettings::AllowImageAnimation);
+ });
+
+ switch (page()->settings()->imageAnimationPolicy()) {
+ case QWebEngineSettings::AllowImageAnimation:
+ allowImageAnimation->setChecked(true);
+ break;
+ case QWebEngineSettings::AnimateImageOnce:
+ allowImageAnimationOnce->setChecked(true);
+ break;
+ case QWebEngineSettings::DisallowImageAnimation:
+ disableImageAnimation->setChecked(true);
+ break;
+ default:
+ allowImageAnimation->setChecked(true);
+ break;
+ }
+
+ menu->addMenu(editImageAnimation);
menu->popup(event->globalPos());
}
@@ -278,8 +295,8 @@ void WebView::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticato
passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
QString introMessage(tr("Enter username and password for \"%1\" at %2")
- .arg(auth->realm())
- .arg(requestUrl.toString().toHtmlEscaped()));
+ .arg(auth->realm(),
+ requestUrl.toString().toHtmlEscaped()));
passwordDialog.m_infoLabel->setText(introMessage);
passwordDialog.m_infoLabel->setWordWrap(true);
@@ -333,6 +350,32 @@ void WebView::handleProxyAuthenticationRequired(const QUrl &, QAuthenticator *au
}
}
+void WebView::handleWebAuthUxRequested(QWebEngineWebAuthUxRequest *request)
+{
+ if (m_authDialog)
+ delete m_authDialog;
+
+ m_authDialog = new WebAuthDialog(request, window());
+ m_authDialog->setModal(false);
+ m_authDialog->setWindowFlags(m_authDialog->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ connect(request, &QWebEngineWebAuthUxRequest::stateChanged, this, &WebView::onStateChanged);
+ m_authDialog->show();
+}
+
+void WebView::onStateChanged(QWebEngineWebAuthUxRequest::WebAuthUxState state)
+{
+ if (QWebEngineWebAuthUxRequest::WebAuthUxState::Completed == state
+ || QWebEngineWebAuthUxRequest::WebAuthUxState::Cancelled == state) {
+ if (m_authDialog) {
+ delete m_authDialog;
+ m_authDialog = nullptr;
+ }
+ } else {
+ m_authDialog->updateDisplay();
+ }
+}
+
//! [registerProtocolHandlerRequested]
void WebView::handleRegisterProtocolHandlerRequested(
QWebEngineRegisterProtocolHandlerRequest request)
@@ -347,3 +390,41 @@ void WebView::handleRegisterProtocolHandlerRequested(
request.reject();
}
//! [registerProtocolHandlerRequested]
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+void WebView::handleFileSystemAccessRequested(QWebEngineFileSystemAccessRequest request)
+{
+ QString accessType;
+ switch (request.accessFlags()) {
+ case QWebEngineFileSystemAccessRequest::Read:
+ accessType = "read";
+ break;
+ case QWebEngineFileSystemAccessRequest::Write:
+ accessType = "write";
+ break;
+ case QWebEngineFileSystemAccessRequest::Read | QWebEngineFileSystemAccessRequest::Write:
+ accessType = "read and write";
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ auto answer = QMessageBox::question(window(), tr("File system access request"),
+ tr("Give %1 %2 access to %3?")
+ .arg(request.origin().host())
+ .arg(accessType)
+ .arg(request.filePath().toString()));
+ if (answer == QMessageBox::Yes)
+ request.accept();
+ else
+ request.reject();
+}
+
+void WebView::handleImageAnimationPolicyChange(QWebEngineSettings::ImageAnimationPolicy policy)
+{
+ if (!page())
+ return;
+
+ page()->settings()->setImageAnimationPolicy(policy);
+}
+#endif // QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h
index 0dc7c33ad..c7e7f394c 100644
--- a/examples/webenginewidgets/simplebrowser/webview.h
+++ b/examples/webenginewidgets/simplebrowser/webview.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WEBVIEW_H
#define WEBVIEW_H
@@ -54,17 +7,25 @@
#include <QIcon>
#include <QWebEngineView>
#include <QWebEngineCertificateError>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+#include <QWebEngineFileSystemAccessRequest>
+#endif
#include <QWebEnginePage>
#include <QWebEngineRegisterProtocolHandlerRequest>
+#include <QWebEngineWebAuthUxRequest>
+#include <QWebEngineSettings>
+#include <QActionGroup>
class WebPage;
+class WebAuthDialog;
class WebView : public QWebEngineView
{
Q_OBJECT
public:
- WebView(QWidget *parent = nullptr);
+ explicit WebView(QWidget *parent = nullptr);
+ ~WebView();
void setPage(WebPage *page);
int loadProgress() const;
@@ -87,12 +48,20 @@ private slots:
void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth,
const QString &proxyHost);
void handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+ void handleFileSystemAccessRequested(QWebEngineFileSystemAccessRequest request);
+ void handleWebAuthUxRequested(QWebEngineWebAuthUxRequest *request);
+#endif
+ void handleImageAnimationPolicyChange(QWebEngineSettings::ImageAnimationPolicy policy);
private:
void createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction);
+ void onStateChanged(QWebEngineWebAuthUxRequest::WebAuthUxState state);
private:
- int m_loadProgress;
+ int m_loadProgress = 100;
+ WebAuthDialog *m_authDialog = nullptr;
+ QActionGroup *m_imageAnimationGroup = nullptr;
};
#endif
diff --git a/examples/webenginewidgets/spellchecker/CMakeLists.txt b/examples/webenginewidgets/spellchecker/CMakeLists.txt
index 1a0c76b06..3a5ea08ca 100644
--- a/examples/webenginewidgets/spellchecker/CMakeLists.txt
+++ b/examples/webenginewidgets/spellchecker/CMakeLists.txt
@@ -1,40 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(spellchecker LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/spellchecker")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(spellchecker
main.cpp
webview.cpp webview.h
)
+
set_target_properties(spellchecker PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(spellchecker PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-
# Resources:
set(spellchecker_resource_files
- "data/icon.svg"
"data/index.html"
"data/style.css"
)
@@ -66,4 +63,3 @@ foreach(dictFile ${dicts})
OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endforeach()
-
diff --git a/examples/webenginewidgets/spellchecker/data/icon.svg b/examples/webenginewidgets/spellchecker/data/icon.svg
deleted file mode 100644
index b90ff26dd..000000000
--- a/examples/webenginewidgets/spellchecker/data/icon.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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/spellchecker/data/index.html b/examples/webenginewidgets/spellchecker/data/index.html
index b6cec5fe0..f68d64bc4 100644
--- a/examples/webenginewidgets/spellchecker/data/index.html
+++ b/examples/webenginewidgets/spellchecker/data/index.html
@@ -6,28 +6,29 @@
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
- <form class="form">
- <img class="logo" src="icon.svg" alt="qtwebengine">
- <div class="header">
- <h1>Contact us</h1>
- <h2>We are here to help</h2>
- </div>
- <label>
- <span>First Name:</span><input id="firstname" type="text" name="name" />
- </label>
- <label>
- <span>Last Name:</span><input id="lastName" type="text" name="name" />
- </label>
- <label>
- <span>Email Address:</span><input id="email" type="text" name="email" />
- </label>
- <label>
- <span>Subject:</span><input id="subject" type="text" name="subject" />
- </label>
- <label>
- <span>Message:</span><textarea id="feedback" name="feedback"></textarea>
- </label>
- <input type="submit" value="Send" />
- </form>
+ <main>
+ <form class="form">
+ <div class="header">
+ <h1>Contact us</h1>
+ <h2>We are here to help</h2>
+ </div>
+ <label>
+ <span>First Name</span><input id="firstname" type="text" name="name" />
+ </label>
+ <label>
+ <span>Last Name</span><input id="lastName" type="text" name="name" />
+ </label>
+ <label>
+ <span>Email</span><input id="email" type="text" name="email" />
+ </label>
+ <label>
+ <span>Subject</span><input id="subject" type="text" name="subject" />
+ </label>
+ <label>
+ <span>Message</span><textarea id="feedback" name="feedback"></textarea>
+ </label>
+ <input type="submit" value="Send" />
+ </form>
+ </main>
</body>
</html>
diff --git a/examples/webenginewidgets/spellchecker/data/spellchecker.qrc b/examples/webenginewidgets/spellchecker/data/spellchecker.qrc
index a9c76cc7e..b5e0b1fe0 100644
--- a/examples/webenginewidgets/spellchecker/data/spellchecker.qrc
+++ b/examples/webenginewidgets/spellchecker/data/spellchecker.qrc
@@ -2,6 +2,5 @@
<qresource prefix="/">
<file>index.html</file>
<file>style.css</file>
- <file>icon.svg</file>
</qresource>
</RCC>
diff --git a/examples/webenginewidgets/spellchecker/data/style.css b/examples/webenginewidgets/spellchecker/data/style.css
index 7b6736f1f..38873c5a0 100644
--- a/examples/webenginewidgets/spellchecker/data/style.css
+++ b/examples/webenginewidgets/spellchecker/data/style.css
@@ -1,90 +1,119 @@
-.logo {
- width: 50px;
- height: 50px;
- float: left;
- margin: 20px 20px 0px 20px;
- -webkit-animation:spin 8s linear infinite;
+@import url('https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap');
+* {
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+}
+
+
+body {
+ width: 100%;
+ padding: 0px;
+ margin: 0px;
}
-@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
.header {
- display: inline
+ display: inline;
+}
+
+.main {
+ max-width: 100%;
}
.form {
- width: 450px;
- height: 600px;
- background: -webkit-linear-gradient(bottom, #ddd, #fff);
- border: 1px solid #999;
- border-radius: 12px;
- color: #46a;
- font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
- font-size: 14px;
- font-style: italic;
- font-weight: bold;
- margin: auto;
- padding: 10px;
- position: relative;
- line-height: 26px;
- text-decoration: none;
- -webkit-box-shadow: 0px 0px 5px #444;
+ width: 100%;
+ height: 100%;
+ background: #fff;
+ border: 0px solid #999;
+ border-radius: 8px;
+ color: #46a;
+ font-family: 'Titillium Web', sans-serif;
+ font-size: 1rem;
+ margin: auto;
+ padding: 40px;
+ position: relative;
+ line-height: 26px;
+ text-decoration: none;
}
h1 {
- padding-left:40px;
- color: #46a2da;
+ padding-left: 20px;
+ color: #00414A;
+ font-size: 2.5rem;
+ font-weight: 700;
+ margin-bottom: 1rem;
}
h2 {
- color: #80c342;
- font-size: 13px;
- margin-top: -20px;
+ padding-left: 20px;
+ color: #00414A;
+ font-size: 1.125rem;
+ font-weight: 400;
+ font-style: italic;
+ margin-bottom: 1.75rem;
}
span {
- margin-left: 20px;
+ font-size: 1.5rem;
+ margin-left: 20px;
+ color: #00414A;
+ font-weight: 700;
}
input {
- width: 400px;
- display: block;
- border: 1px solid #999;
- height: 25px;
- margin-left: 20px;
- margin-bottom: 10px;
- padding-left: 10px;
- -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
+ width: 90%;
+ display: block;
+ height: 2.25rem;
+ margin-left: 20px;
+ margin-right: 20px;
+ margin-bottom: 8px;
+ padding-left: 10px;
+ box-shadow: 1px 1px 4px 0px rgba(0, 0, 0, 0.15);
+ border-radius: var(--radius-radius-minimal, 0.25rem);
+ border: 1px solid var(--color-background-normal, #CCC);
+ background: var(--color-text-input-background, #FFF);
}
textarea {
- width: 400px;
- max-width: 400px;
- height: 180px;
- max-height: 400px;
- display: block;
- margin-left: 20px;
- padding-left: 10px;
- padding-right: 10px;
- -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
+ width: 90%;
+ max-width: 90%;
+ height: 10rem;
+ max-height: 14rem;
+ display: block;
+ margin-left: 20px;
+ margin-right: 20px;
+ padding-left: 10px;
+ padding-top: 10px;
+ box-shadow: 1px 1px 4px 0px rgba(0, 0, 0, 0.15);
+ border-radius: var(--radius-radius-minimal, 0.25rem);
+ border: 1px solid var(--color-background-normal, #CCC);
+ background: var(--color-text-input-background, #FFF);
}
input:focus, textarea:focus {
- outline:none;
- border: 1px solid #46a2da;
+ outline: none;
+ border: 1px solid #00414A;
}
input[type=submit] {
- width: 100px;
- left: 170px;
- bottom: 10px;
- background: #46a2da;
- color: #fff;
- height: 30px;
- position: absolute;
- border-radius: 14px;
+ display: flex;
+ align-items: center;
+ justify-content: center; /* Add this to horizontally center the content */
+ padding: 0.4444em 0.8889em;
+ height: 2.4em;
+ cursor: pointer;
+ width: 6.5rem;
+ background: #00414A;
+ color: #fff;
+ border-radius: 4px;
+ margin-top: 28px;
+ font-family: 'Titillium Web', sans-serif;
+ font-size: 1.125rem;
+ font-weight: 400;
+ transition: color 300ms ease-out, border 300ms ease-out;
}
input[type=submit]:hover {
- background: #80c342;
+ background: #19545C;
}
diff --git a/examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.png b/examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.png
index cc4e74946..1cbe9e6d3 100644
--- a/examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.png
+++ b/examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.png
Binary files differ
diff --git a/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
index ecdb1c818..1d9d7b73c 100644
--- a/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
+++ b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
@@ -1,35 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/spellchecker
\title WebEngine Widgets Spellchecker Example
\ingroup webengine-widgetexamples
\brief Integrates a spellchecker into a simple HTML form.
+ \examplecategory {Web Technologies}
\image spellchecker-example.png
diff --git a/examples/webenginewidgets/spellchecker/main.cpp b/examples/webenginewidgets/spellchecker/main.cpp
index c2951fe00..55e06a874 100644
--- a/examples/webenginewidgets/spellchecker/main.cpp
+++ b/examples/webenginewidgets/spellchecker/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "webview.h"
#include <QApplication>
@@ -58,7 +11,7 @@ int main(int argc, char *argv[])
WebView view;
view.setUrl(QUrl(QStringLiteral("qrc:/index.html")));
- view.resize(500, 640);
+ view.resize(500, 750);
view.show();
return app.exec();
diff --git a/examples/webenginewidgets/spellchecker/spellchecker.pro b/examples/webenginewidgets/spellchecker/spellchecker.pro
index d652e4b1f..a720776ca 100644
--- a/examples/webenginewidgets/spellchecker/spellchecker.pro
+++ b/examples/webenginewidgets/spellchecker/spellchecker.pro
@@ -1,4 +1,3 @@
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093
QT_FOR_CONFIG += webenginecore
TEMPLATE = app
@@ -10,7 +9,7 @@ QT += webenginewidgets
}
qtConfig(webengine-native-spellchecker) {
- error("Spellcheck example can not be built when using native OS dictionaries.")
+ error("Spellchecker example can not be built when using native OS dictionaries.")
}
HEADERS += \
@@ -34,7 +33,7 @@ DISTFILES += \
target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/spellchecker
INSTALLS += target
-qtPrepareTool(CONVERT_TOOL, qwebengine_convert_dict)
+qtPrepareTool(CONVERT_TOOL, qwebengine_convert_dict, "", "", $$[QT_INSTALL_LIBEXECS])
debug_and_release {
CONFIG(debug, debug|release): DICTIONARIES_DIR = debug/qtwebengine_dictionaries
diff --git a/examples/webenginewidgets/spellchecker/webview.cpp b/examples/webenginewidgets/spellchecker/webview.cpp
index b532dd417..388146d31 100644
--- a/examples/webenginewidgets/spellchecker/webview.cpp
+++ b/examples/webenginewidgets/spellchecker/webview.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "webview.h"
#include <QContextMenuEvent>
diff --git a/examples/webenginewidgets/spellchecker/webview.h b/examples/webenginewidgets/spellchecker/webview.h
index 8c877b6e4..598f8b830 100644
--- a/examples/webenginewidgets/spellchecker/webview.h
+++ b/examples/webenginewidgets/spellchecker/webview.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WEBVIEW_H
#define WEBVIEW_H
diff --git a/examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING b/examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING
deleted file mode 100644
index 220881da6..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/3rdparty/COPYING
+++ /dev/null
@@ -1 +0,0 @@
-The icons in this repository are herefore released into the Public Domain.
diff --git a/examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json b/examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json
deleted file mode 100644
index f779da7e2..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/3rdparty/qt_attribution.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "Id": "stylesheetbrowser-tango",
- "Name": "Tango Icon Library",
- "QDocModule": "qtwebengine",
- "QtUsage": "Used in WebEngine StyleSheet Browser example.",
-
- "QtParts": [ "examples" ],
- "Description": "Selected icons from the Tango Icon Library",
- "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
- "Version": "0.8.90",
- "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
- "LicenseId": "urn:dje:license:public-domain",
- "License": "Public Domain",
- "LicenseFile": "COPYING",
- "Copyright": "Ulisse Perusin <uli.peru@gmail.com>
-Steven Garrity <sgarrity@silverorange.com>
-Lapo Calamandrei <calamandrei@gmail.com>
-Ryan Collier <rcollier@novell.com>
-Rodney Dawes <dobey@novell.com>
-Andreas Nilsson <nisses.mail@home.se>
-Tuomas Kuosmanen <tigert@tigert.com>
-Garrett LeSage <garrett@novell.com>
-Jakub Steiner <jimmac@novell.com>"
-}
diff --git a/examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.png b/examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.png
deleted file mode 100644
index cab4d02c7..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/3rdparty/view-refresh.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt b/examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt
deleted file mode 100644
index e0a1723f1..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/CMakeLists.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(stylesheetbrowser LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/stylesheetbrowser")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
-
-qt_add_executable(stylesheetbrowser
- main.cpp
- mainwindow.cpp mainwindow.h mainwindow.ui
- stylesheetdialog.cpp stylesheetdialog.h stylesheetdialog.ui
-)
-set_target_properties(stylesheetbrowser PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(stylesheetbrowser PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineWidgets
-)
-
-
-# Resources:
-set(stylesheetbrowser_resource_files
- "3rdparty/view-refresh.png"
-)
-
-qt_add_resources(stylesheetbrowser "stylesheetbrowser"
- PREFIX
- "/"
- BASE
- "3rdparty"
- FILES
- ${stylesheetbrowser_resource_files}
-)
-
-install(TARGETS stylesheetbrowser
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.png b/examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.png
deleted file mode 100644
index 32c7c43ed..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/doc/images/stylesheetbrowser.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc b/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
deleted file mode 100644
index 5b271bafb..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/doc/src/stylesheetbrowser.qdoc
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginewidgets/stylesheetbrowser
- \title WebEngine StyleSheet Browser Example
- \ingroup webengine-widgetexamples
- \brief Demonstrates how to inject CSS into web pages using user scripts.
-
- \image stylesheetbrowser.png
-
- \e {StyleSheet Browser} demonstrates how to use the \l{Qt WebEngine Widgets C++ Classes}
- {Qt WebEngine C++ classes} to inject user stylesheets into web pages.
-
- \include examples-run.qdocinc
-
- \section1 Working With Stylesheets
-
- We use JavaScript to create and append CSS elements to the documents.
- After declaring the script source, QWebEnginePage::runJavaScript() can run it
- immediately and apply newly created styles on the current content of the web view.
- Encapsulating the script into a QWebEngineScript and adding it to the script collection
- of QWebEnginePage makes its effect permanent.
-
- \quotefromfile webenginewidgets/stylesheetbrowser/mainwindow.cpp
- \skipto MainWindow::insertStyleSheet
- \printuntil /^\}/
-
- Removing stylesheets can be done similarly:
-
- \quotefromfile webenginewidgets/stylesheetbrowser/mainwindow.cpp
- \skipto MainWindow::removeStyleSheet
- \printuntil /^\}/
-
- \section1 Files and Attributions
-
- The example uses icons from the Tango Icon Library:
-
- \table
- \row
- \li \l{stylesheetbrowser-tango}{Tango Icon Library}
- \li Public Domain
- \endtable
-*/
diff --git a/examples/webenginewidgets/stylesheetbrowser/main.cpp b/examples/webenginewidgets/stylesheetbrowser/main.cpp
deleted file mode 100644
index 571fccb11..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/main.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 "stylesheetdialog.h"
-#include <QApplication>
-#include <QUrl>
-
-int main(int argc, char *argv[])
-{
- qRegisterMetaType<StyleSheet>("StyleSheet");
-
- QCoreApplication::setOrganizationName("QtExamples");
- QApplication a(argc, argv);
- MainWindow w(QUrl("http://qt.io"));
- w.show();
- return a.exec();
-}
diff --git a/examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp b/examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp
deleted file mode 100644
index bdf3c56bf..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/mainwindow.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 "stylesheetdialog.h"
-#include "ui_mainwindow.h"
-
-static QMap<QString, QString> defaultStyleSheets = {
- {"Upside down", "body { -webkit-transform: rotate(180deg); }"}
-};
-
-MainWindow::MainWindow(const QUrl &url) :
- QMainWindow(),
- ui(new Ui::MainWindow)
-{
- ui->setupUi(this);
-
- connect(ui->urlBar, &QLineEdit::returnPressed, this, &MainWindow::urlEntered);
- connect(ui->webEngineView, &QWebEngineView::urlChanged, this, &MainWindow::urlChanged);
- connect(ui->settingsButton, &QPushButton::clicked, this, &MainWindow::showStyleSheetsDialog);
- connect(ui->reloadButton, &QPushButton::clicked, this, &MainWindow::reloadRequested);
-
- QSettings settings;
- settings.beginGroup("styleSheets");
- QStringList styleSheets = settings.allKeys();
- if (styleSheets.empty()) {
- // Add back default style sheets if the user cleared them out
- loadDefaultStyleSheets();
- } else {
- for (auto name : qAsConst(styleSheets)) {
- StyleSheet styleSheet = settings.value(name).value<StyleSheet>();
- if (styleSheet.second)
- insertStyleSheet(name, styleSheet.first, false);
- }
- }
- settings.endGroup();
-
- ui->webEngineView->setUrl(url);
-}
-
-MainWindow::~MainWindow()
-{
- delete ui;
-}
-
-void MainWindow::insertStyleSheet(const QString &name, const QString &source, bool immediately)
-{
- QWebEngineScript script;
- QString s = QString::fromLatin1("(function() {"\
- " css = document.createElement('style');"\
- " css.type = 'text/css';"\
- " css.id = '%1';"\
- " document.head.appendChild(css);"\
- " css.innerText = '%2';"\
- "})()").arg(name).arg(source.simplified());
- if (immediately)
- ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
-
- script.setName(name);
- script.setSourceCode(s);
- script.setInjectionPoint(QWebEngineScript::DocumentReady);
- script.setRunsOnSubFrames(true);
- script.setWorldId(QWebEngineScript::ApplicationWorld);
- ui->webEngineView->page()->scripts().insert(script);
-}
-
-void MainWindow::removeStyleSheet(const QString &name, bool immediately)
-{
- QString s = QString::fromLatin1("(function() {"\
- " var element = document.getElementById('%1');"\
- " element.outerHTML = '';"\
- " delete element;"\
- "})()").arg(name);
- if (immediately)
- ui->webEngineView->page()->runJavaScript(s, QWebEngineScript::ApplicationWorld);
-
- const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
- if (!scripts.isEmpty())
- ui->webEngineView->page()->scripts().remove(scripts.first());
-}
-
-bool MainWindow::hasStyleSheet(const QString &name)
-{
- const QList<QWebEngineScript> scripts = ui->webEngineView->page()->scripts().find(name);
- return !scripts.isEmpty();
-}
-
-void MainWindow::loadDefaultStyleSheets()
-{
- QSettings settings;
- settings.beginGroup("styleSheets");
-
- auto it = defaultStyleSheets.constBegin();
- while (it != defaultStyleSheets.constEnd()) {
- settings.setValue(it.key(), QVariant::fromValue(qMakePair(it.value(), true)));
- insertStyleSheet(it.key(), it.value(), false);
- ++it;
- }
-
- settings.endGroup();
-}
-
-void MainWindow::urlEntered()
-{
- ui->webEngineView->setUrl(QUrl::fromUserInput(ui->urlBar->text()));
-}
-
-void MainWindow::urlChanged(const QUrl &url)
-{
- ui->urlBar->setText(url.toString());
-}
-
-void MainWindow::showStyleSheetsDialog()
-{
- StylesheetDialog *dialog = new StylesheetDialog(this);
- dialog->show();
-}
-
-void MainWindow::reloadRequested()
-{
- ui->webEngineView->reload();
-}
diff --git a/examples/webenginewidgets/stylesheetbrowser/mainwindow.h b/examples/webenginewidgets/stylesheetbrowser/mainwindow.h
deleted file mode 100644
index c39735af8..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/mainwindow.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 <QMainWindow>
-#include <QSettings>
-#include <QWebEngineScriptCollection>
-
-QT_BEGIN_NAMESPACE
-namespace Ui {
-class MainWindow;
-}
-QT_END_NAMESPACE
-
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-
-public:
- explicit MainWindow(const QUrl &url);
- ~MainWindow();
-
- void insertStyleSheet(const QString &name, const QString &source, bool immediately);
- void removeStyleSheet(const QString &name, bool immediately);
- bool hasStyleSheet(const QString &name);
- void loadDefaultStyleSheets();
-
-private slots:
- void urlEntered();
- void urlChanged(const QUrl &url);
- void showStyleSheetsDialog();
- void reloadRequested();
-
-private:
- Ui::MainWindow *ui;
-};
-
-#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/stylesheetbrowser/mainwindow.ui b/examples/webenginewidgets/stylesheetbrowser/mainwindow.ui
deleted file mode 100644
index bc68c16bb..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/mainwindow.ui
+++ /dev/null
@@ -1,133 +0,0 @@
-<?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>713</width>
- <height>455</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>StyleSheet Browser</string>
- </property>
- <property name="unifiedTitleAndToolBarOnMac">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="centralWidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QWidget" name="webContentsWidget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QWidget" name="urlBarWidget" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLineEdit" name="urlBar"/>
- </item>
- <item>
- <widget class="QPushButton" name="reloadButton">
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="stylesheetbrowser.qrc">
- <normaloff>:/view-refresh.png</normaloff>:/view-refresh.png</iconset>
- </property>
- <property name="shortcut">
- <string>Ctrl+R</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="settingsButton">
- <property name="text">
- <string>Settings</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QWebEngineView" name="webEngineView" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="url" stdset="0">
- <url>
- <string>about:blank</string>
- </url>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QMenuBar" name="menuBar">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>713</width>
- <height>20</height>
- </rect>
- </property>
- </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <customwidgets>
- <customwidget>
- <class>QWebEngineView</class>
- <extends>QWidget</extends>
- <header location="global">QtWebEngineWidgets/QWebEngineView</header>
- </customwidget>
- </customwidgets>
- <resources>
- <include location="stylesheetbrowser.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc b/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc
deleted file mode 100644
index a1cebd6a7..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetbrowser.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file alias="view-refresh.png">3rdparty/view-refresh.png</file>
- </qresource>
-</RCC>
diff --git a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h b/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h
deleted file mode 100644
index 3bf3219ca..000000000
--- a/examples/webenginewidgets/stylesheetbrowser/stylesheetdialog.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 STYLESHEETDIALOG_H
-#define STYLESHEETDIALOG_H
-
-#include <QDialog>
-#include <QListWidgetItem>
-
-QT_BEGIN_NAMESPACE
-namespace Ui {
-class StylesheetDialog;
-}
-QT_END_NAMESPACE
-
-typedef QPair<QString, bool> StyleSheet; // <source, isEnabled>
-Q_DECLARE_METATYPE(StyleSheet);
-
-class StylesheetDialog : public QDialog
-{
- Q_OBJECT
-
-public:
- explicit StylesheetDialog(QWidget *parent = 0);
- ~StylesheetDialog();
-
-private slots:
- void currentStyleSheetChanged(QListWidgetItem *current, QListWidgetItem *previous);
- void listItemClicked(QListWidgetItem *item);
- void fileNameChanged(const QString &text);
-
- void addButtonClicked();
- void removeButtonClicked();
-
-private:
- Ui::StylesheetDialog *ui;
-};
-
-#endif // STYLESHEETDIALOG_H
diff --git a/examples/webenginewidgets/videoplayer/CMakeLists.txt b/examples/webenginewidgets/videoplayer/CMakeLists.txt
index 61f4e40c6..0aff069d7 100644
--- a/examples/webenginewidgets/videoplayer/CMakeLists.txt
+++ b/examples/webenginewidgets/videoplayer/CMakeLists.txt
@@ -1,21 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(videoplayer LANGUAGES CXX)
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+ set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/videoplayer")
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS Core Gui WebEngineWidgets)
qt_add_executable(videoplayer
fullscreennotification.cpp fullscreennotification.h
@@ -23,17 +20,18 @@ qt_add_executable(videoplayer
main.cpp
mainwindow.cpp mainwindow.h
)
+
set_target_properties(videoplayer PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(videoplayer PUBLIC
Qt::Core
Qt::Gui
Qt::WebEngineWidgets
)
-
# Resources:
set(videoplayer_resource_files
"data/index.html"
diff --git a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc
index 256a69baf..931f08558 100644
--- a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc
+++ b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example webenginewidgets/videoplayer
+ \examplecategory {Web Technologies}
\title WebEngine Widgets Video Player Example
\ingroup webengine-widgetexamples
\brief Displays full screen video using \l QWebEngineView.
diff --git a/examples/webenginewidgets/videoplayer/fullscreennotification.cpp b/examples/webenginewidgets/videoplayer/fullscreennotification.cpp
index dbbf4660d..effd85ded 100644
--- a/examples/webenginewidgets/videoplayer/fullscreennotification.cpp
+++ b/examples/webenginewidgets/videoplayer/fullscreennotification.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "fullscreennotification.h"
diff --git a/examples/webenginewidgets/videoplayer/fullscreennotification.h b/examples/webenginewidgets/videoplayer/fullscreennotification.h
index 31fa0b59d..eebe3b85d 100644
--- a/examples/webenginewidgets/videoplayer/fullscreennotification.h
+++ b/examples/webenginewidgets/videoplayer/fullscreennotification.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef FULLSCREENNOTIFICATION_H
#define FULLSCREENNOTIFICATION_H
diff --git a/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp b/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp
index fbc899d83..fe2e72d86 100644
--- a/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp
+++ b/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "fullscreenwindow.h"
diff --git a/examples/webenginewidgets/videoplayer/fullscreenwindow.h b/examples/webenginewidgets/videoplayer/fullscreenwindow.h
index a5d53bcd8..d7af0b655 100644
--- a/examples/webenginewidgets/videoplayer/fullscreenwindow.h
+++ b/examples/webenginewidgets/videoplayer/fullscreenwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef FULLSCREENWINDOW_H
#define FULLSCREENWINDOW_H
diff --git a/examples/webenginewidgets/videoplayer/main.cpp b/examples/webenginewidgets/videoplayer/main.cpp
index 4a0fedb7b..550546130 100644
--- a/examples/webenginewidgets/videoplayer/main.cpp
+++ b/examples/webenginewidgets/videoplayer/main.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
#include <QApplication>
diff --git a/examples/webenginewidgets/videoplayer/mainwindow.cpp b/examples/webenginewidgets/videoplayer/mainwindow.cpp
index e930041a8..7de2446f1 100644
--- a/examples/webenginewidgets/videoplayer/mainwindow.cpp
+++ b/examples/webenginewidgets/videoplayer/mainwindow.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "mainwindow.h"
diff --git a/examples/webenginewidgets/videoplayer/mainwindow.h b/examples/webenginewidgets/videoplayer/mainwindow.h
index cdbe5d98e..3138800b5 100644
--- a/examples/webenginewidgets/videoplayer/mainwindow.h
+++ b/examples/webenginewidgets/videoplayer/mainwindow.h
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
diff --git a/examples/webenginewidgets/webenginewidgets.pro b/examples/webenginewidgets/webenginewidgets.pro
index f783fc681..2a24686cf 100644
--- a/examples/webenginewidgets/webenginewidgets.pro
+++ b/examples/webenginewidgets/webenginewidgets.pro
@@ -1,27 +1,26 @@
-QT_FOR_CONFIG += webenginecore webenginecore-private
+QT_FOR_CONFIG += webenginecore webenginecore-private network-private
TEMPLATE=subdirs
SUBDIRS += \
- minimal \
contentmanipulation \
cookiebrowser \
notifications \
simplebrowser \
- stylesheetbrowser \
- videoplayer \
- webui
+ push-notifications \
+ videoplayer
qtConfig(webengine-geolocation): SUBDIRS += maps
-qtConfig(webengine-webchannel): SUBDIRS += markdowneditor
+qtConfig(webengine-webchannel): SUBDIRS += recipebrowser
qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printme html2pdf
}
-#qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
-# SUBDIRS += spellchecker
-#} else {
-# message("Spellcheck example will not be built because it depends on usage of Hunspell dictionaries.")
-#}
+qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
+ SUBDIRS += spellchecker
+} else {
+ message("Spellchecker example will not be built because it depends on usage of Hunspell dictionaries.")
+}
+qtConfig(ssl): SUBDIRS += clientcertificate
diff --git a/examples/webenginewidgets/webui/CMakeLists.txt b/examples/webenginewidgets/webui/CMakeLists.txt
deleted file mode 100644
index 4d8123e1f..000000000
--- a/examples/webenginewidgets/webui/CMakeLists.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(webui LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginewidgets/webui")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineWidgets)
-
-qt_add_executable(webui
- main.cpp
- webuihandler.cpp webuihandler.h
-)
-set_target_properties(webui PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-target_link_libraries(webui PUBLIC
- Qt::Core
- Qt::Gui
- Qt::WebEngineWidgets
-)
-
-
-# Resources:
-set(webui_resource_files
- "about.html"
-)
-
-qt_add_resources(webui "webui"
- PREFIX
- "/"
- FILES
- ${webui_resource_files}
-)
-
-install(TARGETS webui
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/webenginewidgets/webui/about.html b/examples/webenginewidgets/webui/about.html
deleted file mode 100644
index 7b5a58969..000000000
--- a/examples/webenginewidgets/webui/about.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Qt WebEngine WebUI Example</title>
- <style>
- html {
- background: #f0f0f0;
- color: #303030;
- font: 16px system-ui;
- height: 100%;
- }
-
- body {
- margin: 0;
- padding: 0;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: stretch;
- }
-
- body > * {
- padding-left: 20px;
- padding-right: 20px;
- }
-
- header {
- flex: none;
- display: flex;
- align-items: center;
- background: #f0fff0;
- border-bottom: 1px solid #e0e0e0;
- padding-top: 20px;
- padding-bottom: 20px;
- }
-
- header > h1 {
- font: bold 20px system-ui;
- margin-left: 18px;
- }
-
- main {
- flex: auto;
- }
-
- footer {
- flex: none;
- display: flex;
- justify-content: center;
- padding-bottom: 20px;
- }
-
- button {
- background: #41cd52;
- color: #f0f0f0;
- font: 16px system-ui;
- border: 0;
- box-shadow: 0px 1px 3px rgb(0,0,0,0.5);
- cursor: pointer;
- margin: 0 0 1px;
- padding: 10px 24px;
- }
-
- button:hover {
- background: #50dc61;
- }
-
- button:active {
- background: #50dc61;
- box-shadow: 0px 1px 2px rgb(0,0,0,0.5);
- margin: 1px 0 0;
- }
-
- button:focus {
- outline: 0;
- }
-
- </style>
- </head>
- <body>
- <header>
- <img width="48px" height="48px"
- src="qrc:/qt-project.org/qmessagebox/images/qtlogo-64.png">
- <h1>WebEngine Widgets<br>WebUI Example</h1>
- </header>
- <main>
- <p>
- Aside from the built-in schemes, such as <code>http</code> and
- <code>qrc</code>, Qt WebEngine may be extended with <em>custom
- schemes</em> by creating <em>custom scheme handlers</em>.
- </p>
-
- <p>
- This is a simple HTML page loaded from a custom scheme and
- displayed by a <code>QWebEngineView</code>. Even the Quit button
- below is a standard HTML <code>&lt;button&gt;</code> element.
- </p>
-
- <p>
- Read the documentation to find out
- </p>
- <ul>
- <li>
- <p>
- How to create a custom scheme handler which serves HTML
- and handles HTML form submissions.
- </p>
- </li>
- <li>
- <p>
- How to prevent ordinary web content from accessing the
- custom scheme.
- </p>
- </li>
- <li>
- <p>
- How to prevent any other scheme from submitting HTML
- form data.
- </p>
- </li>
- </ul>
- </main>
- <footer>
- <form action="" method="post">
- <button name="quit">Quit</button>
- </form>
- </footer>
- </body>
-</html>
diff --git a/examples/webenginewidgets/webui/doc/images/webui-example.png b/examples/webenginewidgets/webui/doc/images/webui-example.png
deleted file mode 100644
index 84e2c7fc3..000000000
--- a/examples/webenginewidgets/webui/doc/images/webui-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/webui/doc/src/webui.qdoc b/examples/webenginewidgets/webui/doc/src/webui.qdoc
deleted file mode 100644
index 949b358a7..000000000
--- a/examples/webenginewidgets/webui/doc/src/webui.qdoc
+++ /dev/null
@@ -1,165 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example webenginewidgets/webui
- \title WebEngine Widgets WebUI Example
- \ingroup webengine-widgetexamples
- \brief Displays HTML over a custom scheme.
-
- \image webui-example.png
-
- \e {WebUI} demonstrates how to implement a custom scheme in a secure way.
-
- Aside from the built-in URL schemes, such as \c {http} and \c {qrc},
- \QWE may be extended with \e {custom schemes} by creating \e {custom
- scheme handlers}. This example shows:
-
- \list
- \li How to create a custom scheme handler which serves HTML and handles
- HTML form submissions.
- \li How to prevent ordinary web content from accessing the custom scheme.
- \li How to prevent any other scheme from submitting HTML form data.
- \endlist
-
- \include examples-run.qdocinc
-
- \section1 Overview
-
- The example program consists of a single \l {QWebEngineView} showing a
- simple HTML page loaded from the URL \c {webui:about}, over our custom
- scheme. Pressing the button at the bottom of the page will trigger an HTML
- form submission via POST to the same URL, at which point our custom scheme
- handler will cause the application to exit.
-
- The program is divided into two parts, the \c {main} function for setting
- everything up, and the \c {WebUiHandler} class for implementing our custom
- scheme handler. The \c {main} function is quite short:
-
- \quotefromfile webenginewidgets/webui/main.cpp
- \skipto int main
- \printuntil /^\}/
-
- Aside from the relatively standard setup of widgets, two points are
- noteworthy. First, we call the static method \c
- {WebUiHandler::registerUrlScheme()} to register our custom scheme with the
- web engine. Second, we create and install our custom scheme handler \c
- {WebUiHandler} using \l
- {QWebEngineProfile::installUrlSchemeHandler()}{installUrlSchemeHandler()}.
- The following sections describe these aspects in more detail.
-
- \section1 Registering the Scheme
-
- As custom schemes are integrated directly into the web engine, they do not
- necessarily need to follow the standard security rules which apply to
- ordinary web content. Depending on the chosen configuration, content served
- over a custom scheme may be given access to local resources, be set to
- ignore Content-Security-Policy rules, or conversely, be denied access to any
- other content entirely.
-
- In order to take advantage of these possibilities, the custom scheme must
- first be registered. This means creating and configuring a \l
- {QWebEngineUrlScheme} object and then handing it over to \l
- {QWebEngineUrlScheme::registerScheme()}. The example program does exactly this in
- the static method \c {WebUiHandler::registerUrlScheme()}:
-
- \quotefromfile webenginewidgets/webui/webuihandler.cpp
- \skipto void WebUiHandler::registerUrlScheme
- \printuntil /^\}/
-
- A custom scheme needs a name, which can be set by passing it to
- the constructor of \c {QWebEngineUrlScheme} or by calling \l
- {QWebEngineUrlScheme::setName}. In the above, the name \c {webui} is set
- through the constructor. Additionally, we activate the flags \l
- {QWebEngineUrlScheme::SecureScheme}{SecureScheme}, \l
- {QWebEngineUrlScheme::LocalScheme}{LocalScheme} and \l
- {QWebEngineUrlScheme::LocalAccessAllowed}{LocalAccessAllowed}. Since our
- custom scheme handler will not deliver resources received from insecure
- network connections, we can safely mark it as a \c {SecureScheme}. The \c {LocalScheme}
- flag prevents content from non-local schemes (such as \c {http}) from
- interacting with our custom scheme. Without this flag it would be possible,
- for example, to embed the \c {webui:about} page in an \c <iframe> element on
- a remotely loaded HTML page, perhaps to attempt a phishing attack. We also
- need the \c {LocalAccessAllowed} flag without which we would not be able to
- access the \c {webui} scheme from our \c {webui:about} page.
-
- Earlier we saw that the call to \c {WebUiHandler::registerUrlScheme()} is
- made already at the top of the \c {main} function. This is so because custom
- schemes need to be registered as early as possible so that that they can be
- passed to all subprocesses. Specifically, custom schemes need to be registered
- before any other \QWE classes are instantiated by the application.
-
- \section1 Handling Requests
-
- A custom scheme handler is, broadly speaking, similar to a web application
- served over HTTP. However, because custom schemes are integrated directly
- into the web engine, they have the advantage in terms of efficiency: there's
- no need for generating and parsing HTTP messages or for transferring data
- over sockets.
-
- Implementing a handler means creating a subclass of \l
- {QWebEngineUrlSchemeHandler}, which is just what is done by the \c
- {WebUiHandler} class of the example program:
-
- \quotefromfile webenginewidgets/webui/webuihandler.h
- \skipto class WebUiHandler
- \printuntil /^\}/
-
- For each request to a \c {webui} URL, the \c
- {WebUiHandler::requestStarted()} method will be called:
-
- \quotefromfile webenginewidgets/webui/webuihandler.cpp
- \skipto void WebUiHandler::requestStarted
- \printuntil /^\}/
-
- The \l {QWebEngineUrlRequestJob} object \c {job} contains the request's
- attributes and provides methods for replying to the request with a response.
- Responses are generated asynchronously by reading them from the \l
- {QIODevice} that the application passes to \l
- {QWebEngineUrlRequestJob::reply()}{reply()}.
-
- \warning The \c requestStarted() method is not called from the main thread,
- but from the web engine's IO thread. Care must be taken to synchronize
- access to any resources on the main thread.
-
- Aside from the usual fare of \l
- {QWebEngineUrlRequestJob::requestMethod()}{requestMethod} and \l
- {QWebEngineUrlRequestJob::requestUrl()}{requestUrl}, there is also the \l
- {QWebEngineUrlRequestJob::initiator()}{initiator}, holding the origin of the
- content which initiated the request. An empty \c initiator means the request
- was initiated directly by the application (via \l
- {QWebEnginePage::setUrl()}, for example). The special value \c "null"
- corresponds to an opaque origin (a sandboxed \c {<iframe>} element, for
- example). Otherwise, the \c initiator will contain the URL scheme, hostname,
- and port of the content which initiated the request.
-
- In this example, the \c initiator is used to ensure that \c {POST} requests
- to \c {webui:about} will only trigger the application's exit if they
- originate from the \c {webui} scheme. This prevents content loaded over
- other schemes from triggering the application's exit.
-
-*/
diff --git a/examples/webenginewidgets/webui/main.cpp b/examples/webenginewidgets/webui/main.cpp
deleted file mode 100644
index 92c1b8e7d..000000000
--- a/examples/webenginewidgets/webui/main.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 "webuihandler.h"
-
-#include <QApplication>
-#include <QWebEnginePage>
-#include <QWebEngineProfile>
-#include <QWebEngineView>
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setOrganizationName("QtExamples");
-
- WebUiHandler::registerUrlScheme();
-
- QApplication app(argc, argv);
-
- QWebEngineProfile profile;
-
- WebUiHandler handler;
- profile.installUrlSchemeHandler(WebUiHandler::schemeName, &handler);
-
- QWebEnginePage page(&profile);
- page.load(WebUiHandler::aboutUrl);
-
- QWebEngineView view;
- view.setPage(&page);
- view.setContextMenuPolicy(Qt::NoContextMenu);
- view.resize(500, 600);
- view.show();
-
- return app.exec();
-}
diff --git a/examples/webenginewidgets/webui/webui.pro b/examples/webenginewidgets/webui/webui.pro
deleted file mode 100644
index 714833587..000000000
--- a/examples/webenginewidgets/webui/webui.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TEMPLATE = app
-
-QT += webenginewidgets
-
-HEADERS += \
- webuihandler.h
-
-SOURCES += \
- main.cpp \
- webuihandler.cpp
-
-RESOURCES += \
- webui.qrc
-
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/webui
-INSTALLS += target
diff --git a/examples/webenginewidgets/webui/webuihandler.cpp b/examples/webenginewidgets/webui/webuihandler.cpp
deleted file mode 100644
index 63c249368..000000000
--- a/examples/webenginewidgets/webui/webuihandler.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 "webuihandler.h"
-
-#include <QApplication>
-#include <QFile>
-#include <QWebEngineUrlRequestJob>
-#include <QWebEngineUrlScheme>
-
-#define SCHEMENAME "webui"
-
-const QByteArray WebUiHandler::schemeName = QByteArrayLiteral(SCHEMENAME);
-const QUrl WebUiHandler::aboutUrl = QUrl(QStringLiteral(SCHEMENAME ":about"));
-
-WebUiHandler::WebUiHandler(QObject *parent)
- : QWebEngineUrlSchemeHandler(parent)
-{
-}
-
-void WebUiHandler::requestStarted(QWebEngineUrlRequestJob *job)
-{
- static const QUrl webUiOrigin(QStringLiteral(SCHEMENAME ":"));
- static const QByteArray GET(QByteArrayLiteral("GET"));
- static const QByteArray POST(QByteArrayLiteral("POST"));
-
- QByteArray method = job->requestMethod();
- QUrl url = job->requestUrl();
- QUrl initiator = job->initiator();
-
- if (method == GET && url == aboutUrl) {
- QFile *file = new QFile(QStringLiteral(":/about.html"), job);
- file->open(QIODevice::ReadOnly);
- job->reply(QByteArrayLiteral("text/html"), file);
- } else if (method == POST && url == aboutUrl && initiator == webUiOrigin) {
- job->fail(QWebEngineUrlRequestJob::RequestAborted);
- QApplication::exit();
- } else {
- job->fail(QWebEngineUrlRequestJob::UrlNotFound);
- }
-}
-
-// static
-void WebUiHandler::registerUrlScheme()
-{
- QWebEngineUrlScheme webUiScheme(schemeName);
- webUiScheme.setFlags(QWebEngineUrlScheme::SecureScheme |
- QWebEngineUrlScheme::LocalScheme |
- QWebEngineUrlScheme::LocalAccessAllowed);
- QWebEngineUrlScheme::registerScheme(webUiScheme);
-}
diff --git a/examples/webenginewidgets/webui/webuihandler.h b/examples/webenginewidgets/webui/webuihandler.h
deleted file mode 100644
index f2ac0dcef..000000000
--- a/examples/webenginewidgets/webui/webuihandler.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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 WEBUIHANDLER_H
-#define WEBUIHANDLER_H
-
-#include <QWebEngineUrlSchemeHandler>
-
-class WebUiHandler : public QWebEngineUrlSchemeHandler
-{
- Q_OBJECT
-public:
- explicit WebUiHandler(QObject *parent = nullptr);
-
- void requestStarted(QWebEngineUrlRequestJob *job) override;
-
- static void registerUrlScheme();
-
- const static QByteArray schemeName;
- const static QUrl aboutUrl;
-};
-
-#endif // !WEBUIHANDLER_H
diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake
index 568580c63..f89692711 100644
--- a/qt_cmdline.cmake
+++ b/qt_cmdline.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_commandline_option(build-qtpdf TYPE boolean NAME qtpdf-build)
qt_commandline_option(webengine-developer-build TYPE boolean)
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 39aa0ea99a30c9c15fb3640fe9a2638982548c0
+Subproject ac780f41ba9b3eb8329ca8e09b8857a070aed8c
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5ba4cb1c6..0084697f2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,10 +1,14 @@
-cmake_minimum_required(VERSION 3.19)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
##
# MAIN CONFIGURE
##
-get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." REALPATH)
-get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${PROJECT_BINARY_DIR}" REALPATH)
+qt_internal_get_filename_path_mode(path_mode)
+
+get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ${path_mode})
+get_filename_component(WEBENGINE_ROOT_BUILD_DIR "${PROJECT_BINARY_DIR}" ${path_mode})
# Note this is configure that does not belong to any module
qt_feature_module_begin(ONLY_EVALUATE_FEATURES)
@@ -52,6 +56,9 @@ if(NOT QT_FEATURE_qtwebengine_build AND NOT QT_FEATURE_qtpdf_build)
return()
endif()
+# Upgrade CMake policies to the minimum supported version.
+cmake_minimum_required(VERSION ${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE})
+
##
# MODULES
##
@@ -71,13 +78,13 @@ if(QT_FEATURE_qtpdf_build)
add_subdirectory(pdf)
# keep log order, pdf build after webengine
if(QT_FEATURE_qtwebengine_core_build)
- add_dependencies(run_pdf_GnReady WebEngineCore)
+ add_dependencies(run_pdf_NinjaReady WebEngineCore)
endif()
if(QT_FEATURE_qtwebengine_widgets_build)
- add_dependencies(run_pdf_GnReady WebEngineWidgets)
+ add_dependencies(run_pdf_NinjaReady WebEngineWidgets)
endif()
if(QT_FEATURE_qtwebengine_quick_build)
- add_dependencies(run_pdf_GnReady WebEngineQuick)
+ add_dependencies(run_pdf_NinjaReady WebEngineQuick)
endif()
if(QT_FEATURE_qtpdf_widgets_build)
add_subdirectory(pdfwidgets)
@@ -117,6 +124,10 @@ endif()
# GN PROJECT
##
+if(CMAKE_CROSSCOMPILING AND NOT Gn_FOUND)
+ message(FATAL_ERROR "No gn found for cross-compilation")
+endif()
+
if(NOT Gn_FOUND)
externalproject_add(gn
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/gn
@@ -131,6 +142,7 @@ if(NOT Gn_FOUND)
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DCMAKE_PREFIX_PATH:PATH=<INSTALL_DIR>
-DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
+ -DQT_ALLOW_SYMLINK_IN_PATHS=${QT_ALLOW_SYMLINK_IN_PATHS}
)
if(QT_FEATURE_qtwebengine_core_build)
add_dependencies(run_core_GnReady gn)
@@ -138,6 +150,10 @@ if(NOT Gn_FOUND)
if(QT_FEATURE_qtpdf_build)
add_dependencies(run_pdf_GnReady gn)
endif()
+endif()
+
+string(REGEX REPLACE "(.)" "\\\\\\1" path_to_match "${installDir}")
+if(NOT Gn_FOUND OR Gn_EXECUTABLE MATCHES "^${path_to_match}")
set(INSTALL_GN 1 CACHE INTERNAL "")
endif()
@@ -145,7 +161,7 @@ endif()
# HOST PROJECT
##
-if(CMAKE_CROSSCOMPILING)
+if(CMAKE_CROSSCOMPILING AND NOT IOS AND NOT MACOS)
if(NOT Gn_FOUND)
message(FATAL_ERROR "\nHost gn not found - cross compilation not possible")
@@ -157,7 +173,8 @@ if(CMAKE_CROSSCOMPILING)
PREFIX host
USES_TERMINAL_BUILD TRUE
EXCLUDE_FROM_ALL TRUE
- CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${QT_HOST_PATH}/lib/cmake/Qt6/qt.toolchain.cmake
+ CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${QT_HOST_PATH_CMAKE_DIR}/Qt6/qt.toolchain.cmake
+ -DQT_USE_ORIGINAL_COMPILER=ON
-DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
-DWEBENGINE_ROOT_SOURCE_DIR=${WEBENGINE_ROOT_SOURCE_DIR}
-DGN_TARGET_CPU=${TEST_architecture_arch}
@@ -175,12 +192,32 @@ if(CMAKE_CROSSCOMPILING)
endif()
# install gn for cross build
-if(LINUX AND INSTALL_GN)
- get_install_config(installConfig)
- install(
- PROGRAMS ${installDir}/bin/gn
- CONFIGURATIONS ${installConfig}
- RUNTIME DESTINATION "${INSTALL_LIBEXECDIR}"
- )
+if((LINUX OR MACOS OR WIN32) AND INSTALL_GN)
+ if(NOT QT_WILL_INSTALL)
+ set(copyOutput
+ ${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/gn${CMAKE_EXECUTABLE_SUFFIX}
+ )
+ if(Gn_FOUND)
+ set(copyInput ${Gn_EXECUTABLE})
+ set(copyDep ${Gn_EXECUTABLE})
+ else()
+ set(copyInput ${installDir}/bin/gn${CMAKE_EXECUTABLE_SUFFIX})
+ set(copyDep gn)
+ endif()
+ add_custom_target(copy-gn ALL DEPENDS ${copyOutput})
+ add_custom_command(
+ OUTPUT ${copyOutput}
+ COMMAND ${CMAKE_COMMAND} -E copy ${copyInput} ${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}
+ DEPENDS ${copyDep}
+ USES_TERMINAL
+ )
+ else()
+ get_install_config(installConfig)
+ install(
+ PROGRAMS "${installDir}/bin/gn${CMAKE_EXECUTABLE_SUFFIX}"
+ CONFIGURATIONS ${installConfig}
+ RUNTIME DESTINATION "${INSTALL_LIBEXECDIR}"
+ )
+ endif()
endif()
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f991e90df..8ba77607b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,18 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
find_package(Ninja 1.7.2 REQUIRED)
-find_package(Python2 2.7.5 REQUIRED)
-find_package(Nodejs 10.19 REQUIRED)
+find_package(Nodejs 14.19 REQUIRED)
+find_package(Perl)
find_package(PkgConfig)
if(PkgConfig_FOUND)
- pkg_check_modules(XSCRNSAVER xscrnsaver)
create_pkg_config_host_wrapper(${CMAKE_CURRENT_BINARY_DIR})
endif()
set(buildDir "${CMAKE_CURRENT_BINARY_DIR}")
add_subdirectory(api)
-add_subdirectory(tools)
+add_subdirectory(tools/webenginedriver)
+add_subdirectory(tools/qwebengine_convert_dict)
##
# TOOLCHAIN SETUP
@@ -46,7 +49,7 @@ foreach(arch ${archs})
get_forward_declaration_macro(forwardDeclarationMacro)
get_target_property(qtWebEngineProcessName WebEngineCore QTWEBENGINEPROCESS_NAME)
- if(QT_FEATURE_debug_and_release AND ("${config}" STREQUAL "Debug"))
+ if("${config}" STREQUAL "Debug")
set(qtWebEngineProcessName "${qtWebEngineProcessName}${CMAKE_DEBUG_POSTFIX}")
endif()
@@ -68,18 +71,19 @@ foreach(arch ${archs})
DEFINES
QT_NO_KEYWORDS
QT_USE_QSTRINGBUILDER
- QTWEBENGINECORE_VERSION_STR=\\\\\\\\\"${QT_REPO_MODULE_VERSION}\\\\\\\\\"
- QTWEBENGINEPROCESS_NAME=\\\\\\\\\"${qtWebEngineProcessName}\\\\\\\\\"
+ QTWEBENGINECORE_VERSION_STR=${QT_REPO_MODULE_VERSION}
+ QTWEBENGINEPROCESS_NAME=${qtWebEngineProcessName}
BUILDING_CHROMIUM
"${forwardDeclarationMacro}"
CXX_COMPILE_OPTIONS
${gnCxxCompileOptions}
SOURCES
- accessibility_activation_observer.cpp accessibility_activation_observer.h
accessibility_tree_formatter_qt.cpp
+ browser_accessibility_qt.cpp browser_accessibility_qt.h
authentication_dialog_controller.cpp authentication_dialog_controller.h authentication_dialog_controller_p.h
+ autofill_client_qt.cpp autofill_client_qt.h
+ autofill_popup_controller.cpp autofill_popup_controller.h autofill_popup_controller_p.h
browser_accessibility_manager_qt.cpp browser_accessibility_manager_qt.h
- browser_accessibility_qt.cpp browser_accessibility_qt.h
browser_main_parts_qt.cpp browser_main_parts_qt.h
browser_message_filter_qt.cpp browser_message_filter_qt.h
browsing_data_remover_delegate_qt.cpp browsing_data_remover_delegate_qt.h
@@ -87,6 +91,7 @@ foreach(arch ${archs})
certificate_error_controller.cpp certificate_error_controller.h
chromium_overrides.cpp
client_cert_select_controller.cpp client_cert_select_controller.h
+ client_hints.cpp client_hints.h
clipboard_change_observer.h
clipboard_qt.cpp clipboard_qt.h
color_chooser_controller.cpp color_chooser_controller.h color_chooser_controller_p.h
@@ -96,11 +101,17 @@ foreach(arch ${archs})
compositor/content_gpu_client_qt.cpp compositor/content_gpu_client_qt.h
compositor/display_overrides.cpp
compositor/display_software_output_surface.cpp compositor/display_software_output_surface.h
+ compositor/native_skia_output_device.cpp compositor/native_skia_output_device.h
content_browser_client_qt.cpp content_browser_client_qt.h
content_client_qt.cpp content_client_qt.h
content_main_delegate_qt.cpp content_main_delegate_qt.h
content_utility_client_qt.cpp content_utility_client_qt.h
+ custom_handlers/protocol_handler_registry_delegate_qt.h custom_handlers/protocol_handler_registry_delegate_qt.cpp
+ custom_handlers/protocol_handler_registry_factory.h custom_handlers/protocol_handler_registry_factory.cpp
+ custom_handlers/register_protocol_handler_request_controller.h
+ custom_handlers/register_protocol_handler_request_controller_impl.cpp custom_handlers/register_protocol_handler_request_controller_impl.h
delegated_frame_host_client_qt.cpp delegated_frame_host_client_qt.h
+ desktop_media_controller.cpp desktop_media_controller.h desktop_media_controller_p.h
desktop_screen_qt.cpp desktop_screen_qt.h
devtools_frontend_qt.cpp devtools_frontend_qt.h
devtools_manager_delegate_qt.cpp devtools_manager_delegate_qt.h
@@ -108,26 +119,34 @@ foreach(arch ${archs})
favicon_driver_qt.cpp favicon_driver_qt.h
favicon_service_factory_qt.cpp favicon_service_factory_qt.h
file_picker_controller.cpp file_picker_controller.h
+ file_system_access/file_system_access_permission_context_factory_qt.cpp file_system_access/file_system_access_permission_context_factory_qt.h
+ file_system_access/file_system_access_permission_context_qt.cpp file_system_access/file_system_access_permission_context_qt.h
+ file_system_access/file_system_access_permission_grant_qt.cpp file_system_access/file_system_access_permission_grant_qt.h
+ file_system_access/file_system_access_permission_request_controller.h
+ file_system_access/file_system_access_permission_request_controller_impl.cpp file_system_access/file_system_access_permission_request_controller_impl.h
+ file_system_access/file_system_access_permission_request_manager_qt.cpp file_system_access/file_system_access_permission_request_manager_qt.h
find_text_helper.cpp find_text_helper.h
global_descriptors_qt.h
javascript_dialog_controller.cpp javascript_dialog_controller.h javascript_dialog_controller_p.h
javascript_dialog_manager_qt.cpp javascript_dialog_manager_qt.h
login_delegate_qt.cpp login_delegate_qt.h
media_capture_devices_dispatcher.cpp media_capture_devices_dispatcher.h
- native_web_keyboard_event_qt.cpp
- net/client_cert_override.cpp net/client_cert_override.h
+ native_web_keyboard_event_qt.cpp native_web_keyboard_event_qt.h
+ net/client_cert_qt.cpp net/client_cert_qt.h
net/client_cert_store_data.cpp net/client_cert_store_data.h
net/cookie_monster_delegate_qt.cpp net/cookie_monster_delegate_qt.h
net/custom_url_loader_factory.cpp net/custom_url_loader_factory.h
- net/proxy_config_monitor.cpp
- net/proxy_config_service_qt.cpp
+ net/proxy_config_monitor.cpp net/proxy_config_monitor.h
+ net/proxy_config_service_qt.cpp net/proxy_config_service_qt.h
net/proxying_restricted_cookie_manager_qt.cpp net/proxying_restricted_cookie_manager_qt.h
net/proxying_url_loader_factory_qt.cpp net/proxying_url_loader_factory_qt.h
net/qrc_url_scheme_handler.cpp net/qrc_url_scheme_handler.h
+ net/resource_request_body_qt.cpp net/resource_request_body_qt.h
net/ssl_host_state_delegate_qt.cpp net/ssl_host_state_delegate_qt.h
net/system_network_context_manager.cpp net/system_network_context_manager.h
net/url_request_custom_job_delegate.cpp net/url_request_custom_job_delegate.h
net/url_request_custom_job_proxy.cpp net/url_request_custom_job_proxy.h
+ net/version_ui_qt.cpp net/version_ui_qt.h
net/webui_controller_factory_qt.cpp net/webui_controller_factory_qt.h
ozone/gl_context_qt.cpp ozone/gl_context_qt.h
ozone/gl_ozone_egl_qt.cpp ozone/gl_ozone_egl_qt.h
@@ -138,24 +157,20 @@ foreach(arch ${archs})
ozone/platform_window_qt.cpp ozone/platform_window_qt.h
ozone/surface_factory_qt.cpp ozone/surface_factory_qt.h
permission_manager_qt.cpp permission_manager_qt.h
+ pdf_util_qt.cpp pdf_util_qt.h
platform_notification_service_qt.cpp platform_notification_service_qt.h
+ pointer_device_qt.cpp
pref_service_adapter.cpp pref_service_adapter.h
process_main.cpp
profile_adapter.cpp profile_adapter.h
profile_adapter_client.cpp profile_adapter_client.h
profile_io_data_qt.cpp profile_io_data_qt.h
profile_qt.cpp profile_qt.h
- proxy_config_monitor.h
- proxy_config_service_qt.h
- quota_permission_context_qt.cpp quota_permission_context_qt.h
- quota_request_controller.h
- quota_request_controller_impl.cpp quota_request_controller_impl.h
- register_protocol_handler_request_controller.h
- register_protocol_handler_request_controller_impl.cpp register_protocol_handler_request_controller_impl.h
render_view_context_menu_qt.cpp render_view_context_menu_qt.h
render_widget_host_view_qt.cpp render_widget_host_view_qt.h
render_widget_host_view_qt_delegate.h
render_widget_host_view_qt_delegate_client.cpp render_widget_host_view_qt_delegate_client.h
+ render_widget_host_view_qt_delegate_item.cpp render_widget_host_view_qt_delegate_item.h
renderer/content_renderer_client_qt.cpp renderer/content_renderer_client_qt.h
renderer/content_settings_observer_qt.cpp renderer/content_settings_observer_qt.h
renderer/render_configuration.cpp renderer/render_configuration.h
@@ -166,7 +181,6 @@ foreach(arch ${archs})
renderer_host/web_engine_page_host.cpp renderer_host/web_engine_page_host.h
request_controller.h
resource_bundle_qt.cpp
- resource_context_qt.cpp resource_context_qt.h
select_file_dialog_factory_qt.cpp select_file_dialog_factory_qt.h
touch_handle_drawable_client.h
touch_handle_drawable_qt.cpp touch_handle_drawable_qt.h
@@ -181,12 +195,18 @@ foreach(arch ${archs})
web_contents_delegate_qt.cpp web_contents_delegate_qt.h
web_contents_view_qt.cpp web_contents_view_qt.h
web_engine_context.cpp web_engine_context.h
- web_engine_context_threads.cpp
web_engine_error.cpp web_engine_error.h
web_engine_library_info.cpp web_engine_library_info.h
web_engine_settings.cpp web_engine_settings.h
web_event_factory.cpp web_event_factory.h
web_usb_detector_qt.cpp web_usb_detector_qt.h
+ authenticator_request_client_delegate_qt.cpp authenticator_request_client_delegate_qt.h
+ authenticator_request_dialog_controller.cpp authenticator_request_dialog_controller.h authenticator_request_dialog_controller_p.h
+ )
+
+ extend_gn_target(${buildGn} CONDITION QT_FEATURE_accessibility
+ SOURCES
+ accessibility_activation_observer.cpp accessibility_activation_observer.h
)
extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_ozone_x11
@@ -195,24 +215,30 @@ foreach(arch ${archs})
ozone/gl_surface_glx_qt.cpp ozone/gl_surface_glx_qt.h
)
+ extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_vulkan
+ SOURCES
+ compositor/native_skia_output_device_vulkan.cpp compositor/native_skia_output_device_vulkan.h
+ compositor/vulkan_implementation_qt.cpp compositor/vulkan_implementation_qt.h
+ )
+
extend_gn_target(${buildGn} CONDITION QT_FEATURE_opengl
SOURCES
compositor/compositor_resource_fence.cpp compositor/compositor_resource_fence.h
- compositor/display_gl_output_surface.cpp compositor/display_gl_output_surface.h
compositor/display_skia_output_device.cpp compositor/display_skia_output_device.h
+ compositor/native_skia_output_device_opengl.cpp compositor/native_skia_output_device_opengl.h
)
- extend_gn_target(${buildGn} CONDITION MACOS AND QT_FEATURE_opengl
+ extend_gn_target(${buildGn} CONDITION MACOS
SOURCES
- macos_context_type_helper.mm macos_context_type_helper.h
+ native_web_keyboard_event_qt_mac.mm
+ compositor/native_skia_output_device_mac.mm
+ compositor/native_skia_output_device_metal.cpp compositor/native_skia_output_device_metal.h
)
extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_pepper_plugins
SOURCES
renderer/pepper/pepper_renderer_host_factory_qt.cpp renderer/pepper/pepper_renderer_host_factory_qt.h
renderer/plugins/loadable_plugin_placeholder_qt.cpp renderer/plugins/loadable_plugin_placeholder_qt.h
- renderer_host/pepper/pepper_host_factory_qt.cpp renderer_host/pepper/pepper_host_factory_qt.h
- renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp renderer_host/pepper/pepper_isolated_file_system_message_filter.h
)
extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_printing_and_pdf
@@ -246,9 +272,9 @@ foreach(arch ${archs})
extensions/extension_web_contents_observer_qt.cpp extensions/extension_web_contents_observer_qt.h
extensions/extensions_api_client_qt.cpp extensions/extensions_api_client_qt.h
extensions/extensions_browser_client_qt.cpp extensions/extensions_browser_client_qt.h
+ extensions/file_system_delegate_qt.cpp extensions/file_system_delegate_qt.h
extensions/messaging_delegate_qt.cpp extensions/messaging_delegate_qt.h
extensions/mime_handler_view_guest_delegate_qt.cpp extensions/mime_handler_view_guest_delegate_qt.h
- extensions/pdf_iframe_navigation_throttle_qt.cpp extensions/pdf_iframe_navigation_throttle_qt.h
extensions/plugin_service_filter_qt.cpp extensions/plugin_service_filter_qt.h
net/plugin_response_interceptor_url_loader_throttle.cpp net/plugin_response_interceptor_url_loader_throttle.h
renderer/extensions/extensions_dispatcher_delegate_qt.cpp renderer/extensions/extensions_dispatcher_delegate_qt.h
@@ -257,9 +283,17 @@ foreach(arch ${archs})
renderer/extensions/resource_request_policy_qt.cpp renderer/extensions/resource_request_policy_qt.h
)
+ extend_gn_target(${buildGn} CONDITION QT_FEATURE_webengine_extensions AND QT_FEATURE_webengine_printing_and_pdf
+ SOURCES
+ extensions/pdf_iframe_navigation_throttle_qt.cpp extensions/pdf_iframe_navigation_throttle_qt.h
+ printing/pdf_stream_delegate_qt.cpp printing/pdf_stream_delegate_qt.h
+ printing/pdf_document_helper_client_qt.cpp printing/pdf_document_helper_client_qt.h
+ )
+
extend_gn_target(${buildGn} CONDITION WIN32
SOURCES
clipboard_util_win.cpp
+ compositor/native_skia_output_device_direct3d11.cpp compositor/native_skia_output_device_direct3d11.h
)
##
@@ -276,38 +310,69 @@ foreach(arch ${archs})
list(APPEND gnArgArg
qtwebengine_target="${buildDir}/${config}/${arch}:QtWebEngineCore"
+ build_dawn_tests=false
+ build_with_tflite_lib=false
+ enable_background_contents=false
+ enable_background_mode=false
+ enable_ipc_fuzzer=false
+ enable_ipc_logging=false
+ enable_java_templates=false
enable_media_remoting=false
enable_message_center=false
enable_nacl=false
+ enable_oop_printing=false
enable_remoting=false
enable_reporting=false
enable_resource_allowlist_generation=false
+ enable_screen_ai_service=false
+ enable_session_service=false
+ enable_supervised_users=false
enable_swiftshader=false
enable_swiftshader_vulkan=false
angle_enable_swiftshader=false
+ dawn_use_swiftshader=false
+ enable_vr=false
enable_web_speech=false
enable_widevine=true
+ enable_library_cdms=true
+ fatal_linker_warnings=false
has_native_accessibility=false
safe_browsing_mode=0
- skia_use_dawn=false
toolkit_views=false
chrome_pgo_phase=0
optimize_webui=false
- enable_js_type_check=false
- v8_use_external_startup_data=false
strip_absolute_paths_from_debug_symbols=false
- disable_ftp_support=true
+ pdf_use_skia=true
+ use_dawn=false
+ skia_use_dawn=false
+ devtools_fast_bundle=false
+ devtools_skip_typecheck=false
+ use_static_angle=true
+ use_perfetto_client_library=false
+ trial_comparison_cert_verifier_supported=false
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_v8_context_snapshot v8_use_external_startup_data
+ CONDITION QT_FEATURE_webengine_v8_context_snapshot
)
-
extend_gn_list(gnArgArg
- ARGS enable_basic_printing enable_print_preview enable_pdf
+ ARGS enable_printing enable_basic_printing enable_print_preview enable_pdf
CONDITION QT_FEATURE_webengine_printing_and_pdf
)
extend_gn_list(gnArgArg
+ ARGS use_cups
+ CONDITION QT_FEATURE_webengine_printing_and_pdf AND NOT WIN32
+ )
+ extend_gn_list(gnArgArg
ARGS enable_plugins
- CONDITION QT_FEATURE_webengine_pepper_plugins
+ CONDITION QT_FEATURE_webengine_printing_and_pdf OR
+ QT_FEATURE_webengine_pepper_plugins
)
extend_gn_list(gnArgArg
+ ARGS enable_ppapi
+ CONDITION QT_FEATURE_webengine_pepper_plugins
+ )
+ extend_gn_list(gnArgArg
ARGS enable_spellcheck
CONDITION QT_FEATURE_webengine_spellchecker
)
@@ -316,6 +381,10 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_webrtc
)
extend_gn_list(gnArgArg
+ ARGS enable_screen_capture
+ CONDITION QT_FEATURE_webengine_webrtc
+ )
+ extend_gn_list(gnArgArg
ARGS enable_hangout_services_extension
CONDITION QT_FEATURE_webengine_webrtc AND QT_FEATURE_webengine_extensions
)
@@ -328,6 +397,10 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_extensions
)
extend_gn_list(gnArgArg
+ ARGS enable_vulkan
+ CONDITION QT_FEATURE_webengine_vulkan
+ )
+ extend_gn_list(gnArgArg
ARGS use_kerberos
CONDITION QT_FEATURE_webengine_kerberos
)
@@ -342,27 +415,35 @@ foreach(arch ${archs})
ARGS use_browser_spellchecker
CONDITION QT_FEATURE_webengine_native_spellchecker
)
+ extend_gn_list(gnArgArg
+ ARGS use_embedded_config
+ CONDITION QT_FEATURE_webengine_embedded_build
+ )
+ extend_gn_list(gnArgArg
+ ARGS enable_webenginedriver
+ CONDITION QT_FEATURE_webenginedriver
+ )
if(LINUX)
list(APPEND gnArgArg
+ use_gtk=false # GTK toolkit bindings
+ use_qt=false # Qt5 toolkit bindings
use_cups=false
use_gio=false
- use_gnome_keyring=false
- use_udev=true
use_bundled_fontconfig=false
- enable_session_service=false
+ use_glib=false
+ use_bluez=false
+ use_udev=true
is_cfi=false
use_ozone=true
- use_x11=false
ozone_auto_platforms=false
ozone_platform_headless=false
ozone_platform_external=true
ozone_platform="qt"
ozone_extra_path="${CMAKE_CURRENT_LIST_DIR}/ozone/ozone_extra.gni"
- use_glib=false
)
set(systemLibs libjpeg libpng freetype harfbuzz libevent libwebp libxml
- opus snappy libvpx icu ffmpeg re2 lcms2
+ opus snappy icu ffmpeg re2 lcms2 libopenjpeg2 libvpx
)
foreach(slib ${systemLibs})
extend_gn_list(gnArgArg
@@ -370,6 +451,16 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_system_${slib}
)
endforeach()
+ if(NOT QT_FEATURE_webengine_system_opus)
+ extend_gn_list(gnArgArg
+ ARGS has_perl
+ CONDITION Perl_FOUND
+ )
+ endif()
+ extend_gn_list(gnArgArg
+ ARGS use_system_libxslt
+ CONDITION QT_FEATURE_webengine_system_libxml
+ )
extend_gn_list(gnArgArg
ARGS icu_use_data_file
CONDITION NOT QT_FEATURE_webengine_system_icu
@@ -387,6 +478,10 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_system_libpng
)
extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_libtiff
+ CONDITION QT_FEATURE_webengine_system_libtiff
+ )
+ extend_gn_list(gnArgArg
ARGS use_libpci
CONDITION QT_FEATURE_webengine_system_libpci
)
@@ -399,6 +494,14 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_system_pulseaudio
)
extend_gn_list(gnArgArg
+ ARGS use_system_minigbm
+ CONDITION QT_FEATURE_webengine_system_gbm
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_vaapi
+ CONDITION QT_FEATURE_webengine_vaapi
+ )
+ extend_gn_list(gnArgArg
ARGS ozone_platform_x11 use_xkbcommon
CONDITION QT_FEATURE_webengine_ozone_x11
)
@@ -407,33 +510,47 @@ foreach(arch ${archs})
CONDITION QT_FEATURE_webengine_ozone_x11 AND QT_FEATURE_webengine_webrtc
)
extend_gn_list(gnArgArg
- ARGS use_xscrnsaver
- CONDITION QT_FEATURE_webengine_ozone_x11 AND XSCRNSAVER_FOUND
+ ARGS use_vaapi_x11
+ CONDITION QT_FEATURE_webengine_ozone_x11 AND QT_FEATURE_webengine_vaapi
)
+ if(QT_FEATURE_webengine_kerberos)
+ list(APPEND gnArgArg
+ external_gssapi_include_dir="${GSSAPI_INCLUDE_DIRS}/gssapi"
+ )
+ endif()
+ get_gn_arch(cpu ${TEST_architecture_arch})
if(CMAKE_CROSSCOMPILING AND cpu STREQUAL "arm")
check_thumb(armThumb)
- if(NOT armThumb AND NOT QT_FEATURE_system_ffmpeg)
+ if(NOT armThumb AND NOT QT_FEATURE_webengine_system_ffmpeg)
list(APPEND gnArgArg media_use_ffmpeg=false use_webaudio_ffmpeg=false)
endif()
endif()
+
+ if(CMAKE_CROSSCOMPILING AND cpu STREQUAL "arm64")
+ # This is a workaround to avoid auto test timeouts on the QEMU arm64 CI.
+ if ("$ENV{TARGET_OSVERSION_COIN}" STREQUAL "qemu")
+ list(APPEND gnArgArg
+ v8_enable_sandbox=false
+ arm_control_flow_integrity="none"
+ )
+ endif()
+ endif()
+ unset(cpu)
endif()
if(MACOS)
list(APPEND gnArgArg
use_external_popup_menu=false
- angle_enable_vulkan=false
+ skia_use_metal=false
)
endif()
if(WIN32)
list(APPEND gnArgArg
- enable_location_source=false
- enable_session_service=false
ninja_use_custom_environment_files=false
com_init_check_hook_disabled=true
heterogeneous_executables=true
- enable_vr=false
)
endif()
@@ -441,7 +558,7 @@ foreach(arch ${archs})
CMAKE_TARGET WebEngineCore
NINJA_TARGETS QtWebEngineCore convert_dict
GN_TARGET ${buildGn}
- GN_ARGS "${gnArgArg}"
+ GN_ARGS ${gnArgArg}
BUILDDIR ${buildDir}/${config}/${arch}
MODULE core
)
@@ -455,14 +572,27 @@ endforeach()
# WEBENGINECORE SETUP
##
-set(arch ${CMAKE_SYSTEM_PROCESSOR})
+list(GET archs 0 arch)
target_include_directories(WebEngineCore PRIVATE
${buildDir}/$<CONFIG>/${arch}/gen
${buildDir}/$<CONFIG>/${arch}/gen/third_party/perfetto
${buildDir}/$<CONFIG>/${arch}/gen/third_party/perfetto/build_config
)
-add_gn_build_aritfacts_to_target(WebEngineCore QtWebEngineCore core ${buildDir})
+set(stamps QtWebEngineCore.stamp)
+if(QT_FEATURE_webengine_v8_context_snapshot)
+ set(dataStamp obj/tools/v8_context_snapshot/v8_context_snapshot.stamp)
+endif()
+
+add_gn_build_artifacts_to_target(
+ CMAKE_TARGET WebEngineCore
+ NINJA_TARGET QtWebEngineCore
+ MODULE core
+ BUILDDIR ${buildDir}
+ COMPLETE_STATIC FALSE
+ NINJA_STAMP QtWebEngineCore.stamp
+ NINJA_DATA_STAMP ${dataStamp}
+)
add_dependencies(WebEngineCore run_core_NinjaDone)
if(COIN_BUG_699)
set_property(TARGET WebEngineCore PROPERTY CXX_LINKER_LAUNCHER ${PROJECT_BINARY_DIR}/linker_ulimit.sh)
@@ -497,15 +627,47 @@ endif()
# WEBENGINECORE DICT TOOL SETUP
##
-if(QT_FEATURE_webengine_spellchecker)
+if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING)
qt_get_tool_target_name(dict_target_name qwebengine_convert_dict)
target_include_directories(${dict_target_name} PRIVATE
../3rdparty/chromium
../3rdparty/chromium/third_party/boringssl/src/include
${buildDir}/$<CONFIG>/${arch}/gen
)
- add_gn_build_aritfacts_to_target(${dict_target_name} convert_dict core ${buildDir})
+ add_gn_build_artifacts_to_target(
+ CMAKE_TARGET ${dict_target_name}
+ NINJA_TARGET convert_dict
+ MODULE core
+ BUILDDIR ${buildDir}
+ COMPLETE_STATIC FALSE
+ NINJA_STAMP convert_dict.stamp
+ )
add_dependencies(${dict_target_name} run_core_NinjaDone)
add_dependencies(${dict_target_name} WebEngineCore)
endif()
+##
+# WEBENGINEDRIVER
+##
+
+if(QT_FEATURE_webenginedriver)
+ add_ninja_command(
+ TARGET webenginedriver_group
+ OUTPUT ${WEBENGINEDRIVER_EXECUTABLE}
+ BUILDDIR ${buildDir}/$<CONFIG>/${arch}
+ MODULE core
+ )
+ add_custom_target(webenginedriver
+ DEPENDS
+ ${buildDir}/$<CONFIG>/${arch}/${WEBENGINEDRIVER_EXECUTABLE})
+ add_dependencies(run_core_NinjaDone webenginedriver)
+endif()
+
+##
+# CHROMIUM UPDATE
+##
+
+add_custom_target(update-chromium
+ COMMAND ${CMAKE_COMMAND} -P ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/SubmoduleUpdate.cmake
+ DEPENDS ${WEBENGINE_ROOT_SOURCE_DIR}/cmake/SubmoduleUpdate.cmake
+)
diff --git a/src/core/accessibility_activation_observer.cpp b/src/core/accessibility_activation_observer.cpp
index 833190844..4f25a35ff 100644
--- a/src/core/accessibility_activation_observer.cpp
+++ b/src/core/accessibility_activation_observer.cpp
@@ -1,46 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "accessibility_activation_observer.h"
-#if QT_CONFIG(accessibility)
-
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
namespace QtWebEngineCore {
@@ -48,12 +10,13 @@ namespace QtWebEngineCore {
namespace {
bool isAccessibilityEnabled() {
- // On Linux accessibility is disabled by default due to performance issues,
- // and can be re-enabled by setting the QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
- // variable. For details, see QTBUG-59922.
+ // On Linux accessibility can be disabled due to performance issues by setting the
+ // QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0. For details,
+ // see QTBUG-59922.
#ifdef Q_OS_LINUX
static bool accessibility_enabled
- = qEnvironmentVariableIsSet("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY");
+ = qEnvironmentVariable("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY", QLatin1String("1"))
+ == QLatin1String("1");
#else
const bool accessibility_enabled = true;
#endif
@@ -85,5 +48,3 @@ void AccessibilityActivationObserver::accessibilityActiveChanged(bool active)
}
} // namespace QtWebEngineCore
-
-#endif // QT_CONFIG(accessibility)
diff --git a/src/core/accessibility_activation_observer.h b/src/core/accessibility_activation_observer.h
index 23fd2101e..81d8b843c 100644
--- a/src/core/accessibility_activation_observer.h
+++ b/src/core/accessibility_activation_observer.h
@@ -1,53 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef ACCESSIBILITY_ACTIVATION_OBSERVER_H
#define ACCESSIBILITY_ACTIVATION_OBSERVER_H
#include <QtGui/qaccessible.h>
-#if QT_CONFIG(accessibility)
-
namespace QtWebEngineCore {
-class RenderWidgetHostViewQt;
-
class AccessibilityActivationObserver : public QAccessible::ActivationObserver
{
public:
@@ -59,6 +19,4 @@ public:
} // namespace QtWebEngineCore
-#endif // QT_CONFIG(accessibility)
-
#endif // ACCESSIBILITY_ACTIVATION_OBSERVER_H
diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp
index 5bbaeca2a..3a3b30cb4 100644
--- a/src/core/accessibility_tree_formatter_qt.cpp
+++ b/src/core/accessibility_tree_formatter_qt.cpp
@@ -1,57 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "ui/accessibility/platform/inspect/ax_tree_formatter_base.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
+#include "content/public/browser/ax_inspect_factory.h"
+#include "ui/accessibility/platform/inspect/ax_event_recorder.h"
+
+#include <QtGui/qtguiglobal.h>
+#include <memory>
+#include <string>
#include <utility>
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
+#if QT_CONFIG(accessibility)
+#include "browser_accessibility_qt.h"
+
#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
-#include "content/browser/accessibility/accessibility_event_recorder.h"
-#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
-#include "content/public/browser/ax_inspect_factory.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "ui/accessibility/platform/inspect/ax_tree_formatter_base.h"
-#include "browser_accessibility_qt.h"
+#include <QtGui/qaccessible.h>
+#endif
namespace content {
@@ -61,20 +31,16 @@ public:
explicit AccessibilityTreeFormatterQt();
~AccessibilityTreeFormatterQt() override;
- base::Value BuildTree(ui::AXPlatformNodeDelegate *start) const override;
- base::Value BuildTreeForWindow(gfx::AcceleratedWidget hwnd) const override
- {
- return base::Value{};
- }
- base::Value BuildTreeForSelector(const AXTreeSelector &selector) const override
+ base::Value::Dict BuildTree(ui::AXPlatformNodeDelegate *start) const override;
+ base::Value::Dict BuildTreeForSelector(const AXTreeSelector &selector) const override
{
- return base::Value{};
+ return base::Value::Dict{};
}
private:
- void RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::DictionaryValue *dict) const;
- void AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict) const;
- std::string ProcessTreeForOutput(const base::DictionaryValue &node) const override;
+ void RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::Value::Dict *dict) const;
+ void AddProperties(const BrowserAccessibility &node, base::Value::Dict *dict) const;
+ std::string ProcessTreeForOutput(const base::Value::Dict &node) const override;
};
AccessibilityTreeFormatterQt::AccessibilityTreeFormatterQt()
@@ -85,129 +51,124 @@ AccessibilityTreeFormatterQt::~AccessibilityTreeFormatterQt()
{
}
-base::Value AccessibilityTreeFormatterQt::BuildTree(ui::AXPlatformNodeDelegate *start) const
+base::Value::Dict AccessibilityTreeFormatterQt::BuildTree(ui::AXPlatformNodeDelegate *start) const
{
BrowserAccessibility *root_internal =
BrowserAccessibility::FromAXPlatformNodeDelegate(start);
- base::Value dict(base::Value::Type::DICTIONARY);
- RecursiveBuildAccessibilityTree(*root_internal, static_cast<base::DictionaryValue *>(&dict));
+ base::Value::Dict dict;
+ RecursiveBuildAccessibilityTree(*root_internal, &dict);
return dict;
}
-void AccessibilityTreeFormatterQt::RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::DictionaryValue *dict) const
+void AccessibilityTreeFormatterQt::RecursiveBuildAccessibilityTree(const BrowserAccessibility &node, base::Value::Dict *dict) const
{
AddProperties(node, dict);
- auto children = std::make_unique<base::ListValue>();
+ base::Value::List children;
for (size_t i = 0; i < node.PlatformChildCount(); ++i) {
- std::unique_ptr<base::DictionaryValue> child_dict(new base::DictionaryValue);
+ base::Value::Dict child_dict;
content::BrowserAccessibility *child_node = node.PlatformGetChild(i);
- RecursiveBuildAccessibilityTree(*child_node, child_dict.get());
- children->Append(std::move(child_dict));
+ RecursiveBuildAccessibilityTree(*child_node, &child_dict);
+ children.Append(std::move(child_dict));
}
dict->Set(kChildrenDictAttr, std::move(children));
}
-void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &node, base::DictionaryValue *dict) const
+void AccessibilityTreeFormatterQt::AddProperties(const BrowserAccessibility &node, base::Value::Dict *dict) const
{
- dict->SetInteger("id", node.GetId());
- const BrowserAccessibilityQt *acc_node = ToBrowserAccessibilityQt(&node);
+ dict->Set("id", node.GetId());
+ const QAccessibleInterface *iface = toQAccessibleInterface(&node);
- dict->SetString("role", qAccessibleRoleString(acc_node->role()));
+ dict->Set("role", qAccessibleRoleString(iface->role()));
- QAccessible::State state = acc_node->state();
+ QAccessible::State state = iface->state();
- std::vector<base::Value> states;
+ base::Value::List states;
if (state.busy)
- states.push_back(base::Value("busy"));
+ states.Append(base::Value("busy"));
if (state.checkable)
- states.push_back(base::Value("checkable"));
+ states.Append(base::Value("checkable"));
if (state.checked)
- states.push_back(base::Value("checked"));
- if (acc_node->IsClickable())
- states.push_back(base::Value("clickable"));
+ states.Append(base::Value("checked"));
+ if (node.IsClickable())
+ states.Append(base::Value("clickable"));
if (state.collapsed)
- states.push_back(base::Value("collapsed"));
+ states.Append(base::Value("collapsed"));
if (state.disabled)
- states.push_back(base::Value("disabled"));
+ states.Append(base::Value("disabled"));
if (state.editable)
- states.push_back(base::Value("editable"));
+ states.Append(base::Value("editable"));
if (state.expandable)
- states.push_back(base::Value("expandable"));
+ states.Append(base::Value("expandable"));
if (state.expanded)
- states.push_back(base::Value("expanded"));
+ states.Append(base::Value("expanded"));
if (state.focusable)
- states.push_back(base::Value("focusable"));
+ states.Append(base::Value("focusable"));
if (state.focused)
- states.push_back(base::Value("focused"));
+ states.Append(base::Value("focused"));
if (state.hasPopup)
- states.push_back(base::Value("hasPopup"));
+ states.Append(base::Value("hasPopup"));
if (state.hotTracked)
- states.push_back(base::Value("hotTracked"));
+ states.Append(base::Value("hotTracked"));
if (state.invisible)
- states.push_back(base::Value("invisible"));
+ states.Append(base::Value("invisible"));
if (state.linked)
- states.push_back(base::Value("linked"));
+ states.Append(base::Value("linked"));
if (state.multiLine)
- states.push_back(base::Value("multiLine"));
+ states.Append(base::Value("multiLine"));
if (state.multiSelectable)
- states.push_back(base::Value("multiSelectable"));
+ states.Append(base::Value("multiSelectable"));
if (state.modal)
- states.push_back(base::Value("modal"));
+ states.Append(base::Value("modal"));
if (state.offscreen)
- states.push_back(base::Value("offscreen"));
+ states.Append(base::Value("offscreen"));
if (state.passwordEdit)
- states.push_back(base::Value("password"));
+ states.Append(base::Value("password"));
if (state.pressed)
- states.push_back(base::Value("pressed"));
+ states.Append(base::Value("pressed"));
if (state.readOnly)
- states.push_back(base::Value("readOnly"));
+ states.Append(base::Value("readOnly"));
if (state.selectable)
- states.push_back(base::Value("selectable"));
+ states.Append(base::Value("selectable"));
if (state.selected)
- states.push_back(base::Value("selected"));
+ states.Append(base::Value("selected"));
if (state.traversed)
- states.push_back(base::Value("traversed"));
- dict->SetKey("states", base::Value(states));
+ states.Append(base::Value("traversed"));
+ dict->Set("states", std::move(states));
- dict->SetString("name", acc_node->text(QAccessible::Name).toStdString());
- dict->SetString("description", acc_node->text(QAccessible::Description).toStdString());
+ dict->Set("name", iface->text(QAccessible::Name).toStdString());
+ dict->Set("description", iface->text(QAccessible::Description).toStdString());
}
-std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::DictionaryValue &node) const
+std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::Value::Dict &node) const
{
std::string error_value;
- if (node.GetString("error", &error_value))
- return error_value;
+ if (auto error_value = node.FindString("error"))
+ return *error_value;
std::string line;
std::string role_value;
- node.GetString("role", &role_value);
- if (!role_value.empty())
- WriteAttribute(true, base::StringPrintf("%s", role_value.c_str()), &line);
+ if (auto role_value = node.FindString("role"))
+ WriteAttribute(true, base::StringPrintf("%s", role_value->c_str()), &line);
- const base::ListValue *states_value = nullptr;
- node.GetList("states", &states_value);
- if (states_value) {
+ if (const auto states_value = node.FindList("states")) {
for (const auto &state : *states_value) {
- std::string state_value;
- if (state.GetAsString(&state_value))
- WriteAttribute(true, state_value, &line);
+ if (auto *state_value = state.GetIfString())
+ WriteAttribute(false, *state_value, &line);
}
}
- std::string name_value;
- if (node.GetString("name", &name_value))
- WriteAttribute(true, base::StringPrintf("name='%s'", name_value.c_str()), &line);
+ if (auto name_value = node.FindString("name"))
+ WriteAttribute(true, base::StringPrintf("name='%s'", name_value->c_str()), &line);
- std::string description_value;
- if (node.GetString("description", &description_value))
- WriteAttribute(false, base::StringPrintf("description='%s'", description_value.c_str()), &line);
+ if (auto description_value = node.FindString("description"))
+ WriteAttribute(false, base::StringPrintf("description='%s'", description_value->c_str()), &line);
int id_value;
- node.GetInteger("id", &id_value);
+ if (auto maybe_id = node.FindInt("id"))
+ id_value = *maybe_id;
WriteAttribute(false, base::StringPrintf("id=%d", id_value), &line);
return line + "\n";
@@ -219,7 +180,7 @@ std::string AccessibilityTreeFormatterQt::ProcessTreeForOutput(const base::Dicti
std::unique_ptr<ui::AXTreeFormatter>
AXInspectFactory::CreatePlatformFormatter()
{
- return AXInspectFactory::CreateFormatter(kQt);
+ return AXInspectFactory::CreateFormatter(ui::AXApiType::kQt);
}
// static
@@ -227,16 +188,16 @@ std::unique_ptr<ui::AXEventRecorder> AXInspectFactory::CreatePlatformRecorder(Br
base::ProcessId pid,
const ui::AXTreeSelector &selector)
{
- return AXInspectFactory::CreateRecorder(kQt, manager, pid, selector);
+ return AXInspectFactory::CreateRecorder(ui::AXApiType::kQt, manager, pid, selector);
}
// static
-std::unique_ptr<ui::AXTreeFormatter> AXInspectFactory::CreateFormatter(AXInspectFactory::Type type)
+std::unique_ptr<ui::AXTreeFormatter> AXInspectFactory::CreateFormatter(ui::AXApiType::Type type)
{
switch (type) {
- case kBlink:
+ case ui::AXApiType::kBlink:
return std::make_unique<AccessibilityTreeFormatterBlink>();
- case kQt:
+ case ui::AXApiType::kQt:
#if QT_CONFIG(accessibility)
return std::make_unique<AccessibilityTreeFormatterQt>();
#else
@@ -249,14 +210,14 @@ std::unique_ptr<ui::AXTreeFormatter> AXInspectFactory::CreateFormatter(AXInspect
}
// static
-std::unique_ptr<ui::AXEventRecorder> AXInspectFactory::CreateRecorder(AXInspectFactory::Type type,
+std::unique_ptr<ui::AXEventRecorder> AXInspectFactory::CreateRecorder(ui::AXApiType::Type type,
BrowserAccessibilityManager *manager,
base::ProcessId pid,
const ui::AXTreeSelector &selector)
{
switch (type) {
- case kQt:
- return std::make_unique<AccessibilityEventRecorder>(manager);
+ case ui::AXApiType::kQt:
+ return std::make_unique<ui::AXEventRecorder>();
default:
NOTREACHED() << "Unsupported inspect type " << type;
}
diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index f878f3465..f2ceb2dfd 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_package(Qt6 ${PROJECT_VERSION} REQUIRED COMPONENTS Gui Network Quick)
find_package(Qt6 ${PROJECT_VERSION} QUIET OPTIONAL_COMPONENTS WebChannel Positioning)
@@ -9,9 +12,12 @@ qt_internal_add_module(WebEngineCore
qwebenginecertificateerror.cpp qwebenginecertificateerror.h
qwebengineclientcertificateselection.cpp qwebengineclientcertificateselection.h
qwebengineclientcertificatestore.cpp qwebengineclientcertificatestore.h
+ qwebengineclienthints.cpp qwebengineclienthints.h
qwebenginecontextmenurequest.cpp qwebenginecontextmenurequest.h qwebenginecontextmenurequest_p.h
qwebenginecookiestore.cpp qwebenginecookiestore.h qwebenginecookiestore_p.h
+ qwebenginedesktopmediarequest.cpp qwebenginedesktopmediarequest.h qwebenginedesktopmediarequest_p.h
qwebenginedownloadrequest.cpp qwebenginedownloadrequest.h qwebenginedownloadrequest_p.h
+ qwebenginefilesystemaccessrequest.cpp qwebenginefilesystemaccessrequest.h
qwebenginefindtextresult.cpp qwebenginefindtextresult.h
qwebenginefullscreenrequest.cpp qwebenginefullscreenrequest.h
qwebenginehistory.cpp qwebenginehistory.h qwebenginehistory_p.h
@@ -29,18 +35,20 @@ qt_internal_add_module(WebEngineCore
qwebenginescriptcollection.cpp qwebenginescriptcollection.h qwebenginescriptcollection_p.h
qwebenginesettings.cpp qwebenginesettings.h
qwebengineurlrequestinfo.cpp qwebengineurlrequestinfo.h qwebengineurlrequestinfo_p.h
- qwebengineurlrequestinterceptor.h
+ qwebengineurlrequestinterceptor.h qwebengineurlrequestinterceptor.cpp
qwebengineurlrequestjob.cpp qwebengineurlrequestjob.h
qwebengineurlscheme.cpp qwebengineurlscheme.h
qwebengineurlschemehandler.cpp qwebengineurlschemehandler.h
+ qwebengineglobalsettings.cpp qwebengineglobalsettings.h qwebengineglobalsettings_p.h
+ qwebenginewebauthuxrequest.cpp qwebenginewebauthuxrequest.h qwebenginewebauthuxrequest_p.h
DEFINES
BUILDING_CHROMIUM
- NOMINMAX
INCLUDE_DIRECTORIES
../
../../3rdparty/chromium
../../3rdparty/chromium/third_party/abseil-cpp
../../3rdparty/chromium/third_party/perfetto/include
+ ../../3rdparty/chromium/third_party/boringssl/src/include
LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
@@ -50,15 +58,28 @@ qt_internal_add_module(WebEngineCore
Qt::Gui
Qt::Network
Qt::Quick
+ EXTRA_CMAKE_FILES
+ "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}WebEngineCoreDeploySupport.cmake"
+ NO_GENERATE_CPP_EXPORTS
)
set_target_properties(WebEngineCore PROPERTIES QTWEBENGINEPROCESS_NAME ${qtWebEngineProcessName})
+set_target_properties(WebEngineCore PROPERTIES CXX_STANDARD 20)
# Chromium included headers are not clean
qt_skip_warnings_are_errors(WebEngineCore)
if(CLANG OR GCC)
- target_compile_options(WebEngineCore PRIVATE "-Wno-unused-parameter")
+ target_compile_options(WebEngineCore PRIVATE
+ "-Wno-unused-parameter"
+ "-Wno-expansion-to-defined"
+ )
+endif()
+
+if(GCC)
+ target_compile_options(WebEngineCore PRIVATE
+ "-Wno-packed-not-aligned"
+ )
endif()
qt_internal_extend_target(WebEngineCore CONDITION QT_FEATURE_webengine_webchannel
@@ -70,6 +91,11 @@ qt_internal_extend_target(WebEngineCore CONDITION QT_FEATURE_webengine_geolocati
Qt::Positioning
)
+get_install_config(config)
+get_architectures(archs)
+get_configs(configs)
+list(GET archs 0 arch)
+
##
# DOCS
##
@@ -78,24 +104,21 @@ qt_internal_add_docs(WebEngineCore
../doc/qtwebengine.qdocconf
)
-add_custom_command(
- OUTPUT chromium_attributions.qdoc
- COMMAND ${Python2_EXECUTABLE} chromium/tools/licenses.py
- --file-template ../core/doc/about_credits.tmpl
- --entry-template ../core/doc/about_credits_entry.tmpl
- credits ${CMAKE_CURRENT_BINARY_DIR}/chromium_attributions.qdoc
- DEPENDS ../doc/about_credits.tmpl ../doc/about_credits_entry.tmpl
- WORKING_DIRECTORY ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty
- USES_TERMINAL
+add_code_attributions_target(
+ TARGET generate_chromium_attributions
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/chromium_attributions.qdoc
+ GN_TARGET :QtWebEngineCore
+ FILE_TEMPLATE ../doc/about_credits.tmpl
+ ENTRY_TEMPLATE ../doc/about_credits_entry.tmpl
+ BUILDDIR ${buildDir}/${config}/${arch}
)
-add_custom_target(generate_chromium_attributions DEPENDS chromium_attributions.qdoc)
-add_dependencies(generate_docs_WebEngineCore generate_chromium_attributions)
+add_dependencies(generate_chromium_attributions run_core_GnDone)
+add_dependencies(prepare_docs_WebEngineCore generate_chromium_attributions)
##
# WEBENGINECORE RESOURCES
##
-set(arch ${CMAKE_SYSTEM_PROCESSOR})
#TODO: use simply filter / globbing-expressions
set(localeList am ar bg bn ca cs da de el en-GB en-US es-419 es et fa fi fil fr
gu he hi hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk
@@ -106,20 +129,49 @@ set(resourceList qtwebengine_resources.pak
qtwebengine_resources_200p.pak
qtwebengine_devtools_resources.pak)
-get_install_config(config)
+set(stamps ${buildDir}/${config}/${arch}/QtWebEngineCore.stamp)
+
+qt_internal_get_filename_path_mode(path_mode)
+
+if(QT_FEATURE_webengine_v8_context_snapshot)
+ foreach(arch ${archs})
+ foreach(config ${configs})
+ if(MACOS)
+ set(ext_arch ".${arch}")
+ # QTBUG-118120 gn does not support x86_64h
+ if(ext_arch STREQUAL "x86_64h")
+ set(ext_arch "x86_64")
+ endif()
+ else()
+ unset(ext_arch)
+ endif()
+ if("${config}" STREQUAL "Debug")
+ set(ext_debug ".debug")
+ else()
+ unset(ext_debug)
+ endif()
+ get_filename_component(resSourcePath ${buildDir}/${config}/${arch}/v8_context_snapshot${ext_arch}${ext_debug}.bin ${path_mode})
+ list(APPEND resourceFiles ${resSourcePath})
+ if(MACOS)
+ set(stamps ${stamps} ${buildDir}/${config}/${arch}/obj/tools/v8_context_snapshot/v8_context_snapshot.stamp)
+ endif()
+ endforeach()
+ endforeach()
+endif()
foreach(loc ${localeList})
- get_filename_component(locSourcePath ${buildDir}/${config}/${arch}/qtwebengine_locales/${loc}.pak REALPATH)
+ get_filename_component(locSourcePath ${buildDir}/${config}/${arch}/qtwebengine_locales/${loc}.pak ${path_mode})
list(APPEND localeFiles ${locSourcePath})
endforeach()
foreach(res ${resourceList})
- get_filename_component(resSourcePath ${buildDir}/${config}/${arch}/${res} REALPATH)
+ get_filename_component(resSourcePath ${buildDir}/${config}/${arch}/${res} ${path_mode})
list(APPEND resourceFiles ${resSourcePath})
endforeach()
-if (NOT QT_FEATURE_webengine_system_icu)
- get_filename_component(icuFile ${buildDir}/${config}/${arch}/icudtl.dat REALPATH)
+
+if(NOT QT_FEATURE_webengine_system_icu)
+ get_filename_component(icuFile ${buildDir}/${config}/${arch}/icudtl.dat ${path_mode})
list(APPEND resourceFiles ${icuFile})
set_target_properties(WebEngineCore PROPERTIES ICUDTL_FILE ${icuFile})
endif()
@@ -139,8 +191,16 @@ if(QT_FEATURE_framework)
GENERATED TRUE
)
- add_custom_command(OUTPUT ${allResourceFiles} DEPENDS ${buildDir}/${config}/${arch}/QtWebEngineCore.stamp)
+ add_custom_command(OUTPUT ${allResourceFiles} DEPENDS "${stamps}")
add_custom_target(generate_resources_${config} DEPENDS ${allResourceFiles})
+
+ addCopyCommand(WebEngineCore "${localeFiles}"
+ "${QT_BUILD_DIR}/${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Resources/qtwebengine_locales/"
+ )
+ addCopyCommand(WebEngineCore "${resourceFiles}"
+ "${QT_BUILD_DIR}/${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Resources/"
+ )
+
else()
install(FILES ${localeFiles}
DESTINATION ${INSTALL_TRANSLATIONSDIR}/qtwebengine_locales
diff --git a/src/core/api/Qt6WebEngineCoreDeploySupport.cmake b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
new file mode 100644
index 000000000..e67eb212b
--- /dev/null
+++ b/src/core/api/Qt6WebEngineCoreDeploySupport.cmake
@@ -0,0 +1,173 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# NOTE: This code should only ever be executed in script mode. It expects to be
+# used either as part of an install(CODE) call or called by a script
+# invoked via cmake -P as a POST_BUILD step. It would not normally be
+# included directly, it should be pulled in automatically by the deploy
+# support set up by qtbase.
+
+cmake_minimum_required(VERSION 3.16...3.21)
+
+_qt_internal_add_deployment_hook(_qt_internal_webenginecore_deploy_hook)
+
+if(NOT QT_DEPLOY_WEBENGINECORE_RESOURCES_DIR)
+ set(QT_DEPLOY_WEBENGINECORE_RESOURCES_DIR "resources")
+endif()
+
+function(_qt_internal_webenginecore_status_message)
+ if(__QT_DEPLOY_VERBOSE)
+ message(STATUS ${ARGV})
+ endif()
+endfunction()
+
+function(_qt_internal_webenginecore_deploy_hook)
+ set(no_value_options "")
+ set(single_value_options "")
+ set(multi_value_options RESOLVED_DEPENDENCIES)
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ set(webenginecore_dependency_found FALSE)
+ foreach(dependency IN LISTS arg_RESOLVED_DEPENDENCIES)
+ if(dependency MATCHES "/libQt[0-9]+WebEngineCore[^/]+")
+ set(webenginecore_dependency_found TRUE)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT webenginecore_dependency_found)
+ _qt_internal_webenginecore_status_message(
+ "No QtWebEngineCore dependency found. "
+ "Skipping deployment of QtWebEngine assets."
+ )
+ return()
+ endif()
+
+ _qt_internal_deploy_webenginecore()
+endfunction()
+
+function(_qt_internal_deploy_webenginecore)
+ _qt_internal_deploy_webenginecore_binary()
+ _qt_internal_deploy_webenginecore_data()
+ _qt_internal_deploy_webenginecore_translations()
+endfunction()
+
+function(_qt_internal_deploy_webenginecore_binary)
+ _qt_internal_webenginecore_status_message("Deploying the WebEngineCore process binary")
+
+ set(candidates "QtWebEngineProcess")
+ if(__QT_DEPLOY_ACTIVE_CONFIG STREQUAL "Debug" AND __QT_DEPLOY_SYSTEM_NAME STREQUAL "Windows")
+ list(PREPEND candidates "QtWebEngineProcessd")
+ endif()
+
+ list(TRANSFORM candidates
+ PREPEND "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_LIBEXECS}/"
+ )
+
+ set(process_path "")
+ foreach(file_path IN LISTS candidates)
+ if(EXISTS "${file_path}")
+ set(process_path "${file_path}")
+ break()
+ endif()
+ endforeach()
+
+ set(install_destination "${QT_DEPLOY_PREFIX}/")
+ if(__QT_DEPLOY_SYSTEM_NAME STREQUAL "Windows")
+ string(APPEND install_destination "${QT_DEPLOY_BIN_DIR}")
+ else()
+ string(APPEND install_destination "${QT_DEPLOY_LIBEXEC_DIR}")
+ endif()
+ file(INSTALL "${process_path}" DESTINATION "${install_destination}")
+
+ get_filename_component(process_file_name "${process_path}" NAME)
+ if(CMAKE_VERSION GREATER_EQUAL "3.19")
+ file(CHMOD "${install_destination}/${process_file_name}"
+ PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ )
+ else()
+ execute_process(
+ COMMAND chmod 0755 "${install_destination}/${process_file_name}"
+ )
+ endif()
+endfunction()
+
+function(_qt_internal_deploy_webenginecore_data)
+ _qt_internal_webenginecore_status_message("Deploying the WebEngineCore data files")
+ set(data_files
+ icudtl.dat
+ qtwebengine_devtools_resources.pak
+ qtwebengine_resources.pak
+ qtwebengine_resources_100p.pak
+ qtwebengine_resources_200p.pak
+ )
+ get_filename_component(resources_dir "resources" ABSOLUTE
+ BASE_DIR "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_DATA}"
+ )
+
+ _qt_internal_webenginecore_find_v8_context_snapshot(
+ snapshot_file
+ RESOURCES_DIR "${resources_dir}"
+ )
+ if(NOT snapshot_file STREQUAL "")
+ list(APPEND data_files "${snapshot_file}")
+ endif()
+
+ get_filename_component(install_destination "${QT_DEPLOY_WEBENGINECORE_RESOURCES_DIR}" ABSOLUTE
+ BASE_DIR "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_DATA_DIR}"
+ )
+ foreach(data_file IN LISTS data_files)
+ file(INSTALL "${resources_dir}/${data_file}" DESTINATION "${install_destination}")
+ endforeach()
+endfunction()
+
+# The V8 snapshot file comes as debug or release build. Multi-config builds have both, a self-built
+# Qt might only have the debug one.
+#
+# This function returns the file name of the V8 context snapshot file in ${out_var}.
+# If no snapshot could be found, ${out_var} is the empty string.
+function(_qt_internal_webenginecore_find_v8_context_snapshot out_var)
+ set(no_value_options "")
+ set(single_value_options RESOURCES_DIR)
+ set(multi_value_options "")
+ cmake_parse_arguments(PARSE_ARGV 1 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ set(result "")
+ set(candidates
+ v8_context_snapshot.bin
+ v8_context_snapshot.debug.bin
+ )
+ if(__QT_DEPLOY_QT_IS_MULTI_CONFIG_BUILD_WITH_DEBUG
+ AND __QT_DEPLOY_ACTIVE_CONFIG STREQUAL "Debug")
+ # Favor the debug version of the snapshot.
+ list(REVERSE candidates)
+ endif()
+ foreach(candidate IN LISTS candidates)
+ if(EXISTS "${arg_RESOURCES_DIR}/${candidate}")
+ set(result "${candidate}")
+ break()
+ endif()
+ endforeach()
+ set("${out_var}" "${result}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_deploy_webenginecore_translations)
+ _qt_internal_webenginecore_status_message("Deploying the WebEngineCore translations")
+
+ get_filename_component(locales_dir "qtwebengine_locales" ABSOLUTE
+ BASE_DIR "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_TRANSLATIONS}"
+ )
+ get_filename_component(install_destination "qtwebengine_locales" ABSOLUTE
+ BASE_DIR "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_TRANSLATIONS_DIR}"
+ )
+ file(GLOB locale_files "${locales_dir}/*.pak")
+ foreach(locale_file IN LISTS locale_files)
+ file(INSTALL "${locale_file}" DESTINATION "${install_destination}")
+ endforeach()
+endfunction()
diff --git a/src/core/api/Qt6WebEngineCoreMacros.cmake b/src/core/api/Qt6WebEngineCoreMacros.cmake
index ada067b3a..8bb731548 100644
--- a/src/core/api/Qt6WebEngineCoreMacros.cmake
+++ b/src/core/api/Qt6WebEngineCoreMacros.cmake
@@ -1,3 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Install support uses the CMAKE_INSTALL_xxxDIR variables. Include this here
+# so that it is more likely to get pulled in earlier at a higher level, and also
+# to avoid re-including it many times later
+include(GNUInstallDirs)
+_qt_internal_add_deploy_support("${CMAKE_CURRENT_LIST_DIR}/Qt6WebEngineCoreDeploySupport.cmake")
+
function(qt6_add_webengine_dictionary)
set(options)
set(oneValueArgs TARGET SOURCE OUTPUT_DIRECTORY)
@@ -14,11 +23,18 @@ function(qt6_add_webengine_dictionary)
endif()
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ get_target_property(isBundle ${ARGS_TARGET} MACOSX_BUNDLE)
if(isMultiConfig)
set(spellcheckerDir ${ARGS_OUTPUT_DIRECTORY}/dict/qtwebengine_dictionaries)
set(copyCommand COMMAND ${CMAKE_COMMAND} -E copy_directory ${ARGS_OUTPUT_DIRECTORY}/dict
${ARGS_OUTPUT_DIRECTORY}/$<CONFIG>
)
+ elseif(APPLE AND isBundle)
+ get_target_property(outputName ${ARGS_TARGET} OUTPUT_NAME)
+ if(NOT outputName)
+ set(outputName ${ARGS_TARGET})
+ endif()
+ set(spellcheckerDir "${ARGS_OUTPUT_DIRECTORY}/${outputName}.app/Contents/Resources/qtwebengine_dictionaries")
else()
set(spellcheckerDir ${ARGS_OUTPUT_DIRECTORY}/qtwebengine_dictionaries)
endif()
@@ -34,18 +50,19 @@ function(qt6_add_webengine_dictionary)
${ARGS_SOURCE} ${spellcheckerDir}/${dictName}.bdic
${copyCommand}
)
- if(NOT TARGET webengine_dictionaries)
- add_custom_target(webengine_dictionaries)
+ set(global_dict_target "qtwebengine_dictionaries")
+ if(NOT TARGET ${global_dict_target})
+ add_custom_target(${global_dict_target})
endif()
# in case of large project gen target should have unique name since it can collide, use TARGET
if (ARGS_TARGET)
add_custom_target(gen-${ARGS_TARGET}-${dictName} DEPENDS ${spellcheckerDir}/${dictName}.bdic)
add_dependencies(${ARGS_TARGET} gen-${ARGS_TARGET}-${dictName})
- add_dependencies(webengine_dictionaries gen-${ARGS_TARGET}-${dictName})
+ add_dependencies(${global_dict_target} gen-${ARGS_TARGET}-${dictName})
else()
add_custom_target(gen-${dictName} DEPENDS ${spellcheckerDir}/${dictName}.bdic)
- add_dependencies(webengine_dictionaries gen-${dictName})
+ add_dependencies(${global_dict_target} gen-${dictName})
endif()
endfunction()
diff --git a/src/core/api/configure.cmake b/src/core/api/configure.cmake
index e79bbbae3..f8488c057 100644
--- a/src/core/api/configure.cmake
+++ b/src/core/api/configure.cmake
@@ -1,13 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
#### Libraries
if(NOT QT_CONFIGURE_RUNNING)
+ find_package(GLIB2 COMPONENTS GIO)
+ find_package(GSSAPI)
find_package(PkgConfig)
- if(PkgConfig_FOUND)
+ if(PkgConfig_FOUND AND QT_FEATURE_pkg_config)
pkg_check_modules(ALSA alsa IMPORTED_TARGET)
pkg_check_modules(PULSEAUDIO libpulse>=0.9.10 libpulse-mainloop-glib)
- pkg_check_modules(GIO gio-2.0)
pkg_check_modules(XDAMAGE xdamage)
+ pkg_check_modules(POPPLER_CPP poppler-cpp IMPORTED_TARGET)
+ pkg_check_modules(GBM gbm)
+ pkg_check_modules(LIBVA libva>=1.14)
+ if(NOT GIO_FOUND)
+ pkg_check_modules(GIO gio-2.0)
+ endif()
endif()
+ find_package(Cups)
find_package(Qt6 ${PROJECT_VERSION} CONFIG QUIET
OPTIONAL_COMPONENTS Positioning WebChannel PrintSupport)
@@ -15,6 +26,19 @@ endif()
#### Tests
+qt_config_compile_test(poppler
+ LABEL "poppler"
+ LIBRARIES
+ PkgConfig::POPPLER_CPP
+ CODE
+"
+#include <poppler-document.h>
+
+int main() {
+ auto *pdf = poppler::document::load_from_raw_data(\"file\",100,std::string(\"user\"));
+}"
+)
+
qt_config_compile_test(alsa
LABEL "alsa"
LIBRARIES
@@ -40,9 +64,9 @@ qt_feature("webengine-system-alsa" PRIVATE
LABEL "Use ALSA"
CONDITION UNIX AND TEST_alsa
)
-qt_feature("webengine-v8-snapshot-support" PRIVATE
- LABEL "Building v8 snapshot supported"
- CONDITION NOT UNIX OR NOT QT_FEATURE_cross_compile OR ( TEST_architecture_arch STREQUAL arm64 ) OR TEST_webengine_host_compiler
+qt_feature("webengine-v8-context-snapshot" PRIVATE
+ LABEL "Use v8 context snapshot"
+ AUTODETECT NOT CMAKE_CROSSCOMPILING
)
qt_feature("webengine-geolocation" PUBLIC
LABEL "Geolocation"
@@ -53,16 +77,23 @@ qt_feature("webengine-system-pulseaudio" PRIVATE
AUTODETECT UNIX
CONDITION PULSEAUDIO_FOUND
)
-qt_feature("webengine-pepper-plugins" PRIVATE
- LABEL "Pepper Plugins"
- PURPOSE "Enables use of Pepper Flash plugins."
- AUTODETECT NOT QT_FEATURE_webengine_embedded_build
+qt_feature("webengine-system-gbm" PRIVATE
+ SECTION "WebEngine"
+ LABEL "Use system GBM"
+ AUTODETECT UNIX
+ CONDITION GBM_FOUND
)
qt_feature("webengine-printing-and-pdf" PRIVATE
LABEL "Printing and PDF"
PURPOSE "Provides printing and output to PDF."
AUTODETECT NOT QT_FEATURE_webengine_embedded_build
- CONDITION TARGET Qt::PrintSupport AND QT_FEATURE_printer
+ CONDITION TARGET Qt::PrintSupport AND QT_FEATURE_printer AND
+ (CUPS_FOUND OR WIN32)
+)
+qt_feature("webengine-pepper-plugins" PRIVATE
+ LABEL "Pepper Plugins"
+ PURPOSE "Enables use of Pepper plugins."
+ AUTODETECT QT_FEATURE_webengine_printing_and_pdf
)
qt_feature("webengine-webchannel" PUBLIC
SECTION "WebEngine"
@@ -81,6 +112,7 @@ qt_feature("webengine-kerberos" PRIVATE
LABEL "Kerberos Authentication"
PURPOSE "Enables Kerberos Authentication Support"
AUTODETECT WIN32
+ CONDITION NOT LINUX OR GSSAPI_FOUND
)
qt_feature("webengine-spellchecker" PUBLIC
LABEL "Spellchecker"
@@ -90,14 +122,14 @@ qt_feature("webengine-native-spellchecker" PUBLIC
LABEL "Native Spellchecker"
PURPOSE "Use the system's native spellchecking engine."
AUTODETECT OFF
- CONDITION MACOS AND QT_FEATURE_webengine_spellchecker
+ CONDITION QT_FEATURE_webengine_spellchecker AND NOT LINUX
)
qt_feature("webengine-extensions" PUBLIC
SECTION "WebEngine"
LABEL "Extensions"
- PURPOSE "Enables Chromium extensions within certain limits. Currently used for enabling the pdf viewer."
- AUTODETECT QT_FEATURE_webengine_printing_and_pdf
- CONDITION QT_FEATURE_webengine_printing_and_pdf
+ PURPOSE "Enables Chromium extensions within certain limits. Currently used by the pdf viewer and hangout webrtc extension."
+ AUTODETECT ON
+ CONDITION QT_FEATURE_webengine_printing_and_pdf OR QT_FEATURE_webengine_webrtc
)
qt_feature("webengine-webrtc" PRIVATE
LABEL "WebRTC"
@@ -126,6 +158,34 @@ qt_feature("webengine-sanitizer" PRIVATE
AUTODETECT CLANG
CONDITION CLANG AND ECM_ENABLE_SANITIZERS
)
+qt_feature("webengine-vulkan" PRIVATE
+ SECTION "WebEngine"
+ LABEL "Vulkan support"
+ PURPOSE "Enables support for Vulkan rendering"
+ CONDITION QT_FEATURE_vulkan
+)
+qt_feature("webengine-vaapi" PRIVATE
+ SECTION "WebEngine"
+ LABEL "VA-API support"
+ PURPOSE "Enables support for VA-API hardware acceleration"
+ AUTODETECT GBM_FOUND AND LIBVA_FOUND AND QT_FEATURE_vulkan
+ # hardware accelerated encoding requires bundled libvpx
+ CONDITION LINUX AND NOT QT_FEATURE_webengine_system_libvpx
+)
+list(LENGTH CMAKE_OSX_ARCHITECTURES osx_arch_count)
+qt_feature("webenginedriver" PUBLIC
+ SECTION "WebEngine"
+ LABEL "Build WebEngineDriver"
+ PURPOSE "Enables WebEngineDriver build"
+ CONDITION NOT CMAKE_CROSSCOMPILING
+ AND NOT (CMAKE_OSX_ARCHITECTURES AND osx_arch_count GREATER 1)
+ DISABLE CMAKE_BUILD_TYPE STREQUAL Debug
+)
+# internal testing feature
+qt_feature("webengine-system-poppler" PRIVATE
+ LABEL "poppler"
+ CONDITION UNIX AND TEST_poppler
+)
qt_configure_add_summary_section(NAME "Qt WebEngineCore")
qt_configure_add_summary_entry(ARGS "webengine-embedded-build")
qt_configure_add_summary_entry(ARGS "webengine-full-debug-info")
@@ -134,7 +194,10 @@ qt_configure_add_summary_entry(ARGS "webengine-pepper-plugins")
qt_configure_add_summary_entry(ARGS "webengine-printing-and-pdf")
qt_configure_add_summary_entry(ARGS "webengine-proprietary-codecs")
qt_configure_add_summary_entry(ARGS "webengine-spellchecker")
-qt_configure_add_summary_entry(ARGS "webengine-native-spellchecker")
+qt_configure_add_summary_entry(
+ ARGS "webengine-native-spellchecker"
+ CONDITION NOT LINUX
+)
qt_configure_add_summary_entry(ARGS "webengine-webrtc")
qt_configure_add_summary_entry(ARGS "webengine-webrtc-pipewire")
qt_configure_add_summary_entry(ARGS "webengine-geolocation")
@@ -146,17 +209,23 @@ qt_configure_add_summary_entry(
CONDITION UNIX
)
qt_configure_add_summary_entry(
- ARGS "webengine-v8-snapshot-support"
- CONDITION UNIX AND cross_compile
+ ARGS "webengine-vulkan"
+ CONDITION QT_FEATURE_vulkan
+)
+qt_configure_add_summary_entry(
+ ARGS "webengine-vaapi"
+ CONDITION LINUX
)
qt_configure_add_summary_entry(
ARGS "webengine-system-alsa"
- CONDITION UNIX
+ CONDITION LINUX
)
qt_configure_add_summary_entry(
ARGS "webengine-system-pulseaudio"
- CONDITION UNIX
+ CONDITION LINUX
)
+qt_configure_add_summary_entry(ARGS "webengine-v8-context-snapshot")
+qt_configure_add_summary_entry(ARGS "webenginedriver")
qt_configure_end_summary_section() # end of "Qt WebEngineCore" section
if(CMAKE_CROSSCOMPILING)
check_thumb(armThumb)
@@ -171,11 +240,16 @@ if(CMAKE_CROSSCOMPILING)
endif()
qt_configure_add_report_entry(
TYPE WARNING
- MESSAGE "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed."
- CONDITION UNIX AND cross_compile AND NOT QT_FEATURE_webengine_v8_snapshot_support
+ MESSAGE "WebRTC requires XDamage with qpa_xcb."
+ CONDITION QT_FEATURE_webengine_ozone_x11 AND NOT XDAMAGE_FOUND
)
qt_configure_add_report_entry(
TYPE WARNING
- MESSAGE "WebRTC requires XDamage with qpa_xcb."
- CONDITION QT_FEATURE_webengine_ozone_x11 AND NOT XDAMAGE_FOUND
+ MESSAGE "VA-API is incompatible with system libvpx."
+ CONDITION QT_FEATURE_webengine_system_libvpx AND QT_FEATURE_webengine_vaapi
+)
+qt_configure_add_report_entry(
+ TYPE WARNING
+ MESSAGE "System GBM is disabled. The bundled minigbm supports Intel only, you might need to install libgbm to avoid rendering issues."
+ CONDITION LINUX AND NOT QT_FEATURE_webengine_system_gbm
)
diff --git a/src/core/api/qt_cmdline.cmake b/src/core/api/qt_cmdline.cmake
index 42dd6b240..fe7092b8c 100644
--- a/src/core/api/qt_cmdline.cmake
+++ b/src/core/api/qt_cmdline.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_commandline_option(webengine-embedded-build TYPE boolean)
qt_commandline_option(webengine-pepper-plugins TYPE boolean)
qt_commandline_option(webengine-printing-and-pdf TYPE boolean)
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index 5215f7ce7..d5112ccb3 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -1,85 +1,31 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtwebenginecoreglobal_p.h"
#include <QGuiApplication>
#if QT_CONFIG(opengl)
# include <QOpenGLContext>
-#ifdef Q_OS_MACOS
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <QOffscreenSurface>
-#include "macos_context_type_helper.h"
-#endif
#endif
#include <QThread>
#include <QQuickWindow>
#include "web_engine_context.h"
+#include "web_engine_library_info.h"
-#if QT_CONFIG(opengl)
+#include "base/base_paths.h"
+#include "base/i18n/icu_util.h"
+#include "base/path_service.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+
+#if QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
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
#endif
-#if QT_CONFIG(opengl)
-#ifdef Q_OS_MACOS
-static bool needsOfflineRendererWorkaround()
-{
- size_t hwmodelsize = 0;
-
- if (sysctlbyname("hw.model", nullptr, &hwmodelsize, nullptr, 0) == -1)
- return false;
-
- char hwmodel[hwmodelsize];
- if (sysctlbyname("hw.model", &hwmodel, &hwmodelsize, nullptr, 0) == -1)
- return false;
-
- return QString::fromLatin1(hwmodel) == QLatin1String("MacPro6,1");
-}
-#endif
-#endif
-
namespace QtWebEngineCore {
-#if QT_CONFIG(opengl)
+#if QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
static QOpenGLContext *shareContext;
static void deleteShareContext()
@@ -96,16 +42,20 @@ static void deleteShareContext()
// after the QGuiApplication creation, when AA_ShareOpenGLContexts fills
// the same need but the flag has to be set earlier.
-Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
+Q_WEBENGINECORE_EXPORT void initialize()
{
-#if QT_CONFIG(opengl)
+#if QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
#ifdef Q_OS_WIN32
qputenv("QT_D3DCREATE_MULTITHREADED", "1");
#endif
-#ifdef Q_OS_MACOS
- if (needsOfflineRendererWorkaround())
- qputenv("QT_MAC_PRO_WEBENGINE_WORKAROUND", "1");
+ auto api = QQuickWindow::graphicsApi();
+ if (api != QSGRendererInterface::OpenGL
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+ && api != QSGRendererInterface::Vulkan && api != QSGRendererInterface::Metal
+ && api != QSGRendererInterface::Direct3D11
#endif
+ )
+ QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
// No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts).
if (!qt_gl_global_share_context()) {
@@ -130,57 +80,6 @@ Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
shareContext = new QOpenGLContext;
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
-#if defined(Q_OS_MACOS)
- if (format == QSurfaceFormat()) {
- QOpenGLContext testContext;
-
- // Chromium turns off OpenGL for CoreProfiles with versions < 4.1
- // The newest Mac that only supports 3.3 was released in Mid 2011,
- // so it should be safe to request 4.1, but we still double check it
- // works in order not to set an invalid default surface format.
- format.setVersion(4, 1);
- format.setProfile(QSurfaceFormat::CoreProfile);
-
- testContext.setFormat(format);
- if (testContext.create()) {
- QOffscreenSurface surface;
- surface.setFormat(format);
- surface.create();
-
- if (testContext.makeCurrent(&surface)) {
- // The Cocoa QPA integration allows sharing between OpenGL 3.2 and 4.1 contexts,
- // which means even though we requested a 4.1 context, if we only get a 3.2
- // context, it will still work an Chromium will not black list it.
- if (testContext.format().version() >= qMakePair(3, 2)
- && testContext.format().profile() == QSurfaceFormat::CoreProfile
- && !isCurrentContextSoftware()) {
- QSurfaceFormat::setDefaultFormat(format);
- } else {
- qWarning("The available OpenGL surface format was either not version 3.2 "
- "or higher or not a Core Profile.\n"
- "Chromium on macOS will fall back to software rendering in this "
- "case.\n"
- "Hardware acceleration and features such as WebGL will not be "
- "available.");
- format = QSurfaceFormat::defaultFormat();
- }
- testContext.doneCurrent();
- }
- surface.destroy();
- }
- } else {
- // The user explicitly requested a specific surface format that does not fit Chromium's
- // requirements. Warn them about this.
- if (format.version() < qMakePair(3, 2)
- || format.profile() != QSurfaceFormat::CoreProfile) {
- qWarning("An OpenGL surfcace format was requested that is either not version 3.2 "
- "or higher or a not Core Profile.\n"
- "Chromium on macOS will fall back to software rendering in this case.\n"
- "Hardware acceleration and features such as WebGL will not be available.");
- }
- }
-#endif
-
shareContext->setFormat(format);
shareContext->create();
qAddPostRoutine(deleteShareContext);
@@ -190,22 +89,7 @@ Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
app->setAttribute(Qt::AA_ShareOpenGLContexts);
}
-#if defined(Q_OS_MACOS)
- // Check that the default QSurfaceFormat OpenGL profile is compatible with the global OpenGL
- // shared context profile, otherwise this could lead to a nasty crash.
- QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
- QSurfaceFormat defaultFormat = QSurfaceFormat::defaultFormat();
-
- if (defaultFormat.profile() != sharedFormat.profile()
- && defaultFormat.profile() == QSurfaceFormat::CoreProfile
- && defaultFormat.version() >= qMakePair(3, 2)) {
- qFatal("QWebEngine: Default QSurfaceFormat OpenGL profile is not compatible with the "
- "global shared context OpenGL profile. Please make sure you set a compatible "
- "QSurfaceFormat before the QtGui application instance is created.");
- }
-#endif
-
-#endif // QT_CONFIG(opengl)
+#endif // QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
}
bool closingDown()
@@ -230,21 +114,29 @@ sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterf
#endif
static void initialize()
{
-#if QT_CONFIG(opengl)
- if (QCoreApplication::instance()) {
- // On window/ANGLE, calling QtWebEngineQuick::initialize from DllMain will result in a crash.
- if (!qt_gl_global_share_context()) {
- qWarning("Qt WebEngine seems to be initialized from a plugin. Please "
- "set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute and "
- "QSGRendererInterface::OpenGLRhi using QQuickWindow::setGraphicsApi "
- "before constructing QGuiApplication.");
- }
- return;
- }
- // QCoreApplication is not yet instantiated, ensuring the call will be deferred
- qAddPreRoutine(QtWebEngineCore::initialize);
- QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
+#if QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
+ // QCoreApplication is not yet instantiated, ensuring the call will be deferred
+ qAddPreRoutine(QtWebEngineCore::initialize);
#endif // QT_CONFIG(opengl)
}
+QT_BEGIN_NAMESPACE
+
+QString qWebEngineGetDomainAndRegistry(const QUrl &url) {
+ base::FilePath icuDataPath;
+ // Let's assume that ICU is already initialized if DIR_QT_LIBRARY_DATA is set.
+ if (!base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &icuDataPath)) {
+ icuDataPath = WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA);
+ if (!base::PathService::OverrideAndCreateIfNeeded(base::DIR_QT_LIBRARY_DATA, icuDataPath, false, false))
+ qWarning("Failed to set ICU data path.");
+ base::i18n::InitializeICU();
+ }
+
+ const QString host = url.host();
+ const std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(host.toStdString(), net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+ return QString::fromStdString(domain);
+}
+
+QT_END_NAMESPACE
+
Q_CONSTRUCTOR_FUNCTION(initialize)
diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h
index 81039a1af..0041a72be 100644
--- a/src/core/api/qtwebenginecoreglobal.h
+++ b/src/core/api/qtwebenginecoreglobal.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTWEBENGINECOREGLOBAL_H
#define QTWEBENGINECOREGLOBAL_H
@@ -45,6 +9,8 @@
QT_BEGIN_NAMESPACE
+class QUrl;
+
#if defined(BUILDING_CHROMIUM)
# define Q_WEBENGINECORE_EXPORT Q_DECL_EXPORT
#else
@@ -54,9 +20,12 @@ QT_BEGIN_NAMESPACE
#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match");
Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineVersion() noexcept;
+Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineProcessName() noexcept;
Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineChromiumVersion() noexcept;
Q_WEBENGINECORE_EXPORT Q_DECL_CONST_FUNCTION const char *qWebEngineChromiumSecurityPatchVersion() noexcept;
+Q_WEBENGINECORE_EXPORT QString qWebEngineGetDomainAndRegistry(const QUrl &url);
+
QT_END_NAMESPACE
#endif // QTWEBENGINECOREGLOBAL_H
diff --git a/src/core/api/qtwebenginecoreglobal_p.h b/src/core/api/qtwebenginecoreglobal_p.h
index a716f5827..a63568c8a 100644
--- a/src/core/api/qtwebenginecoreglobal_p.h
+++ b/src/core/api/qtwebenginecoreglobal_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTWEBENGINECOREGLOBAL_P_H
#define QTWEBENGINECOREGLOBAL_P_H
@@ -63,18 +27,16 @@
#define QT_NOT_USED Q_UNREACHABLE(); // This will assert in debug.
#endif
-#define Q_WEBENGINECORE_PRIVATE_EXPORT Q_WEBENGINECORE_EXPORT
-
namespace QtWebEngineCore {
-Q_WEBENGINECORE_PRIVATE_EXPORT int processMain(int argc, const char **argv);
-Q_WEBENGINECORE_PRIVATE_EXPORT bool closingDown();
+Q_WEBENGINECORE_EXPORT int processMain(int argc, const char **argv);
+Q_WEBENGINECORE_EXPORT bool closingDown();
} // namespace
#if defined(Q_OS_WIN)
namespace sandbox {
struct SandboxInterfaceInfo;
}
namespace QtWebEngineSandbox {
-Q_WEBENGINECORE_PRIVATE_EXPORT sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info = nullptr);
+Q_WEBENGINECORE_EXPORT sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info = nullptr);
void initializeStaticCopy(int argc, const char **argv);
}
#endif
diff --git a/src/core/api/qwebenginecertificateerror.cpp b/src/core/api/qwebenginecertificateerror.cpp
index 748387300..90d8a542d 100644
--- a/src/core/api/qwebenginecertificateerror.cpp
+++ b/src/core/api/qwebenginecertificateerror.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginecertificateerror.h"
@@ -98,8 +62,8 @@ QWebEngineCertificateError::~QWebEngineCertificateError() = default;
\value CertificateKnownInterceptionBlocked The certificate is known to be
used for interception by an entity other the device owner. (Added in
5.15)
- \value SslObsoleteVersion The connection uses an obsolete version of SSL/TLS. (Added in Qt 6.0)
- \value CertificateSymantecLegacy The certificate is a legacy Symantec one that's no longer valid. (Added in Qt 6.0)
+ \value SslObsoleteVersion The connection uses an obsolete version of SSL/TLS. (Added in Qt 6.2, deprecated in Qt 6.4)
+ \value CertificateSymantecLegacy The certificate is a legacy Symantec one that's no longer valid. (Added in Qt 6.2)
*/
/*!
@@ -194,3 +158,5 @@ QList<QSslCertificate> QWebEngineCertificateError::certificateChain() const
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginecertificateerror.cpp"
diff --git a/src/core/api/qwebenginecertificateerror.h b/src/core/api/qwebenginecertificateerror.h
index 82ef5017a..c4a3585f4 100644
--- a/src/core/api/qwebenginecertificateerror.h
+++ b/src/core/api/qwebenginecertificateerror.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECERTIFICATEERROR_H
#define QWEBENGINECERTIFICATEERROR_H
diff --git a/src/core/api/qwebengineclientcertificateselection.cpp b/src/core/api/qwebengineclientcertificateselection.cpp
index 7df5cb57a..d6402353c 100644
--- a/src/core/api/qwebengineclientcertificateselection.cpp
+++ b/src/core/api/qwebengineclientcertificateselection.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineclientcertificateselection.h"
#include "client_cert_select_controller.h"
diff --git a/src/core/api/qwebengineclientcertificateselection.h b/src/core/api/qwebengineclientcertificateselection.h
index 71c85f154..559d1753b 100644
--- a/src/core/api/qwebengineclientcertificateselection.h
+++ b/src/core/api/qwebengineclientcertificateselection.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECLIENTCERTSELECTION_H
#define QWEBENGINECLIENTCERTSELECTION_H
diff --git a/src/core/api/qwebengineclientcertificatestore.cpp b/src/core/api/qwebengineclientcertificatestore.cpp
index 4d84bd165..3d231c05f 100644
--- a/src/core/api/qwebengineclientcertificatestore.cpp
+++ b/src/core/api/qwebengineclientcertificatestore.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineclientcertificatestore.h"
@@ -56,7 +20,21 @@ QT_BEGIN_NAMESPACE
The class allows to store client certificates in an in-memory store.
When a web site requests an SSL client certificate, the QWebEnginePage::selectClientCertificate
signal is emitted with matching certificates from the native certificate store or the in-memory store.
- The getInstance() method can be used to access the single instance of the class.
+
+ The class instance can be obtained with the QWebEngineProfile::clientCertificateStore() method.
+
+ \code
+ QFile certFile(":/resouces/certificate.crt");
+ certFile.open(QIODevice::ReadOnly);
+ const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
+
+ QFile keyFile(":/resources/privatekey.key");
+ keyFile.open(QIODevice::ReadOnly);
+ const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ QWebEngineProfile profile;
+ profile.clientCertificateStore()->add(cert, sslKey);
+ \endcode
*/
QWebEngineClientCertificateStore::QWebEngineClientCertificateStore(QtWebEngineCore::ClientCertificateStoreData *storeData)
@@ -90,7 +68,7 @@ void QWebEngineClientCertificateStore::add(const QSslCertificate &certificate, c
QList<QSslCertificate> QWebEngineClientCertificateStore::certificates() const
{
QList<QSslCertificate> certificateList;
- for (auto data : qAsConst(m_storeData->extraCerts))
+ for (auto data : std::as_const(m_storeData->extraCerts))
certificateList.append(data->certificate);
return certificateList;
}
diff --git a/src/core/api/qwebengineclientcertificatestore.h b/src/core/api/qwebengineclientcertificatestore.h
index 12ac9c6be..fcebbe2b1 100644
--- a/src/core/api/qwebengineclientcertificatestore.h
+++ b/src/core/api/qwebengineclientcertificatestore.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECLIENTCERTIFICATESTORE_H
#define QWEBENGINECLIENTCERTIFICATESTORE_H
diff --git a/src/core/api/qwebengineclienthints.cpp b/src/core/api/qwebengineclienthints.cpp
new file mode 100644
index 000000000..907d4ae76
--- /dev/null
+++ b/src/core/api/qwebengineclienthints.cpp
@@ -0,0 +1,211 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebengineclienthints.h"
+
+#include "profile_adapter.h"
+
+#include <QJsonObject>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWebEngineClientHints
+ \brief The QWebEngineClientHints class provides an object to customize User-Agent Client Hints used by a profile.
+
+ \since 6.8
+
+ \inmodule QtWebEngineCore
+
+ QWebEngineClientHints allows configuration of exposing browser and platform information via
+ User-Agent response and request headers, and a JavaScript API.
+
+ The information accessed via this API is split into two groups: low entropy and high entropy hints.
+ Low entropy hints (\l{QWebEngineClientHints::platform}{platform} and \l{QWebEngineClientHints::mobile}{mobile})
+ are those that do not give away much information; the API makes these accessible with every request and they can not
+ be disabled by QWebEngineClientHints::setAllClientHintsEnabled.
+
+ All the others are high entropy hints; they have the potential to give away more information, therefore they can be
+ disabled by QWebEngineClientHints::setAllClientHintsEnabled.
+
+ Each profile object has its own QWebEngineClientHints object, which configures the
+ Client Hint settings for that browsing context. If a Client Hint is not configured for a web engine
+ profile, its default value is deduced from the system.
+
+ \sa QWebEngineProfile::clientHints(), QQuickWebEngineProfile::clientHints()
+*/
+
+QWebEngineClientHints::QWebEngineClientHints(QtWebEngineCore::ProfileAdapter *profileAdapter)
+ : m_profileAdapter(profileAdapter)
+{
+}
+
+QWebEngineClientHints::~QWebEngineClientHints()
+{
+}
+
+/*!
+ \property QWebEngineClientHints::arch
+ The value of the \c{Sec-CH-UA-Arch} HTTP header and \c{architecture} member of NavigatorUAData in JavaScript.
+*/
+QString QWebEngineClientHints::arch() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAArchitecture).toString();
+}
+
+/*!
+ \property QWebEngineClientHints::platform
+ The value of the \c{Sec-CH-UA-Platform} HTTP header and \c{platform} member of NavigatorUAData in JavaScript.
+
+ Can not be disabled.
+*/
+QString QWebEngineClientHints::platform() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAPlatform).toString();
+}
+
+/*!
+ \property QWebEngineClientHints::model
+ The value of the \c{Sec-CH-UA-Model} HTTP header and \c{model} member of NavigatorUAData in JavaScript.
+*/
+QString QWebEngineClientHints::model() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAModel).toString();
+}
+
+/*!
+ \property QWebEngineClientHints::mobile
+ The value of the \c{Sec-CH-UA-Mobile} HTTP header and \c{mobile} member of NavigatorUAData in JavaScript.
+
+ Can not be disabled.
+*/
+bool QWebEngineClientHints::isMobile() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAMobile).toBool();
+}
+
+/*!
+ \property QWebEngineClientHints::fullVersion
+ The value of the \c{Sec-CH-UA-Full-Version} HTTP header and \c{uaFullVersion} member of NavigatorUAData in JavaScript.
+*/
+QString QWebEngineClientHints::fullVersion() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAFullVersion).toString();
+}
+
+/*!
+ \property QWebEngineClientHints::platformVersion
+ The value of the \c{Sec-CH-UA-Platform-Version} HTTP header and \c{platformVersion} member of NavigatorUAData in JavaScript.
+*/
+QString QWebEngineClientHints::platformVersion() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAPlatformVersion).toString();
+}
+
+/*!
+ \property QWebEngineClientHints::bitness
+ The value of the \c{Sec-CH-UA-Bitness} HTTP header and \c{bitness} member of NavigatorUAData in JavaScript.
+*/
+QString QWebEngineClientHints::bitness() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UABitness).toString();
+}
+
+/*!
+ \property QWebEngineClientHints::fullVersionList
+ The value of the \c{Sec-CH-UA-Full-Version-List} HTTP header and \c{fullVersionList} member of NavigatorUAData in JavaScript.
+
+ It holds brand name and version number pairs in a QHash. The provided values will be automatically extended by the currently used version
+ of Chromium and a semi-random brand.
+*/
+QHash<QString,QString> QWebEngineClientHints::fullVersionList() const
+{
+ QHash<QString, QString> ret;
+ QJsonObject fullVersionList = m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAFullVersionList).toJsonObject();
+ for (const QString &key : fullVersionList.keys())
+ ret.insert(key, fullVersionList.value(key).toString());
+ return ret;
+}
+
+/*!
+ \property QWebEngineClientHints::wow64
+ The value of the \c{Sec-CH-UA-Wow64} HTTP header and \c{wow64} member of NavigatorUAData in JavaScript.
+*/
+bool QWebEngineClientHints::isWow64() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAWOW64).toBool();
+}
+
+void QWebEngineClientHints::setArch(const QString &arch)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAArchitecture, QVariant(arch));
+}
+
+void QWebEngineClientHints::setPlatform(const QString &platform)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAPlatform, QVariant(platform));
+}
+
+void QWebEngineClientHints::setModel(const QString &model)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAModel, QVariant(model));
+}
+
+void QWebEngineClientHints::setIsMobile(const bool mobile)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAMobile, QVariant(mobile));
+}
+
+void QWebEngineClientHints::setFullVersion(const QString &fullVerson)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAFullVersion, QVariant(fullVerson));
+}
+
+void QWebEngineClientHints::setPlatformVersion(const QString &platformVersion)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAPlatformVersion, QVariant(platformVersion));
+}
+
+void QWebEngineClientHints::setBitness(const QString &bitness)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UABitness, QVariant(bitness));
+}
+
+void QWebEngineClientHints::setFullVersionList(const QHash<QString,QString> &fullVersionList)
+{
+ QJsonObject jsonObject;
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ jsonObject.insert(i.key(), QJsonValue(i.value()));
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAFullVersionList, QVariant(jsonObject));
+}
+
+void QWebEngineClientHints::setIsWow64(const bool wow64)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAWOW64, QVariant(wow64));
+}
+
+/*!
+ \property QWebEngineClientHints::isAllClientHintsEnabled
+ This property controls whether the Client Hints HTTP headers are sent by WebEngine or not.
+
+ Enabled by default.
+*/
+bool QWebEngineClientHints::isAllClientHintsEnabled()
+{
+ return m_profileAdapter->clientHintsEnabled();
+}
+
+void QWebEngineClientHints::setAllClientHintsEnabled(bool enabled)
+{
+ m_profileAdapter->setClientHintsEnabled(enabled);
+}
+
+/*!
+ Resets all Client Hints settings to their default values.
+*/
+void QWebEngineClientHints::resetAll()
+{
+ m_profileAdapter->resetClientHints();
+}
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineclienthints.h b/src/core/api/qwebengineclienthints.h
new file mode 100644
index 000000000..8956b5cb6
--- /dev/null
+++ b/src/core/api/qwebengineclienthints.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINECLIENTHINTS_H
+#define QWEBENGINECLIENTHINTS_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qhash.h>
+
+namespace QtWebEngineCore {
+class ProfileAdapter;
+}
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINECORE_EXPORT QWebEngineClientHints
+{
+ Q_GADGET
+ Q_PROPERTY(QString arch READ arch WRITE setArch)
+ Q_PROPERTY(QString platform READ platform WRITE setPlatform)
+ Q_PROPERTY(QString model READ model WRITE setModel)
+ Q_PROPERTY(bool mobile READ isMobile WRITE setIsMobile)
+ Q_PROPERTY(QString fullVersion READ fullVersion WRITE setFullVersion)
+ Q_PROPERTY(QString platformVersion READ platformVersion WRITE setPlatformVersion)
+ Q_PROPERTY(QString bitness READ bitness WRITE setBitness)
+ Q_PROPERTY(QHash<QString,QString> fullVersionList READ fullVersionList WRITE setFullVersionList)
+ Q_PROPERTY(bool wow64 READ isWow64 WRITE setIsWow64)
+
+ Q_PROPERTY(bool isAllClientHintsEnabled READ isAllClientHintsEnabled WRITE setAllClientHintsEnabled)
+
+public:
+ ~QWebEngineClientHints();
+
+ QString arch() const;
+ QString platform() const;
+ QString model() const;
+ bool isMobile() const;
+ QString fullVersion() const;
+ QString platformVersion() const;
+ QString bitness() const;
+ QHash<QString,QString> fullVersionList() const;
+ bool isWow64() const;
+
+ void setArch(const QString &);
+ void setPlatform(const QString &);
+ void setModel(const QString &);
+ void setIsMobile(const bool);
+ void setFullVersion(const QString &);
+ void setPlatformVersion(const QString &);
+ void setBitness(const QString &);
+ void setFullVersionList(const QHash<QString,QString> &);
+ void setIsWow64(const bool);
+
+ bool isAllClientHintsEnabled();
+ void setAllClientHintsEnabled(bool enabled);
+
+ void resetAll();
+
+private:
+ explicit QWebEngineClientHints(QtWebEngineCore::ProfileAdapter *profileAdapter);
+ Q_DISABLE_COPY(QWebEngineClientHints)
+ friend class QWebEngineProfilePrivate;
+ friend class QQuickWebEngineProfilePrivate;
+
+ QtWebEngineCore::ProfileAdapter *m_profileAdapter;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINECLIENTHINTS_H
diff --git a/src/core/api/qwebenginecontextmenurequest.cpp b/src/core/api/qwebenginecontextmenurequest.cpp
index 24ea3a073..25de1fe6b 100644
--- a/src/core/api/qwebenginecontextmenurequest.cpp
+++ b/src/core/api/qwebenginecontextmenurequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginecontextmenurequest.h"
#include "qwebenginecontextmenurequest_p.h"
@@ -292,3 +256,5 @@ bool QWebEngineContextMenuRequest::hasImageContent() const
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginecontextmenurequest.cpp"
diff --git a/src/core/api/qwebenginecontextmenurequest.h b/src/core/api/qwebenginecontextmenurequest.h
index a5911463a..6e6f6338c 100644
--- a/src/core/api/qwebenginecontextmenurequest.h
+++ b/src/core/api/qwebenginecontextmenurequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECONTEXTMENUREQUEST_H
#define QWEBENGINECONTEXTMENUREQUEST_H
diff --git a/src/core/api/qwebenginecontextmenurequest_p.h b/src/core/api/qwebenginecontextmenurequest_p.h
index c7b98a871..0e774f534 100644
--- a/src/core/api/qwebenginecontextmenurequest_p.h
+++ b/src/core/api/qwebenginecontextmenurequest_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECONTEXTMENUREQUEST_P_H
#define QWEBENGINECONTEXTMENUREQUEST_P_H
diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp
index e8d552caf..6c4536a4a 100644
--- a/src/core/api/qwebenginecookiestore.cpp
+++ b/src/core/api/qwebenginecookiestore.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginecookiestore.h"
#include "qwebenginecookiestore_p.h"
@@ -94,7 +58,7 @@ void QWebEngineCookieStorePrivate::processPendingUserCookies()
if (m_pendingUserCookies.isEmpty())
return;
- for (const CookieData &cookieData : qAsConst(m_pendingUserCookies)) {
+ for (const CookieData &cookieData : std::as_const(m_pendingUserCookies)) {
if (cookieData.wasDelete)
delegate->deleteCookie(cookieData.cookie, cookieData.origin);
else
@@ -410,3 +374,5 @@ void QWebEngineCookieStore::setCookieFilter(std::function<bool(const FilterReque
*/
QT_END_NAMESPACE
+
+#include "moc_qwebenginecookiestore.cpp"
diff --git a/src/core/api/qwebenginecookiestore.h b/src/core/api/qwebenginecookiestore.h
index e73222bcd..347d0c45c 100644
--- a/src/core/api/qwebenginecookiestore.h
+++ b/src/core/api/qwebenginecookiestore.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECOOKIESTORE_H
#define QWEBENGINECOOKIESTORE_H
diff --git a/src/core/api/qwebenginecookiestore_p.h b/src/core/api/qwebenginecookiestore_p.h
index 9f26604a6..51200436d 100644
--- a/src/core/api/qwebenginecookiestore_p.h
+++ b/src/core/api/qwebenginecookiestore_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINECOOKIESTORE_P_H
#define QWEBENGINECOOKIESTORE_P_H
@@ -65,7 +29,7 @@ class CookieMonsterDelegateQt;
QT_BEGIN_NAMESPACE
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineCookieStorePrivate
+class Q_WEBENGINECORE_EXPORT QWebEngineCookieStorePrivate
{
Q_DECLARE_PUBLIC(QWebEngineCookieStore)
struct CookieData {
diff --git a/src/core/api/qwebenginedesktopmediarequest.cpp b/src/core/api/qwebenginedesktopmediarequest.cpp
new file mode 100644
index 000000000..dae69a68c
--- /dev/null
+++ b/src/core/api/qwebenginedesktopmediarequest.cpp
@@ -0,0 +1,206 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "desktop_media_controller.h"
+#include "qwebenginedesktopmediarequest.h"
+#include "qwebenginedesktopmediarequest_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QWebEngineDesktopMediaRequestPrivate)
+
+/*!
+ \class QWebEngineDesktopMediaRequest
+ \brief A request for populating a dialog with available sources for screen capturing.
+
+ \since 6.7
+
+ \inmodule QtWebEngineCore
+
+ To allow web applications to capture contents of a display, applications must connect
+ to QWebEnginePage::desktopMediaRequested, which takes a QWebEngineDesktopMediaRequest
+ instance as an argument.
+
+ If a web application requests access to the contents of a display,
+ QWebEnginePage::desktopMediaRequested will be emitted with a
+ QWebEngineDesktopMediaRequest instance as an argument which holds references to
+ QAbstractListModels for available windows and screens that can be captured.
+
+ The data model's \e Qt::DisplayRole specifies the name of the source which is the title of a
+ window or the number of the display.
+ The model is dynamically updates if the available list of sources has changed e.g a window is
+ opened/closed.
+
+ The signal handler needs to then either call QWebEngineDesktopMediaRequest:selectScreen() or
+ QWebEngineDesktopMediaRequest::selectWindow() to accept the request and start screensharing.
+ \sa QWebEnginePage::desktopMediaRequested().
+*/
+
+class QWebEngineMediaSourceModel : public QAbstractListModel
+{
+public:
+ ~QWebEngineMediaSourceModel() override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+private:
+ friend class QWebEngineDesktopMediaRequestPrivate;
+ explicit QWebEngineMediaSourceModel(QtWebEngineCore::DesktopMediaListQt *mediaList);
+ QtWebEngineCore::DesktopMediaListQt *m_mediaList;
+};
+
+QWebEngineMediaSourceModel::QWebEngineMediaSourceModel(QtWebEngineCore::DesktopMediaListQt *mediaList)
+ : m_mediaList(mediaList)
+{
+ QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceAdded, this,
+ [this](int index) {
+ beginInsertRows(QModelIndex(), index, index);
+ endInsertRows();
+ });
+ QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceRemoved, this,
+ [this](int index) {
+ beginRemoveRows(QModelIndex(), index, index);
+ endRemoveRows();
+ });
+ QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceMoved, this,
+ [this](int oldIndex, int newIndex) {
+ beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
+ endMoveRows();
+ });
+ QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceNameChanged, this,
+ [this](int index) {
+ Q_EMIT dataChanged(QModelIndex(), QModelIndex(),
+ { Qt::DisplayRole });
+ });
+}
+
+QWebEngineMediaSourceModel::~QWebEngineMediaSourceModel() { }
+
+int QWebEngineMediaSourceModel::rowCount(const QModelIndex &) const
+{
+ return m_mediaList->getSourceCount();
+}
+
+QVariant QWebEngineMediaSourceModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+ switch (role) {
+ case Qt::DisplayRole:
+ case Qt::EditRole:
+ return m_mediaList->getSourceName(index.row());
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QWebEngineDesktopMediaRequestPrivate::QWebEngineDesktopMediaRequestPrivate(
+ QtWebEngineCore::DesktopMediaController *controller)
+ : controller(controller)
+ , m_screensModel(new QWebEngineMediaSourceModel(controller->screens()))
+ , m_windowsModel(new QWebEngineMediaSourceModel(controller->windows()))
+{
+}
+
+QWebEngineDesktopMediaRequestPrivate::~QWebEngineDesktopMediaRequestPrivate()
+{
+ // Keep old behavior, if there were no user action select the primary screen.
+ if (!didSelectOrCancel)
+ controller->selectScreen(0);
+}
+
+void QWebEngineDesktopMediaRequestPrivate::selectWindow(const QModelIndex &index)
+{
+ Q_ASSERT(index.model() == m_windowsModel.get());
+ if (!index.isValid())
+ return;
+ didSelectOrCancel = true;
+ controller->selectWindow(index.row());
+}
+
+void QWebEngineDesktopMediaRequestPrivate::selectScreen(const QModelIndex &index)
+{
+ Q_ASSERT(index.model() == m_screensModel.get());
+ if (!index.isValid())
+ return;
+ didSelectOrCancel = true;
+ controller->selectScreen(index.row());
+}
+
+void QWebEngineDesktopMediaRequestPrivate::cancel()
+{
+ // Notifies webrtc so it can free up it's resources.
+ didSelectOrCancel = true;
+ controller->cancel();
+}
+
+QWebEngineDesktopMediaRequest::QWebEngineDesktopMediaRequest(
+ QtWebEngineCore::DesktopMediaController *controller)
+ : d(new QWebEngineDesktopMediaRequestPrivate(controller))
+{
+}
+
+QWebEngineDesktopMediaRequest::~QWebEngineDesktopMediaRequest() = default;
+
+QWebEngineDesktopMediaRequest::QWebEngineDesktopMediaRequest(
+ const QWebEngineDesktopMediaRequest &other) noexcept = default;
+
+QWebEngineDesktopMediaRequest &QWebEngineDesktopMediaRequest::operator=(
+ const QWebEngineDesktopMediaRequest &other) noexcept = default;
+
+QWebEngineDesktopMediaRequest::QWebEngineDesktopMediaRequest(
+ QWebEngineDesktopMediaRequest &&other) noexcept = default;
+
+/*!
+ Returns a QAbstractListModel for the available screens.
+
+ \sa windowsModel()
+*/
+QAbstractListModel *QWebEngineDesktopMediaRequest::screensModel() const
+{
+ return d->m_screensModel.get();
+}
+
+/*!
+ Returns a QAbstractListModel for the available windows.
+
+ \sa screensModel()
+*/
+QAbstractListModel *QWebEngineDesktopMediaRequest::windowsModel() const
+{
+ return d->m_windowsModel.get();
+}
+
+/*!
+ Selects the window on the \a index to be captured.
+
+ \sa QWebEngineDesktopMediaRequest::selectScreen()
+*/
+void QWebEngineDesktopMediaRequest::selectWindow(const QModelIndex &index) const
+{
+ d->selectWindow(index);
+}
+
+/*!
+ Selects the screen on the \a index to be captured.
+
+ \sa QWebEngineDesktopMediaRequest::selectWindow()
+*/
+void QWebEngineDesktopMediaRequest::selectScreen(const QModelIndex &index) const
+{
+ d->selectScreen(index);
+}
+
+/*!
+ Rejects a request. Screen capturing will be aborted.
+*/
+void QWebEngineDesktopMediaRequest::cancel() const
+{
+ d->cancel();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginedesktopmediarequest.cpp"
diff --git a/src/core/api/qwebenginedesktopmediarequest.h b/src/core/api/qwebenginedesktopmediarequest.h
new file mode 100644
index 000000000..ebf66bce4
--- /dev/null
+++ b/src/core/api/qwebenginedesktopmediarequest.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEDESKTOPMEDIAREQUEST_H
+#define QWEBENGINEDESKTOPMEDIAREQUEST_H
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qobject.h>
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+namespace QtWebEngineCore {
+class DesktopMediaController;
+}
+
+QT_BEGIN_NAMESPACE
+class QWebEnginePagePrivate;
+class QQuickWebEngineViewPrivate;
+class QWebEngineDesktopMediaRequestPrivate;
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QWebEngineDesktopMediaRequestPrivate,
+ Q_WEBENGINECORE_EXPORT)
+
+class QWebEngineDesktopMediaRequest
+{
+ Q_GADGET_EXPORT(Q_WEBENGINECORE_EXPORT)
+ Q_PROPERTY(QAbstractListModel *screensModel READ screensModel FINAL)
+ Q_PROPERTY(QAbstractListModel *windowsModel READ windowsModel FINAL)
+
+public:
+ Q_WEBENGINECORE_EXPORT ~QWebEngineDesktopMediaRequest();
+
+ Q_WEBENGINECORE_EXPORT
+ QWebEngineDesktopMediaRequest(const QWebEngineDesktopMediaRequest &other) noexcept;
+ Q_WEBENGINECORE_EXPORT
+ QWebEngineDesktopMediaRequest(QWebEngineDesktopMediaRequest &&other) noexcept;
+ Q_WEBENGINECORE_EXPORT
+ QWebEngineDesktopMediaRequest &operator=(const QWebEngineDesktopMediaRequest &other) noexcept;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QWebEngineDesktopMediaRequest)
+ void swap(QWebEngineDesktopMediaRequest &other) noexcept { d.swap(other.d); }
+
+ Q_WEBENGINECORE_EXPORT QAbstractListModel *screensModel() const;
+ Q_WEBENGINECORE_EXPORT QAbstractListModel *windowsModel() const;
+
+ Q_WEBENGINECORE_EXPORT Q_INVOKABLE void selectScreen(const QModelIndex &index) const;
+ Q_WEBENGINECORE_EXPORT Q_INVOKABLE void selectWindow(const QModelIndex &index) const;
+ Q_WEBENGINECORE_EXPORT Q_INVOKABLE void cancel() const;
+
+private:
+ friend class QWebEnginePagePrivate;
+ friend class QQuickWebEngineViewPrivate;
+ Q_WEBENGINECORE_EXPORT explicit QWebEngineDesktopMediaRequest(
+ QtWebEngineCore::DesktopMediaController *controller);
+ QExplicitlySharedDataPointer<QWebEngineDesktopMediaRequestPrivate> d;
+};
+Q_DECLARE_SHARED(QWebEngineDesktopMediaRequest)
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEDESKTOPMEDIAREQUEST_H
diff --git a/src/core/api/qwebenginedesktopmediarequest_p.h b/src/core/api/qwebenginedesktopmediarequest_p.h
new file mode 100644
index 000000000..3add71bc0
--- /dev/null
+++ b/src/core/api/qwebenginedesktopmediarequest_p.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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.
+//
+
+#ifndef QWEBENGINEDESKTOPMEDIAREQUEST_P_H
+#define QWEBENGINEDESKTOPMEDIAREQUEST_P_H
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/QSharedData>
+#include <QtCore/qobject.h>
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+namespace QtWebEngineCore {
+class DesktopMediaController;
+}
+
+QT_BEGIN_NAMESPACE
+class QWebEngineMediaSourceModel;
+
+class QWebEngineDesktopMediaRequestPrivate : public QSharedData
+{
+public:
+ ~QWebEngineDesktopMediaRequestPrivate();
+ explicit QWebEngineDesktopMediaRequestPrivate(
+ QtWebEngineCore::DesktopMediaController *controller);
+
+ void selectScreen(const QModelIndex &index);
+ void selectWindow(const QModelIndex &index);
+ void cancel();
+
+ bool didSelectOrCancel = false;
+ std::unique_ptr<QtWebEngineCore::DesktopMediaController> controller;
+ std::unique_ptr<QWebEngineMediaSourceModel> m_screensModel;
+ std::unique_ptr<QWebEngineMediaSourceModel> m_windowsModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEDESKTOPMEDIAREQUEST_P_H
diff --git a/src/core/api/qwebenginedownloadrequest.cpp b/src/core/api/qwebenginedownloadrequest.cpp
index 222336239..cbf46b448 100644
--- a/src/core/api/qwebenginedownloadrequest.cpp
+++ b/src/core/api/qwebenginedownloadrequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginedownloadrequest.h"
#include "qwebenginedownloadrequest_p.h"
@@ -159,20 +123,9 @@ static inline QWebEngineDownloadRequest::DownloadInterruptReason toDownloadInter
QWebEnginePage::download, QWebEnginePage::save
*/
-QWebEngineDownloadRequestPrivate::QWebEngineDownloadRequestPrivate(QtWebEngineCore::ProfileAdapter *adapter, const QUrl &url)
- : downloadFinished(false)
- , downloadId(-1)
- , downloadState(QWebEngineDownloadRequest::DownloadCancelled)
- , savePageFormat(QWebEngineDownloadRequest::MimeHtmlSaveFormat)
- , interruptReason(QWebEngineDownloadRequest::NoReason)
- , downloadUrl(url)
- , downloadPaused(false)
- , isCustomFileName(false)
- , totalBytes(-1)
- , receivedBytes(0)
- , isSavePageDownload(false)
- , profileAdapter(adapter)
- , adapterClient(nullptr)
+QWebEngineDownloadRequestPrivate::QWebEngineDownloadRequestPrivate(
+ QtWebEngineCore::ProfileAdapter *adapter)
+ : profileAdapter(adapter)
{
}
@@ -266,16 +219,22 @@ void QWebEngineDownloadRequest::cancel()
QWebEngineDownloadRequest::DownloadState state = d->downloadState;
- if (state == QWebEngineDownloadRequest::DownloadCompleted
- || state == QWebEngineDownloadRequest::DownloadCancelled)
+ if (state == QWebEngineDownloadRequest::DownloadCompleted)
return;
- // We directly cancel the download request if the user cancels
- // before it even started, so no need to notify the profile here.
+ bool cancelled = state == QWebEngineDownloadRequest::DownloadCancelled;
+ if (cancelled)
+ return;
+
+ // Check if the download manager has a DownloadItem for this ID
+ // (network downloads or in progress page/resource saves)
if (state == QWebEngineDownloadRequest::DownloadInProgress) {
if (d->profileAdapter)
- d->profileAdapter->cancelDownload(d->downloadId);
- } else {
+ cancelled = d->profileAdapter->cancelDownload(d->downloadId);
+ }
+
+ // Not cancelled downloads are not even started yet at this point
+ if (!cancelled) {
d->downloadState = QWebEngineDownloadRequest::DownloadCancelled;
Q_EMIT stateChanged(d->downloadState);
d->setFinished();
@@ -427,7 +386,7 @@ QWebEngineDownloadRequest::DownloadState QWebEngineDownloadRequest::state() cons
}
/*!
- Returns the the total amount of data to download in bytes.
+ Returns the total amount of data to download in bytes.
\c -1 means the size is unknown.
*/
@@ -648,7 +607,7 @@ QString QWebEngineDownloadRequest::interruptReasonString() const
QWebEnginePage *QWebEngineDownloadRequest::page() const
{
Q_D(const QWebEngineDownloadRequest);
- if (d->adapterClient->clientType() == QtWebEngineCore::WebContentsAdapterClient::WidgetsClient)
+ if (d->adapterClient && d->adapterClient->clientType() == QtWebEngineCore::WebContentsAdapterClient::WidgetsClient)
return const_cast<QWebEnginePage *>(static_cast<const QWebEnginePage *>(d->adapterClient->holdingQObject()));
return nullptr;
}
@@ -674,3 +633,5 @@ QWebEngineDownloadRequest::~QWebEngineDownloadRequest()
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginedownloadrequest.cpp"
diff --git a/src/core/api/qwebenginedownloadrequest.h b/src/core/api/qwebenginedownloadrequest.h
index 35ed4263b..36604188e 100644
--- a/src/core/api/qwebenginedownloadrequest.h
+++ b/src/core/api/qwebenginedownloadrequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEDOWNLOADREQUEST_H
#define QWEBENGINEDOWNLOADREQUEST_H
diff --git a/src/core/api/qwebenginedownloadrequest_p.h b/src/core/api/qwebenginedownloadrequest_p.h
index e158d8edd..eef6c9bb5 100644
--- a/src/core/api/qwebenginedownloadrequest_p.h
+++ b/src/core/api/qwebenginedownloadrequest_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEDOWNLOADREQUEST_P_H
#define QWEBENGINEDOWNLOADREQUEST_P_H
@@ -64,35 +28,38 @@ class WebContentsAdapterClient;
QT_BEGIN_NAMESPACE
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineDownloadRequestPrivate
+class Q_WEBENGINECORE_EXPORT QWebEngineDownloadRequestPrivate
{
public:
- QWebEngineDownloadRequestPrivate(QtWebEngineCore::ProfileAdapter *adapter, const QUrl &url);
+ QWebEngineDownloadRequestPrivate(QtWebEngineCore::ProfileAdapter *adapter);
~QWebEngineDownloadRequestPrivate();
void update(const QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo &info);
void setFinished();
- bool downloadFinished;
- quint32 downloadId;
+ bool downloadFinished = false;
+ quint32 downloadId = -1;
qint64 startTime;
- QWebEngineDownloadRequest::DownloadState downloadState;
- QWebEngineDownloadRequest::SavePageFormat savePageFormat;
- QWebEngineDownloadRequest::DownloadInterruptReason interruptReason;
+ QWebEngineDownloadRequest::DownloadState downloadState =
+ QWebEngineDownloadRequest::DownloadCancelled;
+ QWebEngineDownloadRequest::SavePageFormat savePageFormat =
+ QWebEngineDownloadRequest::MimeHtmlSaveFormat;
+ QWebEngineDownloadRequest::DownloadInterruptReason interruptReason =
+ QWebEngineDownloadRequest::NoReason;
QString downloadPath;
- const QUrl downloadUrl;
+ QUrl downloadUrl;
QString mimeType;
- bool downloadPaused;
+ bool downloadPaused = false;
QString suggestedFileName;
QString downloadDirectory;
QString downloadFileName;
- bool isCustomFileName;
- qint64 totalBytes;
- qint64 receivedBytes;
- bool isSavePageDownload;
+ bool isCustomFileName = false;
+ qint64 totalBytes = -1;
+ qint64 receivedBytes = 0;
+ bool isSavePageDownload = false;
QWebEngineDownloadRequest *q_ptr;
QPointer<QtWebEngineCore::ProfileAdapter> profileAdapter;
- QtWebEngineCore::WebContentsAdapterClient *adapterClient;
+ QtWebEngineCore::WebContentsAdapterClient *adapterClient = nullptr;
Q_DECLARE_PUBLIC(QWebEngineDownloadRequest)
};
diff --git a/src/core/api/qwebenginefilesystemaccessrequest.cpp b/src/core/api/qwebenginefilesystemaccessrequest.cpp
new file mode 100644
index 000000000..3f901b671
--- /dev/null
+++ b/src/core/api/qwebenginefilesystemaccessrequest.cpp
@@ -0,0 +1,126 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebenginefilesystemaccessrequest.h"
+
+#include "file_system_access/file_system_access_permission_request_controller.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWebEngineFileSystemAccessRequest
+ \brief The QWebEngineFileSystemAccessRequest class enables accepting or rejecting
+ requests for local file system access from JavaScript applications.
+
+ \since 6.4
+
+ \inmodule QtWebEngineCore
+
+ To allow web applications to access local files of the computer,
+ applications must connect to QWebEnginePage::fileSystemAccessRequested, which takes a
+ QWebEngineFileSystemAccessRequest instance as an argument.
+
+ If a web applications requests access to local files or directories,
+ QWebEnginePage::fileSystemAccessRequested will be emitted with an
+ QWebEngineFileSystemAccessRequest instance as an argument where accessFlags() indicates
+ the type of the requested access: read, write or both. The signal handler needs to then
+ either call accept() or reject().
+*/
+
+/*!
+ \enum QWebEngineFileSystemAccessRequest::AccessFlag
+
+ This enum describes the type of the requested access: read, write or both. The options
+ can be OR-ed together from the following list:
+
+ \value Read
+ \value Write
+*/
+
+/*!
+ \enum QWebEngineFileSystemAccessRequest::HandleType
+
+ This enum describes the type of the requested file system entry.
+
+ \value File
+ \value Directory
+*/
+
+QWebEngineFileSystemAccessRequest::QWebEngineFileSystemAccessRequest(
+ const QWebEngineFileSystemAccessRequest &other) = default;
+QWebEngineFileSystemAccessRequest &QWebEngineFileSystemAccessRequest::operator=(
+ const QWebEngineFileSystemAccessRequest &other) = default;
+QWebEngineFileSystemAccessRequest::~QWebEngineFileSystemAccessRequest() = default;
+
+/*! \fn bool QWebEngineFileSystemAccessRequest::operator==(const QWebEngineFileSystemAccessRequest &lhs, const QWebEngineFileSystemAccessRequest &rhs)
+ Returns \c true if \a lhs and \a rhs both point to the same request.
+*/
+
+/*! \fn bool QWebEngineFileSystemAccessRequest::operator!=(const QWebEngineFileSystemAccessRequest &lhs, const QWebEngineFileSystemAccessRequest &rhs)
+ Returns \c true if \a lhs and \a rhs point to different requests.
+*/
+
+/*! \internal */
+QWebEngineFileSystemAccessRequest::QWebEngineFileSystemAccessRequest(
+ std::shared_ptr<QtWebEngineCore::FileSystemAccessPermissionRequestController> controller)
+ : d_ptr(std::move(controller))
+{
+}
+
+/*!
+ Rejects a request to access local files.
+*/
+void QWebEngineFileSystemAccessRequest::reject()
+{
+ d_ptr->reject();
+}
+
+/*!
+ Accepts the request to access local files.
+*/
+void QWebEngineFileSystemAccessRequest::accept()
+{
+ d_ptr->accept();
+}
+
+/*!
+ \property QWebEngineFileSystemAccessRequest::origin
+ \brief The URL of the web page that issued the file system access request.
+*/
+
+QUrl QWebEngineFileSystemAccessRequest::origin() const
+{
+ return d_ptr->origin();
+}
+
+/*!
+ \property QWebEngineFileSystemAccessRequest::filePath
+ \brief Returns the file path this file system access request is referring to.
+*/
+
+QUrl QWebEngineFileSystemAccessRequest::filePath() const
+{
+ return d_ptr->filePath();
+}
+
+/*!
+ \property QWebEngineFileSystemAccessRequest::handleType
+ \brief Returns the type of the requested file system entry. (File or directory)
+ */
+HandleType QWebEngineFileSystemAccessRequest::handleType() const
+{
+ return d_ptr->handleType();
+}
+
+/*!
+ \property QWebEngineFileSystemAccessRequest::accessFlags
+ \brief Contains the requested file access rights.
+ */
+AccessFlags QWebEngineFileSystemAccessRequest::accessFlags() const
+{
+ return d_ptr->accessFlags();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginefilesystemaccessrequest.cpp"
diff --git a/src/core/api/qwebenginefilesystemaccessrequest.h b/src/core/api/qwebenginefilesystemaccessrequest.h
new file mode 100644
index 000000000..37b1e1861
--- /dev/null
+++ b/src/core/api/qwebenginefilesystemaccessrequest.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEFILESYSTEMACCESSREQUEST_H
+#define QWEBENGINEFILESYSTEMACCESSREQUEST_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtCore/qurl.h>
+#include <memory>
+
+namespace QtWebEngineCore {
+class FileSystemAccessPermissionRequestController;
+class FileSystemAccessPermissionRequestManagerQt;
+}
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINECORE_EXPORT QWebEngineFileSystemAccessRequest
+{
+ Q_GADGET
+ Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
+ Q_PROPERTY(QUrl filePath READ filePath CONSTANT FINAL)
+ Q_PROPERTY(HandleType handleType READ handleType CONSTANT FINAL)
+ Q_PROPERTY(AccessFlags accessFlags READ accessFlags CONSTANT FINAL)
+
+public:
+ QWebEngineFileSystemAccessRequest(const QWebEngineFileSystemAccessRequest &other);
+ QWebEngineFileSystemAccessRequest &operator=(const QWebEngineFileSystemAccessRequest &other);
+ QWebEngineFileSystemAccessRequest(QWebEngineFileSystemAccessRequest &&other) noexcept = default;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QWebEngineFileSystemAccessRequest)
+ ~QWebEngineFileSystemAccessRequest();
+
+ void swap(QWebEngineFileSystemAccessRequest &other) noexcept { d_ptr.swap(other.d_ptr); }
+
+ enum HandleType { File, Directory };
+ Q_ENUM(HandleType)
+
+ enum AccessFlag { Read = 0x1, Write = 0x2 };
+ Q_DECLARE_FLAGS(AccessFlags, AccessFlag)
+ Q_FLAG(AccessFlags)
+
+ Q_INVOKABLE void accept();
+ Q_INVOKABLE void reject();
+ QUrl origin() const;
+ QUrl filePath() const;
+ HandleType handleType() const;
+ AccessFlags accessFlags() const;
+
+ inline friend bool operator==(const QWebEngineFileSystemAccessRequest &lhs,
+ const QWebEngineFileSystemAccessRequest &rhs) noexcept
+ { return lhs.d_ptr == rhs.d_ptr; }
+ inline friend bool operator!=(const QWebEngineFileSystemAccessRequest &lhs,
+ const QWebEngineFileSystemAccessRequest &rhs) noexcept
+ { return lhs.d_ptr != rhs.d_ptr; }
+
+private:
+ QWebEngineFileSystemAccessRequest(
+ std::shared_ptr<QtWebEngineCore::FileSystemAccessPermissionRequestController>);
+ friend QtWebEngineCore::FileSystemAccessPermissionRequestManagerQt;
+
+ std::shared_ptr<QtWebEngineCore::FileSystemAccessPermissionRequestController> d_ptr;
+};
+
+Q_DECLARE_SHARED(QWebEngineFileSystemAccessRequest)
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWebEngineFileSystemAccessRequest::AccessFlags)
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEFILESYSTEMACCESSREQUEST_H
diff --git a/src/core/api/qwebenginefindtextresult.cpp b/src/core/api/qwebenginefindtextresult.cpp
index cba8f6b4c..ce953ddff 100644
--- a/src/core/api/qwebenginefindtextresult.cpp
+++ b/src/core/api/qwebenginefindtextresult.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginefindtextresult.h"
diff --git a/src/core/api/qwebenginefindtextresult.h b/src/core/api/qwebenginefindtextresult.h
index 8576dbabb..d506a50f5 100644
--- a/src/core/api/qwebenginefindtextresult.h
+++ b/src/core/api/qwebenginefindtextresult.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEFINDTEXTRESULT_H
#define QWEBENGINEFINDTEXTRESULT_H
diff --git a/src/core/api/qwebenginefullscreenrequest.cpp b/src/core/api/qwebenginefullscreenrequest.cpp
index cac1d56ba..938aad19c 100644
--- a/src/core/api/qwebenginefullscreenrequest.cpp
+++ b/src/core/api/qwebenginefullscreenrequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginefullscreenrequest.h"
@@ -145,3 +109,5 @@ QUrl QWebEngineFullScreenRequest::origin() const
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginefullscreenrequest.cpp"
diff --git a/src/core/api/qwebenginefullscreenrequest.h b/src/core/api/qwebenginefullscreenrequest.h
index aa7a6a9d2..8e25286b6 100644
--- a/src/core/api/qwebenginefullscreenrequest.h
+++ b/src/core/api/qwebenginefullscreenrequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEFULLSCREENREQUEST_H
#define QWEBENGINEFULLSCREENREQUEST_H
diff --git a/src/core/api/qwebengineglobalsettings.cpp b/src/core/api/qwebengineglobalsettings.cpp
new file mode 100644
index 000000000..6aadd5517
--- /dev/null
+++ b/src/core/api/qwebengineglobalsettings.cpp
@@ -0,0 +1,125 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebengineglobalsettings.h"
+#include "qwebengineglobalsettings_p.h"
+#include <QDebug>
+
+#ifdef signals
+#undef signals
+#endif
+
+namespace QtWebEngineCore {
+extern void configureStubHostResolver(QWebEngineGlobalSettings::SecureDnsMode dnsMode,
+ std::string dnsOverHttpsTemplates, bool insecureDnsClientEnabled,
+ bool additionalInsecureDnsTypesEnabled);
+extern bool isValidTemplates(std::string templates);
+
+} // namespace QtWebEngineCore
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \namespace QWebEngineGlobalSettings
+ \brief The QWebEngineGlobalSettings namespace holds global settings of the web engine.
+ \since 6.6
+ \inmodule QtWebEngineCore
+
+ The QWebEngineGlobalSettings namespace holds global properties of the web engine.
+
+ Invoke setDnsMode() to configure DNS-over-HTTPS.
+
+ \sa QWebEngineGlobalSettings::setDnsMode()
+*/
+
+/*!
+ \enum QWebEngineGlobalSettings::SecureDnsMode
+
+ This enum sets the DNS-over-HTTPS mode used by the DnsMode structure:
+
+ \value SystemOnly This is the default. Use the system DNS host resolution.
+ \value SecureWithFallback Enable DNS-over-HTTPS (DoH). DoH servers have to be
+ provided through \l {QWebEngineGlobalSettings::DnsMode::serverTemplates}{serverTemplates} in
+ the DnsMode structure. If a host cannot be resolved via the provided servers,
+ the system DNS host resolution is used.
+ \value SecureOnly Enable DNS-over-HTTPS and only allow hosts to be resolved
+ this way. DoH servers have to be provided through
+ \l {QWebEngineGlobalSettings::DnsMode::serverTemplates}{serverTemplates} in the DnsMode
+ structure. If the DNS-over-HTTPS resolution fails, there is no fallback and the DNS host
+ resolution fails completely.
+*/
+
+/*!
+ \class QWebEngineGlobalSettings::DnsMode
+ \brief The DnsMode struct provides means to specify the DNS host resolution mode.
+ \since 6.6
+ \inmodule QtWebEngineCore
+
+ The QWebEngineGlobalSettings::DnsMode structure describes the DNS mode and
+ the associated DNS server template used for the DNS host resolution.
+*/
+
+/*!
+ \variable QWebEngineGlobalSettings::DnsMode::secureMode
+ \brief The DNS mode used for the host resolution.
+
+ Set \a secureMode to SecureDnsMode::SecureOnly to only allow DNS-over-HTTPS host resolution
+ using servers from \a serverTemplates.
+
+ Set \a secureMode to SecureDnsMode::SecureWithFallback to enable DNS-over-HTTPS host resolution
+ using servers from \a serverTemplates, with a fallback to the system DNS.
+
+ \sa QWebEngineGlobalSettings::SecureDnsMode
+*/
+
+/*!
+ \variable QWebEngineGlobalSettings::DnsMode::serverTemplates
+ \brief A list of server URI templates used for secure DNS-over-HTTPS host resolution.
+
+ The \c serverTemplates structure member lists
+ \l{https://datatracker.ietf.org/d7oc/html/rfc6570}{URI templates}.
+ An example of a URI template is https://dns.google/dns-query{?dns}.
+*/
+
+/*!
+ \fn void QWebEngineGlobalSettings::setDnsMode(DnsMode dnsMode)
+
+ Sets \a dnsMode for DNS-over-HTTPS host resolution.
+
+ This function returns \c false if the \l {QWebEngineGlobalSettings::DnsMode::serverTemplates}
+ {serverTemplates} list in the \l {QWebEngineGlobalSettings::DnsMode}{DnsMode} structure is empty
+ or contains URI templates that cannot be parsed for SecureDnsMode::SecureOnly or
+ SecureDnsMode::SecureWithFallback. Otherwise, it returns \c true meaning that the DNS mode
+ change is triggered.
+*/
+
+bool QWebEngineGlobalSettings::setDnsMode(DnsMode dnsMode)
+{
+ QWebEngineGlobalSettingsPrivate *d = QWebEngineGlobalSettingsPrivate::instance();
+ if (dnsMode.secureMode != SecureDnsMode::SystemOnly) {
+ const QString servers = dnsMode.serverTemplates.join(QChar::Space);
+ const std::string templates = servers.toStdString();
+ if (!QtWebEngineCore::isValidTemplates(templates))
+ return false;
+ d->dnsOverHttpsTemplates = templates;
+ }
+ d->dnsMode = dnsMode.secureMode;
+ d->configureStubHostResolver();
+ return true;
+}
+
+/*!
+ \internal
+*/
+QWebEngineGlobalSettingsPrivate *QWebEngineGlobalSettingsPrivate::instance()
+{
+ static QWebEngineGlobalSettingsPrivate settings;
+ return &settings;
+}
+
+void QWebEngineGlobalSettingsPrivate::configureStubHostResolver()
+{
+ QtWebEngineCore::configureStubHostResolver(dnsMode, dnsOverHttpsTemplates, insecureDnsClientEnabled, additionalInsecureDnsTypesEnabled);
+}
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineglobalsettings.h b/src/core/api/qwebengineglobalsettings.h
new file mode 100644
index 000000000..a9eff6d12
--- /dev/null
+++ b/src/core/api/qwebengineglobalsettings.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEGLOBALSETTINGS_H
+#define QWEBENGINEGLOBALSETTINGS_H
+
+#if 0
+#pragma qt_class(QWebEngineGlobalSettings)
+#endif
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+namespace QWebEngineGlobalSettings {
+// Mapping net::SecureDnsMode
+enum class SecureDnsMode : quint8 { SystemOnly = 0, SecureWithFallback = 1, SecureOnly = 2 };
+struct DnsMode
+{
+ SecureDnsMode secureMode = SecureDnsMode::SystemOnly;
+ QStringList serverTemplates;
+};
+Q_WEBENGINECORE_EXPORT bool setDnsMode(DnsMode dnsMode);
+}
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEGLOBALSETTINGS_H
diff --git a/src/core/api/qwebengineglobalsettings_p.h b/src/core/api/qwebengineglobalsettings_p.h
new file mode 100644
index 000000000..8e35ad68c
--- /dev/null
+++ b/src/core/api/qwebengineglobalsettings_p.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEGLOBALSETTINGS_P_H
+#define QWEBENGINEGLOBALSETTINGS_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 "qwebengineglobalsettings.h"
+#include <string>
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINECORE_EXPORT QWebEngineGlobalSettingsPrivate
+{
+public:
+ QWebEngineGlobalSettingsPrivate()
+ : dnsMode(QWebEngineGlobalSettings::SecureDnsMode::SystemOnly)
+ , dnsOverHttpsTemplates("")
+ , insecureDnsClientEnabled(false)
+ , additionalInsecureDnsTypesEnabled(false){};
+
+ static QWebEngineGlobalSettingsPrivate *instance();
+ QWebEngineGlobalSettings::SecureDnsMode dnsMode;
+ std::string dnsOverHttpsTemplates;
+ const bool insecureDnsClientEnabled;
+ const bool additionalInsecureDnsTypesEnabled;
+
+ void configureStubHostResolver();
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEGLOBALSETTINGS_P_H
diff --git a/src/core/api/qwebenginehistory.cpp b/src/core/api/qwebenginehistory.cpp
index 2364aed6b..5d2fc8e9e 100644
--- a/src/core/api/qwebenginehistory.cpp
+++ b/src/core/api/qwebenginehistory.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
@@ -278,13 +242,6 @@ QWebEngineHistory::QWebEngineHistory(QWebEngineHistoryPrivate *d) : d_ptr(d) { }
QWebEngineHistory::~QWebEngineHistory() { }
-/*!
- \qmlmethod void WebEngineHistory::clear()
- \since QtWebEngine 1.11
-
- Clears the history.
-*/
-
void QWebEngineHistory::clear()
{
Q_D(const QWebEngineHistory);
@@ -428,3 +385,5 @@ void QWebEngineHistory::reset()
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginehistory.cpp"
diff --git a/src/core/api/qwebenginehistory.h b/src/core/api/qwebenginehistory.h
index 6afb8d8c1..fd54e62a5 100644
--- a/src/core/api/qwebenginehistory.h
+++ b/src/core/api/qwebenginehistory.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEHISTORY_H
#define QWEBENGINEHISTORY_H
@@ -74,7 +38,7 @@ public:
bool isValid() const;
- void swap(QWebEngineHistoryItem &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ void swap(QWebEngineHistoryItem &other) noexcept { d.swap(other.d); }
private:
QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *priv);
diff --git a/src/core/api/qwebenginehistory_p.h b/src/core/api/qwebenginehistory_p.h
index fb52f799c..fe28f4a0e 100644
--- a/src/core/api/qwebenginehistory_p.h
+++ b/src/core/api/qwebenginehistory_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEHISTORY_P_H
#define QWEBENGINEHISTORY_P_H
@@ -108,7 +72,7 @@ public:
int offsetForIndex(int) const override;
};
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineHistoryPrivate
+class Q_WEBENGINECORE_EXPORT QWebEngineHistoryPrivate
{
public:
typedef std::function<QUrl (const QUrl &)> ImageProviderUrl;
diff --git a/src/core/api/qwebenginehttprequest.cpp b/src/core/api/qwebenginehttprequest.cpp
index f5733cde4..050213d1e 100644
--- a/src/core/api/qwebenginehttprequest.cpp
+++ b/src/core/api/qwebenginehttprequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformdefs.h"
#include <QtCore/qshareddata.h>
@@ -182,16 +146,16 @@ QWebEngineHttpRequest QWebEngineHttpRequest::postRequest(const QUrl &url,
QWebEngineHttpRequest result(url);
result.setMethod(QWebEngineHttpRequest::Post);
- QString buffer;
+ QByteArray buffer;
for (QMap<QString, QString>::const_iterator it = postData.begin(); it != postData.end(); it++) {
QByteArray key = QUrl::toPercentEncoding(it.key());
QByteArray value = QUrl::toPercentEncoding(it.value());
- if (buffer.length() > 0)
- buffer += QLatin1Char('&');
- buffer += key + QLatin1Char('=') + value;
+ if (buffer.size() > 0)
+ buffer += '&';
+ buffer.append(key).append('=').append(value);
}
- result.setPostData(buffer.toLatin1());
+ result.setPostData(buffer);
result.setHeader(QByteArrayLiteral("Content-Type"),
QByteArrayLiteral("application/x-www-form-urlencoded"));
diff --git a/src/core/api/qwebenginehttprequest.h b/src/core/api/qwebenginehttprequest.h
index b302217f2..6c0298f86 100644
--- a/src/core/api/qwebenginehttprequest.h
+++ b/src/core/api/qwebenginehttprequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEHTTPREQUEST_H
#define QWEBENGINEHTTPREQUEST_H
@@ -73,7 +37,7 @@ public:
QWebEngineHttpRequest &operator=(const QWebEngineHttpRequest &other);
static QWebEngineHttpRequest postRequest(const QUrl &url, const QMap<QString, QString> &postData);
- void swap(QWebEngineHttpRequest &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ void swap(QWebEngineHttpRequest &other) noexcept { d.swap(other.d); }
bool operator==(const QWebEngineHttpRequest &other) const;
inline bool operator!=(const QWebEngineHttpRequest &other) const { return !operator==(other); }
diff --git a/src/core/api/qwebengineloadinginfo.cpp b/src/core/api/qwebengineloadinginfo.cpp
index ce6e57d5c..a72117e9d 100644
--- a/src/core/api/qwebengineloadinginfo.cpp
+++ b/src/core/api/qwebengineloadinginfo.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qwebengineloadinginfo.h>
@@ -53,17 +17,20 @@ Q_STATIC_ASSERT(static_cast<int>(WebEngineError::CertificateErrorDomain) == stat
Q_STATIC_ASSERT(static_cast<int>(WebEngineError::HttpErrorDomain) == static_cast<int>(ErrorDomain::HttpErrorDomain));
Q_STATIC_ASSERT(static_cast<int>(WebEngineError::FtpErrorDomain) == static_cast<int>(ErrorDomain::FtpErrorDomain));
Q_STATIC_ASSERT(static_cast<int>(WebEngineError::DnsErrorDomain) == static_cast<int>(ErrorDomain::DnsErrorDomain));
+Q_STATIC_ASSERT(static_cast<int>(WebEngineError::HttpStatusCodeDomain) == static_cast<int>(ErrorDomain::HttpStatusCodeDomain));
class QWebEngineLoadingInfo::QWebEngineLoadingInfoPrivate : public QSharedData {
public:
QWebEngineLoadingInfoPrivate(const QUrl& url, LoadStatus status, bool isErrorPage,
- const QString& errorString, int errorCode, ErrorDomain errorDomain)
+ const QString& errorString, int errorCode, ErrorDomain errorDomain,
+ const QMultiMap<QByteArray,QByteArray>& responseHeaders)
: url(url)
, status(status)
, isErrorPage(isErrorPage)
, errorString(errorString)
, errorCode(errorCode)
, errorDomain(errorDomain)
+ , responseHeaders(responseHeaders)
{
}
@@ -73,6 +40,7 @@ public:
QString errorString;
int errorCode;
ErrorDomain errorDomain;
+ QMultiMap<QByteArray,QByteArray> responseHeaders;
};
/*!
@@ -87,8 +55,10 @@ public:
\sa QWebEnginePage::loadStarted, QWebEnginePage::loadFinished, WebEngineView::loadingChanged
*/
QWebEngineLoadingInfo::QWebEngineLoadingInfo(const QUrl& url, LoadStatus status, bool isErrorPage,
- const QString& errorString, int errorCode, ErrorDomain errorDomain)
- : d_ptr(new QWebEngineLoadingInfoPrivate(url, status, isErrorPage, errorString, errorCode, errorDomain))
+ const QString& errorString, int errorCode, ErrorDomain errorDomain,
+ const QMultiMap<QByteArray,QByteArray>& responseHeaders)
+ : d_ptr(new QWebEngineLoadingInfoPrivate(url, status, isErrorPage, errorString, errorCode, errorDomain,
+ responseHeaders))
{
}
@@ -169,6 +139,8 @@ QString QWebEngineLoadingInfo::errorString() const
Error is related to the FTP connection.
\value DnsErrorDomain
Error is related to the DNS connection.
+ \value HttpStatusCodeDomain
+ Error is the HTTP response status code, even in case of success e.g. the server replied with status 200.
*/
/*
\property QWebEngineLoadingInfo::errorDomain
@@ -190,4 +162,19 @@ int QWebEngineLoadingInfo::errorCode() const
return d->errorCode;
}
+/*!
+ \property QWebEngineLoadingInfo::responseHeaders
+ \since 6.6
+ \brief Holds the response headers when \c QWebEngineLoadingInfo::status()
+ is equal to \c QWebEngineLoadingInfo::LoadSucceededStatus or
+ \c QWebEngineLoadingInfo::LoadFailedStatus.
+*/
+QMultiMap<QByteArray,QByteArray> QWebEngineLoadingInfo::responseHeaders() const
+{
+ Q_D(const QWebEngineLoadingInfo);
+ return d->responseHeaders;
+}
+
QT_END_NAMESPACE
+
+#include "moc_qwebengineloadinginfo.cpp"
diff --git a/src/core/api/qwebengineloadinginfo.h b/src/core/api/qwebengineloadinginfo.h
index b37dea609..48d14601a 100644
--- a/src/core/api/qwebengineloadinginfo.h
+++ b/src/core/api/qwebengineloadinginfo.h
@@ -1,48 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINELOADINGINFO_H
#define QWEBENGINELOADINGINFO_H
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtCore/qmap.h>
#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
#include <QtCore/qurl.h>
namespace QtWebEngineCore {
@@ -61,6 +27,7 @@ class Q_WEBENGINECORE_EXPORT QWebEngineLoadingInfo
Q_PROPERTY(QString errorString READ errorString CONSTANT FINAL)
Q_PROPERTY(ErrorDomain errorDomain READ errorDomain CONSTANT FINAL)
Q_PROPERTY(int errorCode READ errorCode CONSTANT FINAL)
+ Q_PROPERTY(QMultiMap<QByteArray,QByteArray> responseHeaders READ responseHeaders CONSTANT REVISION(6,6) FINAL)
public:
enum LoadStatus {
@@ -78,7 +45,8 @@ public:
CertificateErrorDomain,
HttpErrorDomain,
FtpErrorDomain,
- DnsErrorDomain
+ DnsErrorDomain,
+ HttpStatusCodeDomain
};
Q_ENUM(ErrorDomain)
@@ -94,11 +62,13 @@ public:
QString errorString() const;
ErrorDomain errorDomain() const;
int errorCode() const;
+ QMultiMap<QByteArray,QByteArray> responseHeaders() const;
private:
QWebEngineLoadingInfo(const QUrl &url, LoadStatus status, bool isErrorPage = false,
const QString &errorString = QString(), int errorCode = 0,
- ErrorDomain errorDomain = NoErrorDomain);
+ ErrorDomain errorDomain = NoErrorDomain,
+ const QMultiMap<QByteArray,QByteArray> &responseHeaders = {});
class QWebEngineLoadingInfoPrivate;
Q_DECLARE_PRIVATE(QWebEngineLoadingInfo)
QExplicitlySharedDataPointer<QWebEngineLoadingInfoPrivate> d_ptr;
diff --git a/src/core/api/qwebenginemessagepumpscheduler.cpp b/src/core/api/qwebenginemessagepumpscheduler.cpp
index 34cbc49bf..a435e2c0c 100644
--- a/src/core/api/qwebenginemessagepumpscheduler.cpp
+++ b/src/core/api/qwebenginemessagepumpscheduler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginemessagepumpscheduler_p.h"
@@ -47,9 +11,14 @@ QWebEngineMessagePumpScheduler::QWebEngineMessagePumpScheduler(std::function<voi
: m_callback(std::move(callback))
{}
-void QWebEngineMessagePumpScheduler::scheduleWork()
+void QWebEngineMessagePumpScheduler::scheduleImmediateWork()
{
- QCoreApplication::postEvent(this, new QTimerEvent(0));
+ QCoreApplication::postEvent(this, new QTimerEvent(0), Qt::NormalEventPriority);
+}
+
+void QWebEngineMessagePumpScheduler::scheduleIdleWork()
+{
+ QCoreApplication::postEvent(this, new QTimerEvent(0), Qt::LowEventPriority);
}
void QWebEngineMessagePumpScheduler::scheduleDelayedWork(int delay)
@@ -70,3 +39,5 @@ void QWebEngineMessagePumpScheduler::timerEvent(QTimerEvent *ev)
m_timerId = 0;
m_callback();
}
+
+#include "moc_qwebenginemessagepumpscheduler_p.cpp"
diff --git a/src/core/api/qwebenginemessagepumpscheduler_p.h b/src/core/api/qwebenginemessagepumpscheduler_p.h
index 46ed62f54..37f7dd9a6 100644
--- a/src/core/api/qwebenginemessagepumpscheduler_p.h
+++ b/src/core/api/qwebenginemessagepumpscheduler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEMESSAGEPUMPSCHEDULER_P_H
#define QWEBENGINEMESSAGEPUMPSCHEDULER_P_H
@@ -59,12 +23,13 @@
QT_BEGIN_NAMESPACE
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineMessagePumpScheduler : public QObject
+class Q_WEBENGINECORE_EXPORT QWebEngineMessagePumpScheduler : public QObject
{
Q_OBJECT
public:
QWebEngineMessagePumpScheduler(std::function<void()> callback);
- void scheduleWork();
+ void scheduleImmediateWork();
+ void scheduleIdleWork();
void scheduleDelayedWork(int delay);
protected:
diff --git a/src/core/api/qwebenginenavigationrequest.cpp b/src/core/api/qwebenginenavigationrequest.cpp
index 070770012..0a30f6472 100644
--- a/src/core/api/qwebenginenavigationrequest.cpp
+++ b/src/core/api/qwebenginenavigationrequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginenavigationrequest.h"
@@ -125,7 +89,10 @@ void QWebEngineNavigationRequest::setAction(QWebEngineNavigationRequest::Navigat
return;
acceptRequest ? accept() : reject();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit actionChanged();
+QT_WARNING_POP
}
#endif
/*!
@@ -214,3 +181,5 @@ bool QWebEngineNavigationRequest::isAccepted() const
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginenavigationrequest.cpp"
diff --git a/src/core/api/qwebenginenavigationrequest.h b/src/core/api/qwebenginenavigationrequest.h
index ab098b6aa..12fc2b4a1 100644
--- a/src/core/api/qwebenginenavigationrequest.h
+++ b/src/core/api/qwebenginenavigationrequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINENAVIGATIONREQUEST_H
#define QWEBENGINENAVIGATIONREQUEST_H
diff --git a/src/core/api/qwebenginenewwindowrequest.cpp b/src/core/api/qwebenginenewwindowrequest.cpp
index 70fbd2bb4..895033fd1 100644
--- a/src/core/api/qwebenginenewwindowrequest.cpp
+++ b/src/core/api/qwebenginenewwindowrequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginenewwindowrequest.h"
#include "qwebenginenewwindowrequest_p.h"
@@ -61,7 +25,7 @@ QT_BEGIN_NAMESPACE
/*!
\qmltype WebEngineNewWindowRequest
\instantiates QWebEngineNewWindowRequest
- \inqmlmodule QtWebEngineQuick
+ \inqmlmodule QtWebEngine
\since QtWebEngine 1.12
\brief A utility type for the WebEngineView::newWindowRequested signal.
@@ -189,3 +153,5 @@ void QWebEngineNewWindowRequest::openIn(QWebEnginePage *page)
}
QT_END_NAMESPACE
+
+#include "moc_qwebenginenewwindowrequest.cpp"
diff --git a/src/core/api/qwebenginenewwindowrequest.h b/src/core/api/qwebenginenewwindowrequest.h
index 8fd35ad6f..86d182581 100644
--- a/src/core/api/qwebenginenewwindowrequest.h
+++ b/src/core/api/qwebenginenewwindowrequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINENEWWINDOWREQUEST_H
#define QWEBENGINENEWWINDOWREQUEST_H
diff --git a/src/core/api/qwebenginenewwindowrequest_p.h b/src/core/api/qwebenginenewwindowrequest_p.h
index ec69dc84c..979d3fe2d 100644
--- a/src/core/api/qwebenginenewwindowrequest_p.h
+++ b/src/core/api/qwebenginenewwindowrequest_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINENEWWINDOWREQUEST_P_H
#define QWEBENGINENEWWINDOWREQUEST_P_H
diff --git a/src/core/api/qwebenginenotification.cpp b/src/core/api/qwebenginenotification.cpp
index 60646d2c9..136047042 100644
--- a/src/core/api/qwebenginenotification.cpp
+++ b/src/core/api/qwebenginenotification.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginenotification.h"
diff --git a/src/core/api/qwebenginenotification.h b/src/core/api/qwebenginenotification.h
index 791f6bb1b..646413d39 100644
--- a/src/core/api/qwebenginenotification.h
+++ b/src/core/api/qwebenginenotification.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINENOTIFICATION_H
#define QWEBENGINENOTIFICATION_H
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index c58ef5e7c..ac645c430 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -1,63 +1,32 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginepage.h"
+#include "authenticator_request_dialog_controller.h"
#include "qwebenginepage_p.h"
#include "qwebenginecertificateerror.h"
+#include "qwebenginedesktopmediarequest.h"
+#include "qwebenginefilesystemaccessrequest.h"
#include "qwebenginefindtextresult.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
+#include "qwebenginehttprequest.h"
#include "qwebengineloadinginfo.h"
#include "qwebenginenavigationrequest.h"
#include "qwebenginenewwindowrequest.h"
#include "qwebenginenewwindowrequest_p.h"
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
-#include "qwebenginequotarequest.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
#include "qwebenginescript.h"
#include "qwebenginescriptcollection_p.h"
#include "qwebenginesettings.h"
+#include "qwebenginewebauthuxrequest.h"
#include "authentication_dialog_controller.h"
+#include "autofill_popup_controller.h"
#include "color_chooser_controller.h"
#include "find_text_helper.h"
#include "file_picker_controller.h"
@@ -66,6 +35,8 @@
#include "render_view_context_menu_qt.h"
#include "render_widget_host_view_qt_delegate.h"
#include "render_widget_host_view_qt_delegate_client.h"
+#include "render_widget_host_view_qt_delegate_item.h"
+#include "touch_selection_menu_controller.h"
#include "web_contents_adapter.h"
#include <QAction>
@@ -74,60 +45,19 @@
#include <QClipboard>
#include <QKeyEvent>
#include <QIcon>
+
#include <QLoggingCategory>
#include <QMimeData>
+#include <QtCore/QPointer>
+#include <QRect>
#include <QTimer>
#include <QUrl>
+#include <QVariant>
QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
-// add temporary dummy code to cover the case when page is loading and there is no view
-class DummyDelegate : public QObject, public QtWebEngineCore::RenderWidgetHostViewQtDelegate
-{
-public:
- DummyDelegate(RenderWidgetHostViewQtDelegateClient *client) : m_delegateClient(client) {};
- ~DummyDelegate() = default;
- void initAsPopup(const QRect &) override { Q_UNREACHABLE(); }
- QRectF viewGeometry() const override { return QRectF(m_pos, m_size); }
- void setKeyboardFocus() override { }
- bool hasKeyboardFocus() override { return false; }
- void lockMouse() override { Q_UNREACHABLE(); }
- void unlockMouse() override { Q_UNREACHABLE(); }
- void show() override { m_delegateClient->notifyShown(); }
- void hide() override { m_delegateClient->notifyHidden(); }
- bool isVisible() const override { Q_UNREACHABLE(); }
- QWindow *window() const override { return nullptr; }
- void updateCursor(const QCursor &cursor) override
- {
- Q_UNUSED(cursor);
- /*setCursor(cursor);*/
- }
- void resize(int width, int height) override
- {
- m_size = QSize(width, height);
- m_delegateClient->visualPropertiesChanged();
- }
- void move(const QPoint &) override { Q_UNREACHABLE(); }
- void inputMethodStateChanged(bool, bool) override { }
- void setInputMethodHints(Qt::InputMethodHints) override { }
- void setClearColor(const QColor &) override { }
- void adapterClientChanged(WebContentsAdapterClient *) override { }
- bool copySurface(const QRect &, const QSize &, QImage &)
- {
- Q_UNREACHABLE();
- return false;
- }
- QRect windowGeometry() const override { return QRect(m_pos, m_size); }
- bool forwardEvent(QEvent *ev) { return m_delegateClient->forwardEvent(ev); }
-
-private:
- RenderWidgetHostViewQtDelegateClient *m_delegateClient;
- QPoint m_pos;
- QSize m_size;
-};
-
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -178,8 +108,11 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
{
memset(actions, 0, sizeof(actions));
+#if QT_DEPRECATED_SINCE(6, 5)
qRegisterMetaType<QWebEngineQuotaRequest>();
+#endif
qRegisterMetaType<QWebEngineRegisterProtocolHandlerRequest>();
+ qRegisterMetaType<QWebEngineFileSystemAccessRequest>();
qRegisterMetaType<QWebEngineFindTextResult>();
// See setVisible().
@@ -200,6 +133,14 @@ QWebEnginePagePrivate::~QWebEnginePagePrivate()
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
+ if (view)
+ return view->CreateRenderWidgetHostViewQtDelegate(client);
+ delegateItem = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, false);
+ return delegateItem;
+}
+
+RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client)
+{
// Set the QWebEngineView as the parent for a popup delegate, so that the new popup window
// responds properly to clicks in case the QWebEngineView is inside a modal QDialog. Setting the
// parent essentially notifies the OS that the popup window is part of the modal session, and
@@ -207,7 +148,9 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie
// The new delegate will not be deleted by the parent view though, because we unset the parent
// when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
// dismissed.
- return view ? view->CreateRenderWidgetHostViewQtDelegate(client) : new DummyDelegate(client);
+ return view
+ ? view->CreateRenderWidgetHostViewQtDelegateForPopup(client)
+ : new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, true);
}
void QWebEnginePagePrivate::initializationFinished()
@@ -277,6 +220,12 @@ void QWebEnginePagePrivate::selectionChanged()
});
}
+void QWebEnginePagePrivate::zoomUpdateIsNeeded()
+{
+ Q_Q(QWebEnginePage);
+ q->setZoomFactor(defaultZoomFactor);
+}
+
void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible)
{
Q_Q(QWebEnginePage);
@@ -387,6 +336,109 @@ void QWebEnginePagePrivate::createNewWindow(WindowOpenDisposition disposition, b
Q_EMIT q->newWindowRequested(request);
}
+QString QWebEnginePagePrivate::actionText(int action)
+{
+ switch (action) {
+ case QWebEnginePage::Back:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back);
+ case QWebEnginePage::Forward:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward);
+ case QWebEnginePage::Stop:
+ return QWebEnginePage::tr("Stop");
+ case QWebEnginePage::Reload:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload);
+ case QWebEnginePage::ReloadAndBypassCache:
+ return QWebEnginePage::tr("Reload and Bypass Cache");
+ case QWebEnginePage::Cut:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut);
+ case QWebEnginePage::Copy:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy);
+ case QWebEnginePage::Paste:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste);
+ case QWebEnginePage::Undo:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo);
+ case QWebEnginePage::Redo:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo);
+ case QWebEnginePage::SelectAll:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll);
+ case QWebEnginePage::PasteAndMatchStyle:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle);
+ case QWebEnginePage::OpenLinkInThisWindow:
+ return QWebEnginePage::tr("Open link in this window");
+ case QWebEnginePage::OpenLinkInNewWindow:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow);
+ case QWebEnginePage::OpenLinkInNewTab:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab);
+ case QWebEnginePage::OpenLinkInNewBackgroundTab:
+ return QWebEnginePage::tr("Open link in new background tab");
+ case QWebEnginePage::CopyLinkToClipboard:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard);
+ case QWebEnginePage::DownloadLinkToDisk:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk);
+ case QWebEnginePage::CopyImageToClipboard:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard);
+ case QWebEnginePage::CopyImageUrlToClipboard:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard);
+ case QWebEnginePage::DownloadImageToDisk:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk);
+ case QWebEnginePage::CopyMediaUrlToClipboard:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard);
+ case QWebEnginePage::ToggleMediaControls:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls);
+ case QWebEnginePage::ToggleMediaLoop:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop);
+ case QWebEnginePage::ToggleMediaPlayPause:
+ return QWebEnginePage::tr("Toggle Play/Pause");
+ case QWebEnginePage::ToggleMediaMute:
+ return QWebEnginePage::tr("Toggle Mute");
+ case QWebEnginePage::DownloadMediaToDisk:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk);
+ case QWebEnginePage::InspectElement:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement);
+ case QWebEnginePage::ExitFullScreen:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen);
+ case QWebEnginePage::RequestClose:
+ return QWebEnginePage::tr("Close Page");
+ case QWebEnginePage::Unselect:
+ return QWebEnginePage::tr("Unselect");
+ case QWebEnginePage::SavePage:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage);
+ case QWebEnginePage::ViewSource:
+ return RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource);
+ case QWebEnginePage::ToggleBold:
+ return QWebEnginePage::tr("&Bold");
+ case QWebEnginePage::ToggleItalic:
+ return QWebEnginePage::tr("&Italic");
+ case QWebEnginePage::ToggleUnderline:
+ return QWebEnginePage::tr("&Underline");
+ case QWebEnginePage::ToggleStrikethrough:
+ return QWebEnginePage::tr("&Strikethrough");
+ case QWebEnginePage::AlignLeft:
+ return QWebEnginePage::tr("Align &Left");
+ case QWebEnginePage::AlignCenter:
+ return QWebEnginePage::tr("Align &Center");
+ case QWebEnginePage::AlignRight:
+ return QWebEnginePage::tr("Align &Right");
+ case QWebEnginePage::AlignJustified:
+ return QWebEnginePage::tr("Align &Justified");
+ case QWebEnginePage::Indent:
+ return QWebEnginePage::tr("&Indent");
+ case QWebEnginePage::Outdent:
+ return QWebEnginePage::tr("&Outdent");
+ case QWebEnginePage::InsertOrderedList:
+ return QWebEnginePage::tr("Insert &Ordered List");
+ case QWebEnginePage::InsertUnorderedList:
+ return QWebEnginePage::tr("Insert &Unordered List");
+ case QWebEnginePage::ChangeTextDirectionLTR:
+ return QWebEnginePage::tr("Change text direction left to right");
+ case QWebEnginePage::ChangeTextDirectionRTL:
+ return QWebEnginePage::tr("Change text direction right to left");
+ default:
+ break;
+ }
+ return {};
+}
+
class WebContentsAdapterOwner : public QObject
{
public:
@@ -409,6 +461,8 @@ bool QWebEnginePagePrivate::adoptWebContents(WebContentsAdapter *webContents)
m_isBeingAdopted = true;
+ webContents->setRequestInterceptor(adapter->requestInterceptor());
+
// 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->sharedFromThis());
@@ -456,8 +510,6 @@ void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const Q
void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
{
#if QT_CONFIG(webengine_printing_and_pdf)
- Q_Q(QWebEnginePage);
-
// If no currentPrinter is set that means that were printing to PDF only.
if (!currentPrinter) {
if (!result.data())
@@ -508,7 +560,7 @@ void QWebEnginePagePrivate::releaseProfile()
{
qWarning("Release of profile requested but WebEnginePage still not deleted. Expect troubles !");
// this is not the way to go, but might avoid the crash if user code does not make any calls to page.
- delete q_ptr->d_ptr.take();
+ q_ptr->d_ptr.reset();
}
void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
@@ -543,6 +595,10 @@ static QWebEnginePage::Feature toFeature(QtWebEngineCore::ProfileAdapter::Permis
return QWebEnginePage::Notifications;
case QtWebEngineCore::ProfileAdapter::GeolocationPermission:
return QWebEnginePage::Geolocation;
+ case QtWebEngineCore::ProfileAdapter::ClipboardReadWrite:
+ return QWebEnginePage::ClipboardReadWrite;
+ case QtWebEngineCore::ProfileAdapter::LocalFontsPermission:
+ return QWebEnginePage::LocalFontsAccess;
default:
break;
}
@@ -562,16 +618,25 @@ void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOr
Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
}
-void QWebEnginePagePrivate::runQuotaRequest(QWebEngineQuotaRequest request)
+void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
{
Q_Q(QWebEnginePage);
- Q_EMIT q->quotaRequested(request);
+ Q_EMIT q->registerProtocolHandlerRequested(request);
}
-void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
+/*!
+ \fn void QWebEnginePage::fileSystemAccessRequested(QWebEngineFileSystemAccessRequest request)
+ \since 6.4
+
+ This signal is emitted when the web page requests access to local files or directories.
+
+ The request object \a request can be used to accept or reject the request.
+*/
+
+void QWebEnginePagePrivate::runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest request)
{
Q_Q(QWebEnginePage);
- Q_EMIT q->registerProtocolHandlerRequested(request);
+ Q_EMIT q->fileSystemAccessRequested(request);
}
QObject *QWebEnginePagePrivate::accessibilityParentObject()
@@ -581,7 +646,7 @@ QObject *QWebEnginePagePrivate::accessibilityParentObject()
void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
{
-#ifdef QT_NO_ACTION
+#if !QT_CONFIG(action)
Q_UNUSED(action);
#else
QAction *a = actions[action];
@@ -624,7 +689,7 @@ void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
}
a->setEnabled(enabled);
-#endif // QT_NO_ACTION
+#endif // QT_CONFIG(action)
}
void QWebEnginePagePrivate::updateNavigationActions()
@@ -649,7 +714,7 @@ void QWebEnginePagePrivate::updateEditActions()
updateAction(QWebEnginePage::Unselect);
}
-#ifndef QT_NO_ACTION
+#if QT_CONFIG(action)
void QWebEnginePagePrivate::_q_webActionTriggered(bool checked)
{
Q_Q(QWebEnginePage);
@@ -659,7 +724,7 @@ void QWebEnginePagePrivate::_q_webActionTriggered(bool checked)
QWebEnginePage::WebAction action = static_cast<QWebEnginePage::WebAction>(a->data().toInt());
q->triggerAction(action, checked);
}
-#endif // QT_NO_ACTION
+#endif // QT_CONFIG(action)
void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
{
@@ -714,12 +779,31 @@ void QWebEnginePagePrivate::findTextFinished(const QWebEngineFindTextResult &res
Q_EMIT q->findTextFinished(result);
}
+void QWebEnginePagePrivate::showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ const QRect &bounds, bool autoselectFirstSuggestion)
+{
+ if (view)
+ view->showAutofillPopup(controller, bounds, autoselectFirstSuggestion);
+}
+
+void QWebEnginePagePrivate::hideAutofillPopup()
+{
+ if (view)
+ view->hideAutofillPopup();
+}
+
void QWebEnginePagePrivate::ensureInitialized() const
{
if (!adapter->isInitialized())
adapter->loadDefault();
}
+void QWebEnginePagePrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *request)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->webAuthUxRequested(request);
+}
+
QWebEnginePage::QWebEnginePage(QObject* parent)
: QObject(parent)
, d_ptr(new QWebEnginePagePrivate())
@@ -783,12 +867,13 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
/*!
\fn QWebEnginePage::quotaRequested(QWebEngineQuotaRequest quotaRequest)
\since 5.11
+ \deprecated [6.5] This signal is no longer emitted.
- This signal is emitted when the web page requests larger persistent storage
- than the application's current allocation in File System API. The default quota
- is 0 bytes.
+ Requesting host quota is no longer supported by Chromium.
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
- The request object \a quotaRequest can be used to accept or reject the request.
+ For further details, see https://crbug.com/1233525
*/
/*!
@@ -833,8 +918,6 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
the audio is played or stopped.
\note The signal is also emitted when calling the setAudioMuted() method.
- Also, if the audio is paused, this signal is emitted with an approximate \b{two-second
- delay}, from the moment the audio is paused.
*/
/*!
@@ -888,9 +971,9 @@ QWebEnginePage::~QWebEnginePage()
setDevToolsPage(nullptr);
emit _q_aboutToDelete();
- for (auto varFun : qAsConst(d_ptr->m_variantCallbacks))
+ for (auto varFun : std::as_const(d_ptr->m_variantCallbacks))
varFun(QVariant());
- for (auto strFun : qAsConst(d_ptr->m_stringCallbacks))
+ for (auto strFun : std::as_const(d_ptr->m_stringCallbacks))
strFun(QString());
d_ptr->m_variantCallbacks.clear();
d_ptr->m_stringCallbacks.clear();
@@ -1081,157 +1164,16 @@ QString QWebEnginePage::selectedText() const
return d->adapter->selectedText();
}
-#ifndef QT_NO_ACTION
+#if QT_CONFIG(action)
QAction *QWebEnginePage::action(WebAction action) const
{
Q_D(const QWebEnginePage);
if (action == QWebEnginePage::NoWebAction)
- return 0;
+ return nullptr;
if (d->actions[action])
return d->actions[action];
- QString text;
- switch (action) {
- case Back:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back);
- break;
- case Forward:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward);
- break;
- case Stop:
- text = tr("Stop");
- break;
- case Reload:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload);
- break;
- case ReloadAndBypassCache:
- text = tr("Reload and Bypass Cache");
- break;
- case Cut:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut);
- break;
- case Copy:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy);
- break;
- case Paste:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste);
- break;
- case Undo:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo);
- break;
- case Redo:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo);
- break;
- case SelectAll:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll);
- break;
- case PasteAndMatchStyle:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle);
- break;
- case OpenLinkInThisWindow:
- text = tr("Open link in this window");
- break;
- case OpenLinkInNewWindow:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow);
- break;
- case OpenLinkInNewTab:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab);
- break;
- case OpenLinkInNewBackgroundTab:
- text = tr("Open link in new background tab");
- break;
- case CopyLinkToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard);
- break;
- case DownloadLinkToDisk:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk);
- break;
- case CopyImageToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard);
- break;
- case CopyImageUrlToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard);
- break;
- case DownloadImageToDisk:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk);
- break;
- case CopyMediaUrlToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard);
- break;
- case ToggleMediaControls:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls);
- break;
- case ToggleMediaLoop:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop);
- break;
- case ToggleMediaPlayPause:
- text = tr("Toggle Play/Pause");
- break;
- case ToggleMediaMute:
- text = tr("Toggle Mute");
- break;
- case DownloadMediaToDisk:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk);
- break;
- case InspectElement:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement);
- break;
- case ExitFullScreen:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen);
- break;
- case RequestClose:
- text = tr("Close Page");
- break;
- case Unselect:
- text = tr("Unselect");
- break;
- case SavePage:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage);
- break;
- case ViewSource:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource);
- break;
- case ToggleBold:
- text = tr("&Bold");
- break;
- case ToggleItalic:
- text = tr("&Italic");
- break;
- case ToggleUnderline:
- text = tr("&Underline");
- break;
- case ToggleStrikethrough:
- text = tr("&Strikethrough");
- break;
- case AlignLeft:
- text = tr("Align &Left");
- break;
- case AlignCenter:
- text = tr("Align &Center");
- break;
- case AlignRight:
- text = tr("Align &Right");
- break;
- case AlignJustified:
- text = tr("Align &Justified");
- break;
- case Indent:
- text = tr("&Indent");
- break;
- case Outdent:
- text = tr("&Outdent");
- break;
- case InsertOrderedList:
- text = tr("Insert &Ordered List");
- break;
- case InsertUnorderedList:
- text = tr("Insert &Unordered List");
- break;
- case NoWebAction:
- case WebActionCount:
- Q_UNREACHABLE();
- break;
- }
+ const QString text = QWebEnginePagePrivate::actionText(action);
QAction *a = new QAction(const_cast<QWebEnginePage*>(this));
a->setText(text);
@@ -1243,7 +1185,7 @@ QAction *QWebEnginePage::action(WebAction action) const
d->updateAction(action);
return a;
}
-#endif // QT_NO_ACTION
+#endif // QT_CONFIG(action)
void QWebEnginePage::triggerAction(WebAction action, bool)
{
@@ -1290,26 +1232,26 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
d->adapter->unselect();
break;
case OpenLinkInThisWindow:
- if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
setUrl(d->view->lastContextMenuRequest()->filteredLinkUrl());
break;
case OpenLinkInNewWindow:
- if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
d->createNewWindow(WebContentsAdapterClient::NewWindowDisposition, true,
d->view->lastContextMenuRequest()->filteredLinkUrl());
break;
case OpenLinkInNewTab:
- if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
d->createNewWindow(WebContentsAdapterClient::NewForegroundTabDisposition, true,
d->view->lastContextMenuRequest()->filteredLinkUrl());
break;
case OpenLinkInNewBackgroundTab:
- if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
d->createNewWindow(WebContentsAdapterClient::NewBackgroundTabDisposition, true,
d->view->lastContextMenuRequest()->filteredLinkUrl());
break;
case CopyLinkToClipboard:
- if (d->view && !d->view->lastContextMenuRequest()->linkUrl().isEmpty()) {
+ if (d->view && d->view->lastContextMenuRequest() && !d->view->lastContextMenuRequest()->linkUrl().isEmpty()) {
QString urlString = d->view->lastContextMenuRequest()->linkUrl().toString(
QUrl::FullyEncoded);
QString linkText = d->view->lastContextMenuRequest()->linkText().toHtmlEscaped();
@@ -1326,7 +1268,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case DownloadLinkToDisk:
- if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid())
d->adapter->download(d->view->lastContextMenuRequest()->filteredLinkUrl(),
d->view->lastContextMenuRequest()->suggestedFileName(),
d->view->lastContextMenuRequest()->referrerUrl(),
@@ -1334,7 +1276,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
break;
case CopyImageToClipboard:
- if (d->view && d->view->lastContextMenuRequest()->hasImageContent()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->hasImageContent()
&& (d->view->lastContextMenuRequest()->mediaType()
== QWebEngineContextMenuRequest::MediaTypeImage
|| d->view->lastContextMenuRequest()->mediaType()
@@ -1343,7 +1285,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case CopyImageUrlToClipboard:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
&& d->view->lastContextMenuRequest()->mediaType()
== QWebEngineContextMenuRequest::MediaTypeImage) {
QString urlString =
@@ -1364,14 +1306,14 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
break;
case DownloadImageToDisk:
case DownloadMediaToDisk:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid())
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid())
d->adapter->download(d->view->lastContextMenuRequest()->mediaUrl(),
d->view->lastContextMenuRequest()->suggestedFileName(),
d->view->lastContextMenuRequest()->referrerUrl(),
d->view->lastContextMenuRequest()->referrerPolicy());
break;
case CopyMediaUrlToClipboard:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
&& (d->view->lastContextMenuRequest()->mediaType()
== QWebEngineContextMenuRequest::MediaTypeAudio
|| d->view->lastContextMenuRequest()->mediaType()
@@ -1395,7 +1337,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case ToggleMediaControls:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
&& d->view->lastContextMenuRequest()->mediaFlags()
& QWebEngineContextMenuRequest::MediaCanToggleControls) {
bool enable = !(d->view->lastContextMenuRequest()->mediaFlags()
@@ -1405,7 +1347,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case ToggleMediaLoop:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
&& (d->view->lastContextMenuRequest()->mediaType()
== QWebEngineContextMenuRequest::MediaTypeAudio
|| d->view->lastContextMenuRequest()->mediaType()
@@ -1417,7 +1359,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case ToggleMediaPlayPause:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
&& (d->view->lastContextMenuRequest()->mediaType()
== QWebEngineContextMenuRequest::MediaTypeAudio
|| d->view->lastContextMenuRequest()->mediaType()
@@ -1429,7 +1371,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case ToggleMediaMute:
- if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()
+ if (d->view && d->view->lastContextMenuRequest() && d->view->lastContextMenuRequest()->mediaUrl().isValid()
&& d->view->lastContextMenuRequest()->mediaFlags()
& QWebEngineContextMenuRequest::MediaHasAudio) {
// Make sure to negate the value, so that toggling actually works.
@@ -1440,7 +1382,7 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
break;
case InspectElement:
- if (d->view)
+ if (d->view && d->view->lastContextMenuRequest())
d->adapter->inspectElementAt(d->view->lastContextMenuRequest()->position());
break;
case ExitFullScreen:
@@ -1500,6 +1442,12 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
case InsertUnorderedList:
runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QWebEngineScript::ApplicationWorld);
break;
+ case ChangeTextDirectionLTR:
+ d->adapter->changeTextDirection(true /*left to right*/);
+ break;
+ case ChangeTextDirectionRTL:
+ d->adapter->changeTextDirection(false /*left to right*/);
+ break;
case NoWebAction:
break;
case WebActionCount:
@@ -1543,6 +1491,15 @@ bool QWebEnginePage::event(QEvent *e)
return QObject::event(e);
}
+void QWebEnginePagePrivate::desktopMediaRequested(
+ QtWebEngineCore::DesktopMediaController *controller)
+{
+ Q_Q(QWebEnginePage);
+ QTimer::singleShot(0, q, [q, controller]() {
+ Q_EMIT q->desktopMediaRequested(QWebEngineDesktopMediaRequest(controller));
+ });
+}
+
void QWebEnginePagePrivate::contextMenuRequested(QWebEngineContextMenuRequest *data)
{
if (view)
@@ -1550,7 +1507,7 @@ void QWebEnginePagePrivate::contextMenuRequested(QWebEngineContextMenuRequest *d
}
/*!
- \fn bool QWebEnginePage::navigationRequested(QWebEngineNavigationRequest &request)
+ \fn void QWebEnginePage::navigationRequested(QWebEngineNavigationRequest &request)
\since 6.2
This signal is emitted on navigation together with the call the acceptNavigationRequest().
@@ -1691,6 +1648,17 @@ void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
view->setToolTip(toolTipText);
}
+/*!
+ \fn void QWebEnginePage::printRequested()
+ \since 5.12
+
+ This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print
+ button of PDF viewer plugin.
+ Typically, the signal handler can simply call printToPdf().
+
+ \sa printToPdf()
+*/
+
void QWebEnginePagePrivate::printRequested()
{
Q_Q(QWebEnginePage);
@@ -1701,6 +1669,31 @@ void QWebEnginePagePrivate::printRequested()
view->printRequested();
}
+QtWebEngineCore::TouchHandleDrawableDelegate *
+QWebEnginePagePrivate::createTouchHandleDelegate(const QMap<int, QImage> &images)
+{
+ return view->createTouchHandleDelegate(images);
+}
+
+void QWebEnginePagePrivate::showTouchSelectionMenu(
+ QtWebEngineCore::TouchSelectionMenuController *controller, const QRect &selectionBounds,
+ const QSize &handleSize)
+{
+ Q_UNUSED(handleSize);
+
+ if (controller->buttonCount() == 1) {
+ controller->runContextMenu();
+ return;
+ }
+
+ view->showTouchSelectionMenu(controller, selectionBounds);
+}
+
+void QWebEnginePagePrivate::hideTouchSelectionMenu()
+{
+ view->hideTouchSelectionMenu();
+}
+
void QWebEnginePagePrivate::lifecycleStateChanged(LifecycleState state)
{
Q_Q(QWebEnginePage);
@@ -1728,7 +1721,9 @@ void QWebEnginePagePrivate::visibleChanged(bool visible)
The page does not take ownership of the pointer. This interceptor is called
after any interceptors on the profile, and unlike profile interceptors, only
- URL requests from this page are intercepted.
+ URL requests from this page are intercepted. If the original request was
+ already blocked or redirected by the profile interceptor, it will not be
+ intercepted by this.
To unset the request interceptor, set a \c nullptr.
@@ -1759,6 +1754,13 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
case Notifications:
d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::AskPermission);
break;
+ case ClipboardReadWrite:
+ d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
+ ProfileAdapter::AskPermission);
+ break;
+ case LocalFontsAccess:
+ d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, ProfileAdapter::AskPermission);
+ break;
}
return;
}
@@ -1796,6 +1798,13 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
case Notifications:
d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::AllowedPermission);
break;
+ case ClipboardReadWrite:
+ d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
+ ProfileAdapter::AllowedPermission);
+ break;
+ case LocalFontsAccess:
+ d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, ProfileAdapter::AllowedPermission);
+ break;
}
} else { // if (policy == PermissionDeniedByUser)
switch (feature) {
@@ -1815,6 +1824,13 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
case Notifications:
d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::DeniedPermission);
break;
+ case ClipboardReadWrite:
+ d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
+ ProfileAdapter::DeniedPermission);
+ break;
+ case LocalFontsAccess:
+ d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, ProfileAdapter::DeniedPermission);
+ break;
}
}
}
@@ -2003,8 +2019,12 @@ void QWebEnginePage::setZoomFactor(qreal factor)
{
Q_D(QWebEnginePage);
d->defaultZoomFactor = factor;
- if (d->adapter->isInitialized())
+
+ if (d->adapter->isInitialized()) {
d->adapter->setZoomFactor(factor);
+ // MEMO: should reset if factor was not applied due to being invalid
+ d->defaultZoomFactor = zoomFactor();
+ }
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, const std::function<void(const QVariant &)> &resultCallback)
@@ -2018,7 +2038,10 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, const std::funct
return;
}
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld);
- d->m_variantCallbacks.insert(requestId, resultCallback);
+ if (requestId)
+ d->m_variantCallbacks.insert(requestId, resultCallback);
+ else if (resultCallback)
+ resultCallback(QVariant());
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId, const std::function<void(const QVariant &)> &resultCallback)
@@ -2033,7 +2056,10 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId,
}
if (resultCallback) {
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, worldId);
- d->m_variantCallbacks.insert(requestId, resultCallback);
+ if (requestId)
+ d->m_variantCallbacks.insert(requestId, resultCallback);
+ else
+ resultCallback(QVariant());
} else {
d->adapter->runJavaScript(scriptSource, worldId);
}
@@ -2149,9 +2175,28 @@ void QWebEnginePage::setDevToolsPage(QWebEnginePage *devToolsPage)
}
}
+/*!
+ \since 6.6
+ Returns the id of the developer tools host associated with this page.
+
+ If remote debugging is enabled (see \l{Qt WebEngine Developer Tools}), the id can be used to
+ build the URL to connect to the developer tool websocket:
+ \c{ws://localhost:<debugggin-port>/devtools/page/<id>)}. The websocket can be used to to interact
+ with the page using the \l{https://chromedevtools.github.io/devtools-protocol/}{DevTools
+ Protocol}.
+*/
+
+QString QWebEnginePage::devToolsId() const
+{
+ Q_D(const QWebEnginePage);
+ d->ensureInitialized();
+ return d->adapter->devToolsId();
+}
+
ASSERT_ENUMS_MATCH(FilePickerController::Open, QWebEnginePage::FileSelectOpen)
ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, QWebEnginePage::FileSelectOpenMultiple)
ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, QWebEnginePage::FileSelectUploadFolder)
+ASSERT_ENUMS_MATCH(FilePickerController::Save, QWebEnginePage::FileSelectSave)
// TODO: remove virtuals
QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes)
@@ -2266,6 +2311,9 @@ QSizeF QWebEnginePage::contentsSize() const
To be informed about the result of the request, connect to the signal
pdfPrintingFinished().
+ \note The \l QWebEnginePage::Stop web action can be used to interrupt
+ this asynchronous operation.
+
If a file already exists at the provided file path, it will be overwritten.
\sa pdfPrintingFinished()
*/
@@ -2291,6 +2339,8 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &layo
The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array
will contain the PDF data, otherwise, the byte array will be empty.
+ \note The \l QWebEnginePage::Stop web action can be used to interrupt this operation.
+
\warning We guarantee that the callback (\a resultCallback) is always called, but it might be done
during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid
value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it.
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
index fcff3ab1e..621dacdc8 100644
--- a/src/core/api/qwebenginepage.h
+++ b/src/core/api/qwebenginepage.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEPAGE_H
#define QWEBENGINEPAGE_H
@@ -43,37 +7,41 @@
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
#include <QtWebEngineCore/qwebengineclientcertificateselection.h>
#include <QtWebEngineCore/qwebenginedownloadrequest.h>
-#include <QtWebEngineCore/qwebenginehttprequest.h>
+#include <QtWebEngineCore/qwebenginequotarequest.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
-#include <QtCore/qvariant.h>
-#include <QtGui/qaction.h>
#include <QtGui/qpagelayout.h>
#include <QtGui/qpageranges.h>
+#include <QtGui/qtgui-config.h>
#include <functional>
QT_BEGIN_NAMESPACE
+class QAction;
class QAuthenticator;
class QContextMenuBuilder;
+class QRect;
+class QVariant;
class QWebChannel;
class QWebEngineCertificateError;
-class QWebEngineClientCertificateSelection;
+class QWebEngineDesktopMediaRequest;
+class QWebEngineFileSystemAccessRequest;
class QWebEngineFindTextResult;
class QWebEngineFullScreenRequest;
class QWebEngineHistory;
+class QWebEngineHttpRequest;
class QWebEngineLoadingInfo;
class QWebEngineNavigationRequest;
class QWebEngineNewWindowRequest;
class QWebEnginePagePrivate;
class QWebEngineProfile;
-class QWebEngineQuotaRequest;
class QWebEngineRegisterProtocolHandlerRequest;
class QWebEngineScriptCollection;
class QWebEngineSettings;
class QWebEngineUrlRequestInterceptor;
+class QWebEngineWebAuthUxRequest;
class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
{
@@ -83,7 +51,7 @@ class Q_WEBENGINECORE_EXPORT QWebEnginePage : public QObject
Q_PROPERTY(QUrl requestedUrl READ requestedUrl)
Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor)
Q_PROPERTY(QString title READ title)
- Q_PROPERTY(QUrl url READ url WRITE setUrl)
+ Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(QUrl iconUrl READ iconUrl NOTIFY iconUrlChanged)
Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
@@ -156,6 +124,9 @@ public:
InsertOrderedList,
InsertUnorderedList,
+ ChangeTextDirectionLTR,
+ ChangeTextDirectionRTL,
+
WebActionCount
};
Q_ENUM(WebAction)
@@ -201,7 +172,9 @@ public:
MediaAudioVideoCapture,
MouseLock,
DesktopVideoCapture,
- DesktopAudioVideoCapture
+ DesktopAudioVideoCapture,
+ ClipboardReadWrite,
+ LocalFontsAccess,
};
Q_ENUM(Feature)
@@ -211,6 +184,7 @@ public:
FileSelectOpen,
FileSelectOpenMultiple,
FileSelectUploadFolder,
+ FileSelectSave
};
Q_ENUM(FileSelectionMode)
@@ -249,7 +223,7 @@ public:
QWebEngineProfile *profile() const;
-#ifndef QT_NO_ACTION
+#if QT_CONFIG(action)
QAction *action(WebAction action) const;
#endif
virtual void triggerAction(WebAction action, bool checked = false);
@@ -315,6 +289,7 @@ public:
QWebEnginePage *inspectedPage() const;
void setDevToolsPage(QWebEnginePage *page);
QWebEnginePage *devToolsPage() const;
+ QString devToolsId() const;
void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
@@ -342,13 +317,18 @@ Q_SIGNALS:
void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
+#if QT_DEPRECATED_SINCE(6, 5)
+ QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
void quotaRequested(QWebEngineQuotaRequest quotaRequest);
+#endif
void registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
+ void fileSystemAccessRequested(QWebEngineFileSystemAccessRequest request);
void selectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection);
void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator);
void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost);
void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
+ void desktopMediaRequested(const QWebEngineDesktopMediaRequest &request);
void certificateError(const QWebEngineCertificateError &certificateError);
void navigationRequested(QWebEngineNavigationRequest &request);
void newWindowRequested(QWebEngineNewWindowRequest &request);
@@ -378,6 +358,8 @@ Q_SIGNALS:
// TODO: fixme / rewrite bindPageToView
void _q_aboutToDelete();
+ void webAuthUxRequested(QWebEngineWebAuthUxRequest *request);
+
protected:
virtual QWebEnginePage *createWindow(WebWindowType type);
virtual QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles,
@@ -395,16 +377,16 @@ private:
Q_DISABLE_COPY(QWebEnginePage)
Q_DECLARE_PRIVATE(QWebEnginePage)
QScopedPointer<QWebEnginePagePrivate> d_ptr;
-#ifndef QT_NO_ACTION
+#if QT_CONFIG(action)
Q_PRIVATE_SLOT(d_func(), void _q_webActionTriggered(bool checked))
#endif
friend class QContextMenuBuilder;
friend class QWebEngineView;
friend class QWebEngineViewPrivate;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
friend class QWebEngineViewAccessible;
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QWebEnginePage::FindFlags)
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 4862763aa..a51d8603b 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEPAGE_P_H
#define QWEBENGINEPAGE_P_H
@@ -59,12 +23,14 @@
#include <QtCore/qcompilerdetection.h>
#include <QtCore/QPointer>
#include <QtCore/QTimer>
+#include <QtGui/QColor>
namespace QtWebEngineCore {
+class AutofillPopupController;
class RenderWidgetHostViewQtDelegate;
-class RenderWidgetHostViewQtDelegateWidget;
class RenderWidgetHostViewQtDelegateClient;
-class TouchHandleDrawableClient;
+class RenderWidgetHostViewQtDelegateItem;
+class TouchHandleDrawableDelegate;
class TouchSelectionMenuController;
class WebContentsAdapter;
}
@@ -94,6 +60,8 @@ public:
virtual void setToolTip(const QString &toolTipText) = 0;
virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate(
QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) = 0;
+ virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegateForPopup(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) = 0;
virtual QWebEngineContextMenuRequest *lastContextMenuRequest() const = 0;
virtual QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) = 0;
virtual bool isEnabled() const = 0;
@@ -106,9 +74,17 @@ public:
virtual void didPrintPage(QPrinter *&printer, QSharedPointer<QByteArray> result) = 0;
virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0;
virtual void printRequested() = 0;
+ virtual void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ const QRect &bounds, bool autoselectFirstSuggestion) = 0;
+ virtual void hideAutofillPopup() = 0;
+ virtual QtWebEngineCore::TouchHandleDrawableDelegate *
+ createTouchHandleDelegate(const QMap<int, QImage> &) = 0;
+ virtual void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *,
+ const QRect &) = 0;
+ virtual void hideTouchSelectionMenu() = 0;
};
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient
+class Q_WEBENGINECORE_EXPORT QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient
{
public:
Q_DECLARE_PUBLIC(QWebEnginePage)
@@ -118,7 +94,7 @@ public:
~QWebEnginePagePrivate();
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
- QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override { return CreateRenderWidgetHostViewQtDelegate(client); }
+ QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
void initializationFinished() override;
void lifecycleStateChanged(LifecycleState state) override;
void recommendedStateChanged(LifecycleState state) override;
@@ -129,6 +105,7 @@ public:
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl &) override;
void selectionChanged() override;
+ void zoomUpdateIsNeeded() override;
void recentlyAudibleChanged(bool recentlyAudible) override;
void renderProcessPidChanged(qint64 pid) override;
QRectF viewportRect() const override;
@@ -145,6 +122,7 @@ public:
bool isBeingAdopted() override;
void close() override;
void windowCloseRejected() override;
+ void desktopMediaRequested(QtWebEngineCore::DesktopMediaController *) override;
void contextMenuRequested(QWebEngineContextMenuRequest *request) override;
void navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame) override;
void requestFullScreenMode(const QUrl &origin, bool fullscreen) override;
@@ -166,8 +144,8 @@ public:
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
- void runQuotaRequest(QWebEngineQuotaRequest) override;
void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
+ void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override;
QObject *accessibilityParentObject() override;
QWebEngineSettings *webEngineSettings() const override;
void allowCertificateError(const QWebEngineCertificateError &error) override;
@@ -183,12 +161,18 @@ public:
bool isEnabled() const override;
void setToolTip(const QString &toolTipText) override;
void printRequested() override;
- QtWebEngineCore::TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &) override { return nullptr; }
- void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override { }
- void hideTouchSelectionMenu() override { }
+ QtWebEngineCore::TouchHandleDrawableDelegate *
+ createTouchHandleDelegate(const QMap<int, QImage> &) override;
+ void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &,
+ const QSize &) override;
+ void hideTouchSelectionMenu() override;
const QObject *holdingQObject() const override;
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }
void findTextFinished(const QWebEngineFindTextResult &result) override;
+ void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ const QRect &bounds, bool autoselectFirstSuggestion) override;
+ void hideAutofillPopup() override;
+ void showWebAuthDialog(QWebEngineWebAuthUxRequest *controller) override;
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
@@ -204,6 +188,8 @@ public:
void setFullScreenMode(bool);
void ensureInitialized() const;
+ static QString actionText(int action);
+
QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
QWebEngineHistory *history;
QWebEngineProfile *profile;
@@ -218,13 +204,12 @@ public:
QWebChannel *webChannel;
unsigned int webChannelWorldId;
QUrl iconUrl;
- bool m_navigationActionTriggered;
QPointer<QWebEnginePage> inspectedPage;
QPointer<QWebEnginePage> devToolsPage;
bool defaultAudioMuted;
qreal defaultZoomFactor;
QTimer wasShownTimer;
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget = nullptr;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *delegateItem = nullptr;
#if QT_CONFIG(webengine_printing_and_pdf)
QPrinter *currentPrinter = nullptr;
#endif
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 5e48f4dd1..dbb98102c 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -1,44 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
+#include "qwebengineclienthints.h"
#include "qwebenginecookiestore.h"
#include "qwebenginedownloadrequest.h"
#include "qwebenginedownloadrequest_p.h"
@@ -49,6 +14,7 @@
#include "qtwebenginecoreglobal.h"
#include "profile_adapter.h"
#include "visited_links_manager_qt.h"
+#include "web_engine_settings.h"
#include <QDir>
#include <QtWebEngineCore/qwebengineurlscheme.h>
@@ -163,11 +129,22 @@ void QWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::
\sa QWebEngineDownloadRequest, QWebEnginePage::download()
*/
+/*!
+ \fn QWebEngineProfile::clearHttpCacheCompleted()
+
+ \since 6.7
+
+ This signal is emitted when the clearHttpCache() operation is completed.
+
+ \sa QWebEngineProfile::clearHttpCache()
+*/
+
QWebEngineProfilePrivate::QWebEngineProfilePrivate(ProfileAdapter* profileAdapter)
: m_settings(new QWebEngineSettings())
, m_profileAdapter(profileAdapter)
, m_scriptCollection(new QWebEngineScriptCollection(
new QWebEngineScriptCollectionPrivate(profileAdapter->userResourceController())))
+ , m_clientHints(new QWebEngineClientHints(profileAdapter))
{
m_profileAdapter->addClient(this);
}
@@ -183,6 +160,8 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter())
delete m_profileAdapter;
+ else if (m_profileAdapter)
+ m_profileAdapter->releaseAllWebContentsAdapterClients();
delete m_settings;
}
@@ -219,11 +198,14 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_Q(QWebEngineProfile);
Q_ASSERT(!m_ongoingDownloads.contains(info.id));
- QWebEngineDownloadRequestPrivate *itemPrivate = new QWebEngineDownloadRequestPrivate(m_profileAdapter, info.url);
+ QWebEngineDownloadRequestPrivate *itemPrivate =
+ new QWebEngineDownloadRequestPrivate(m_profileAdapter);
itemPrivate->downloadId = info.id;
itemPrivate->downloadState = info.accepted ? QWebEngineDownloadRequest::DownloadInProgress
: QWebEngineDownloadRequest::DownloadRequested;
itemPrivate->startTime = info.startTime;
+ itemPrivate->downloadUrl = info.url;
+ itemPrivate->totalBytes = info.totalBytes;
itemPrivate->downloadDirectory = QFileInfo(info.path).path();
itemPrivate->downloadFileName = QFileInfo(info.path).fileName();
itemPrivate->suggestedFileName = info.suggestedFileName;
@@ -271,6 +253,12 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
download->d_func()->update(info);
}
+void QWebEngineProfilePrivate::clearHttpCacheCompleted()
+{
+ Q_Q(QWebEngineProfile);
+ Q_EMIT q->clearHttpCacheCompleted();
+}
+
void QWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
{
Q_ASSERT(m_profileAdapter);
@@ -283,6 +271,11 @@ void QWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::W
m_profileAdapter->removeWebContentsAdapterClient(adapter);
}
+QtWebEngineCore::WebEngineSettings *QWebEngineProfilePrivate::coreSettings() const
+{
+ return QtWebEngineCore::WebEngineSettings::get(settings());
+}
+
/*!
Constructs a new off-the-record profile with the parent \a parent.
@@ -418,6 +411,37 @@ void QWebEngineProfile::setDownloadPath(const QString &path)
}
/*!
+ \since 6.5
+
+ Returns \c true if the push messaging service is enabled.
+ \note By default the push messaging service is disabled.
+
+ \sa setPushServiceEnabled()
+*/
+bool QWebEngineProfile::isPushServiceEnabled() const
+{
+ const Q_D(QWebEngineProfile);
+ return d->profileAdapter()->pushServiceEnabled();
+}
+
+/*!
+ \since 6.5
+
+ Enables the push messaging service if \a enable is \c true, otherwise disables it.
+
+ \note \QWE uses \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)}
+ as a browser push service. Therefore, all push messages will go through the
+ Google push service and its respective servers.
+
+ \sa isPushServiceEnabled()
+*/
+void QWebEngineProfile::setPushServiceEnabled(bool enable)
+{
+ Q_D(QWebEngineProfile);
+ d->profileAdapter()->setPushServiceEnabled(enable);
+}
+
+/*!
Returns the path used for caches.
By default, this is below StandardPaths::CacheLocation in a QtWebengine/StorageName specific
@@ -454,7 +478,7 @@ void QWebEngineProfile::setCachePath(const QString &path)
"Windows NT 6.2" (Windows 8), unless the application does contain a manifest
that declares newer Windows versions as supported.
- \sa setHttpUserAgent()
+ \sa setHttpUserAgent(), {windows_manifest} {Windows Application Manifest}
*/
QString QWebEngineProfile::httpUserAgent() const
{
@@ -489,7 +513,10 @@ QWebEngineProfile::HttpCacheType QWebEngineProfile::httpCacheType() const
/*!
Sets the HTTP cache type to \a httpCacheType.
- \sa httpCacheType(), setCachePath()
+ \note Setting the \a httpCacheType to NoCache on the profile, which has already some cache
+ entries does not trigger the removal of those entries.
+
+ \sa httpCacheType(), setCachePath(), clearHttpCache()
*/
void QWebEngineProfile::setHttpCacheType(QWebEngineProfile::HttpCacheType httpCacheType)
{
@@ -808,6 +835,12 @@ void QWebEngineProfile::removeAllUrlSchemeHandlers()
\since 5.7
Removes the profile's cache entries.
+
+ \note Make sure that you do not start new navigation or any operation on the profile while
+ the clear operation is in progress. The clearHttpCacheCompleted() signal notifies about the
+ completion.
+
+ \sa QWebEngineProfile::clearHttpCacheCompleted()
*/
void QWebEngineProfile::clearHttpCache()
{
@@ -896,4 +929,19 @@ void QWebEngineProfile::requestIconForIconURL(const QUrl &url, int desiredSizeIn
iconAvailableCallback);
}
+/*!
+ Return the Client Hints settings associated with this browsing context.
+
+ \since 6.8
+ \sa QWebEngineClientHints
+*/
+QWebEngineClientHints *QWebEngineProfile::clientHints() const
+{
+ Q_D(const QWebEngineProfile);
+ return d->m_clientHints.data();
+}
+
QT_END_NAMESPACE
+
+#include "moc_qwebengineprofile.cpp"
+#include "moc_qwebengineurlrequestinterceptor.cpp"
diff --git a/src/core/api/qwebengineprofile.h b/src/core/api/qwebengineprofile.h
index 5e8deb216..a0027cb81 100644
--- a/src/core/api/qwebengineprofile.h
+++ b/src/core/api/qwebengineprofile.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEPROFILE_H
#define QWEBENGINEPROFILE_H
@@ -53,6 +17,7 @@ QT_BEGIN_NAMESPACE
class QUrl;
class QWebEngineClientCertificateStore;
+class QWebEngineClientHints;
class QWebEngineCookieStore;
class QWebEngineDownloadRequest;
class QWebEngineNotification;
@@ -117,6 +82,7 @@ public:
QWebEngineSettings *settings() const;
QWebEngineScriptCollection *scripts() const;
+ QWebEngineClientHints *clientHints() const;
const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const;
void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *);
@@ -134,6 +100,9 @@ public:
QString downloadPath() const;
void setDownloadPath(const QString &path);
+ bool isPushServiceEnabled() const;
+ void setPushServiceEnabled(bool enabled);
+
void setNotificationPresenter(std::function<void(std::unique_ptr<QWebEngineNotification>)> notificationPresenter);
QWebEngineClientCertificateStore *clientCertificateStore();
@@ -145,6 +114,7 @@ public:
Q_SIGNALS:
void downloadRequested(QWebEngineDownloadRequest *download);
+ void clearHttpCacheCompleted();
private:
Q_DISABLE_COPY(QWebEngineProfile)
diff --git a/src/core/api/qwebengineprofile_p.h b/src/core/api/qwebengineprofile_p.h
index 396c8b9bf..0ccc27037 100644
--- a/src/core/api/qwebengineprofile_p.h
+++ b/src/core/api/qwebengineprofile_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEPROFILE_P_H
#define QWEBENGINEPROFILE_P_H
@@ -62,16 +26,18 @@
namespace QtWebEngineCore {
class ProfileAdapter;
+class WebEngineSettings;
}
QT_BEGIN_NAMESPACE
+class QWebEngineClientHints;
class QWebEngineNotification;
class QWebEngineProfile;
class QWebEngineScriptCollection;
class QWebEngineSettings;
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClient {
+class Q_WEBENGINECORE_EXPORT QWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClient {
public:
Q_DECLARE_PUBLIC(QWebEngineProfile)
QWebEngineProfilePrivate(QtWebEngineCore::ProfileAdapter *profileAdapter);
@@ -79,6 +45,7 @@ public:
QtWebEngineCore::ProfileAdapter *profileAdapter() const;
QWebEngineSettings *settings() const { return m_settings; }
+ QtWebEngineCore::WebEngineSettings *coreSettings() const override;
void downloadDestroyed(quint32 downloadId);
@@ -88,6 +55,7 @@ public:
void downloadUpdated(const DownloadItemInfo &info) override;
void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &) override;
+ void clearHttpCacheCompleted() override;
void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
@@ -97,6 +65,7 @@ private:
QWebEngineSettings *m_settings;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QScopedPointer<QWebEngineScriptCollection> m_scriptCollection;
+ QScopedPointer<QWebEngineClientHints> m_clientHints;
QMap<quint32, QPointer<QWebEngineDownloadRequest>> m_ongoingDownloads;
std::function<void(std::unique_ptr<QWebEngineNotification>)> m_notificationPresenter;
};
diff --git a/src/core/api/qwebenginequotarequest.cpp b/src/core/api/qwebenginequotarequest.cpp
index 7686d0806..3c312216d 100644
--- a/src/core/api/qwebenginequotarequest.cpp
+++ b/src/core/api/qwebenginequotarequest.cpp
@@ -1,113 +1,56 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginequotarequest.h"
-#include "quota_request_controller.h"
+#if QT_DEPRECATED_SINCE(6, 5)
QT_BEGIN_NAMESPACE
/*!
\class QWebEngineQuotaRequest
- \brief The QWebEngineQuotaRequest class enables accepting or rejecting
- requests for larger persistent storage than the application's current
- allocation in File System API.
-
\since 5.11
\inmodule QtWebEngineCore
+ \deprecated [6.5] Requesting host quota is no longer supported by Chromium.
+
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
- This class is used by the QWebEnginePage::quotaRequested() signal to \l
- accept() or \l reject() a request for an increase in the persistent storage
- allocated to the application. The default quota is 0 bytes.
+ For further details, see https://crbug.com/1233525
*/
/*! \fn QWebEngineQuotaRequest::QWebEngineQuotaRequest()
\internal
*/
-/*! \internal */
-QWebEngineQuotaRequest::QWebEngineQuotaRequest(QSharedPointer<QtWebEngineCore::QuotaRequestController> controller)
- : d_ptr(controller)
-{}
-
-/*!
- Rejects a request for larger persistent storage.
-*/
void QWebEngineQuotaRequest::reject()
{
- d_ptr->reject();
}
-/*!
- Accepts a request for larger persistent storage.
-*/
void QWebEngineQuotaRequest::accept()
{
- d_ptr->accept();
}
/*!
\property QWebEngineQuotaRequest::origin
- \brief The URL of the web page that issued the quota request.
*/
QUrl QWebEngineQuotaRequest::origin() const
{
- return d_ptr->origin();
+ return QUrl();
}
/*!
\property QWebEngineQuotaRequest::requestedSize
- \brief Contains the size of the requested disk space in bytes.
*/
qint64 QWebEngineQuotaRequest::requestedSize() const
{
- return d_ptr->requestedSize();
+ return 0;
}
-/*! \fn bool QWebEngineQuotaRequest::operator==(const QWebEngineQuotaRequest &that) const
- Returns \c true if \a that points to the same object as this quota request.
-*/
+QT_END_NAMESPACE
-/*! \fn bool QWebEngineQuotaRequest::operator!=(const QWebEngineQuotaRequest &that) const
- Returns \c true if \a that points to a different object than this request.
-*/
+#endif // QT_DEPRECATED_SINCE(6, 5)
-QT_END_NAMESPACE
+#include "moc_qwebenginequotarequest.cpp"
diff --git a/src/core/api/qwebenginequotarequest.h b/src/core/api/qwebenginequotarequest.h
index 599ca8963..f542f5576 100644
--- a/src/core/api/qwebenginequotarequest.h
+++ b/src/core/api/qwebenginequotarequest.h
@@ -1,54 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEQUOTAREQUEST_H
#define QWEBENGINEQUOTAREQUEST_H
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
-#include <QtCore/qsharedpointer.h>
#include <QtCore/qurl.h>
-namespace QtWebEngineCore {
-class QuotaPermissionContextQt;
-class QuotaRequestController;
-} // namespace QtWebEngineCore
+#if QT_DEPRECATED_SINCE(6, 5)
QT_BEGIN_NAMESPACE
@@ -58,20 +18,18 @@ class Q_WEBENGINECORE_EXPORT QWebEngineQuotaRequest
Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
Q_PROPERTY(qint64 requestedSize READ requestedSize CONSTANT FINAL)
public:
+ QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
QWebEngineQuotaRequest() {}
Q_INVOKABLE void accept();
Q_INVOKABLE void reject();
QUrl origin() const;
qint64 requestedSize() const;
- bool operator==(const QWebEngineQuotaRequest &that) const { return d_ptr == that.d_ptr; }
- bool operator!=(const QWebEngineQuotaRequest &that) const { return d_ptr != that.d_ptr; }
-
-private:
- QWebEngineQuotaRequest(QSharedPointer<QtWebEngineCore::QuotaRequestController>);
- friend QtWebEngineCore::QuotaPermissionContextQt;
- QSharedPointer<QtWebEngineCore::QuotaRequestController> d_ptr;
+ bool operator==(const QWebEngineQuotaRequest &) const { Q_UNREACHABLE(); }
+ bool operator!=(const QWebEngineQuotaRequest &) const { Q_UNREACHABLE(); }
};
QT_END_NAMESPACE
+#endif // QT_DEPRECATED_SINCE(6, 5)
+
#endif // QWEBENGINEQUOTAREQUEST_H
diff --git a/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp b/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp
index bb59282ea..3e52302e4 100644
--- a/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp
+++ b/src/core/api/qwebengineregisterprotocolhandlerrequest.cpp
@@ -1,45 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineregisterprotocolhandlerrequest.h"
-#include "register_protocol_handler_request_controller.h"
+#include "custom_handlers/register_protocol_handler_request_controller.h"
QT_BEGIN_NAMESPACE
@@ -114,3 +78,5 @@ QString QWebEngineRegisterProtocolHandlerRequest::scheme() const
*/
QT_END_NAMESPACE
+
+#include "moc_qwebengineregisterprotocolhandlerrequest.cpp"
diff --git a/src/core/api/qwebengineregisterprotocolhandlerrequest.h b/src/core/api/qwebengineregisterprotocolhandlerrequest.h
index 86eb37404..d6e51695e 100644
--- a/src/core/api/qwebengineregisterprotocolhandlerrequest.h
+++ b/src/core/api/qwebengineregisterprotocolhandlerrequest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEREGISTERPROTOCOLHANDLERREQUEST_H
#define QWEBENGINEREGISTERPROTOCOLHANDLERREQUEST_H
diff --git a/src/core/api/qwebenginescript.cpp b/src/core/api/qwebenginescript.cpp
index f23e91ea5..29b92a396 100644
--- a/src/core/api/qwebenginescript.cpp
+++ b/src/core/api/qwebenginescript.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginescript.h"
@@ -181,12 +145,11 @@ void QWebEngineScript::setSourceUrl(const QUrl &url)
d->setSourceUrl(url);
QFile file;
- if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
+ if (url.isLocalFile()) {
+ file.setFileName(url.toLocalFile());
+ } else if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
if (url.authority().isEmpty())
file.setFileName(QLatin1Char(':') + url.path());
- return;
- } else {
- file.setFileName(url.toLocalFile());
}
if (!file.open(QIODevice::ReadOnly)) {
@@ -316,3 +279,5 @@ QDebug operator<<(QDebug d, const QWebEngineScript &script)
#endif
QT_END_NAMESPACE
+
+#include "moc_qwebenginescript.cpp"
diff --git a/src/core/api/qwebenginescript.h b/src/core/api/qwebenginescript.h
index a9b1bb869..9827c4879 100644
--- a/src/core/api/qwebenginescript.h
+++ b/src/core/api/qwebenginescript.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINESCRIPT_H
#define QWEBENGINESCRIPT_H
@@ -107,7 +71,7 @@ public:
bool operator==(const QWebEngineScript &other) const;
inline bool operator!=(const QWebEngineScript &other) const
{ return !operator==(other); }
- void swap(QWebEngineScript &other) { qSwap(d, other.d); }
+ void swap(QWebEngineScript &other) noexcept { d.swap(other.d); }
private:
friend class QWebEngineScriptCollectionPrivate;
diff --git a/src/core/api/qwebenginescriptcollection.cpp b/src/core/api/qwebenginescriptcollection.cpp
index d19fcaa24..7867192b6 100644
--- a/src/core/api/qwebenginescriptcollection.cpp
+++ b/src/core/api/qwebenginescriptcollection.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginescriptcollection.h"
#include "qwebenginescriptcollection_p.h"
@@ -156,7 +120,7 @@ QWebEngineScriptCollectionPrivate::QWebEngineScriptCollectionPrivate(QtWebEngine
int QWebEngineScriptCollectionPrivate::count() const
{
- return m_scripts.count();
+ return m_scripts.size();
}
bool QWebEngineScriptCollectionPrivate::contains(const QWebEngineScript &s) const
@@ -184,7 +148,7 @@ QList<QWebEngineScript> QWebEngineScriptCollectionPrivate::toList(const QString
return m_scripts;
QList<QWebEngineScript> ret;
- for (const QWebEngineScript &script : qAsConst(m_scripts))
+ for (const QWebEngineScript &script : std::as_const(m_scripts))
if (scriptName == script.name())
ret.append(script);
return ret;
@@ -209,7 +173,7 @@ void QWebEngineScriptCollectionPrivate::initializationFinished(QSharedPointer<Qt
Q_ASSERT(m_contents);
Q_ASSERT(contents);
- for (const QWebEngineScript &script : qAsConst(m_scripts))
+ for (const QWebEngineScript &script : std::as_const(m_scripts))
m_scriptController->addUserScript(*script.d, contents.data());
m_contents = contents;
}
diff --git a/src/core/api/qwebenginescriptcollection.h b/src/core/api/qwebenginescriptcollection.h
index 7bc9005cb..a3b3c1c08 100644
--- a/src/core/api/qwebenginescriptcollection.h
+++ b/src/core/api/qwebenginescriptcollection.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINESCRIPTCOLLECTION_H
#define QWEBENGINESCRIPTCOLLECTION_H
@@ -70,6 +34,7 @@ private:
friend class QWebEngineProfilePrivate;
friend class QQuickWebEngineProfilePrivate;
friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineScriptCollectionPrivate;
QWebEngineScriptCollection(QWebEngineScriptCollectionPrivate *);
QScopedPointer<QWebEngineScriptCollectionPrivate> d;
diff --git a/src/core/api/qwebenginescriptcollection_p.h b/src/core/api/qwebenginescriptcollection_p.h
index 62444c78f..67b3aa4a7 100644
--- a/src/core/api/qwebenginescriptcollection_p.h
+++ b/src/core/api/qwebenginescriptcollection_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINESCRIPTCOLLECTION_P_H
#define QWEBENGINESCRIPTCOLLECTION_P_H
@@ -63,7 +27,7 @@ class UserResourceControllerHost;
} // namespace
QT_BEGIN_NAMESPACE
-class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineScriptCollectionPrivate
+class Q_WEBENGINECORE_EXPORT QWebEngineScriptCollectionPrivate
{
public:
QWebEngineScriptCollectionPrivate(QtWebEngineCore::UserResourceControllerHost *, QSharedPointer<QtWebEngineCore::WebContentsAdapter> = QSharedPointer<QtWebEngineCore::WebContentsAdapter>());
diff --git a/src/core/api/qwebenginesettings.cpp b/src/core/api/qwebenginesettings.cpp
index 08f76b80e..f19d8efe5 100644
--- a/src/core/api/qwebenginesettings.cpp
+++ b/src/core/api/qwebenginesettings.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginesettings.h"
#include "web_engine_settings.h"
@@ -139,4 +103,19 @@ void QWebEngineSettings::setParentSettings(QWebEngineSettings *parentSettings)
d_ptr->setParentSettings(parentSettings->d_ptr.data());
}
+void QWebEngineSettings::setImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy)
+{
+ d_ptr->setImageAnimationPolicy(policy);
+}
+
+QWebEngineSettings::ImageAnimationPolicy QWebEngineSettings::imageAnimationPolicy() const
+{
+ return d_ptr->imageAnimationPolicy();
+}
+
+void QWebEngineSettings::resetImageAnimationPolicy()
+{
+ d_ptr->setImageAnimationPolicy(QWebEngineSettings::InheritedImageAnimationPolicy);
+}
+
QT_END_NAMESPACE
diff --git a/src/core/api/qwebenginesettings.h b/src/core/api/qwebenginesettings.h
index ff1935616..7f89f1ea6 100644
--- a/src/core/api/qwebenginesettings.h
+++ b/src/core/api/qwebenginesettings.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINESETTINGS_H
#define QWEBENGINESETTINGS_H
@@ -95,6 +59,9 @@ public:
JavascriptCanPaste,
DnsPrefetchEnabled,
PdfViewerEnabled,
+ NavigateOnDropEnabled,
+ ReadingFromCanvasEnabled,
+ ForceDarkMode,
};
enum FontSize {
@@ -111,6 +78,13 @@ public:
AllowAllUnknownUrlSchemes
};
+ enum ImageAnimationPolicy {
+ InheritedImageAnimationPolicy = 0,
+ AllowImageAnimation,
+ AnimateImageOnce,
+ DisallowImageAnimation
+ };
+
public:
~QWebEngineSettings();
void setFontFamily(FontFamily which, const QString &family);
@@ -132,6 +106,10 @@ public:
void setUnknownUrlSchemePolicy(UnknownUrlSchemePolicy policy);
void resetUnknownUrlSchemePolicy();
+ void setImageAnimationPolicy(ImageAnimationPolicy policy);
+ ImageAnimationPolicy imageAnimationPolicy() const;
+ void resetImageAnimationPolicy();
+
private:
explicit QWebEngineSettings(QWebEngineSettings *parentSettings = nullptr);
void setParentSettings(QWebEngineSettings *parentSettings);
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 10661ec8f..152cf4dd0 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -1,49 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineurlrequestinfo.h"
#include "qwebengineurlrequestinfo_p.h"
#include "web_contents_adapter_client.h"
+#include "net/resource_request_body_qt.h"
+
+#include <memory>
+#include <utility>
QT_BEGIN_NAMESPACE
+// We changed the type from QScopedPointer to unique_ptr, make sure it's binary compatible:
+static_assert(sizeof(QScopedPointer<QWebEngineUrlRequestInfoPrivate>)
+ == sizeof(std::unique_ptr<QWebEngineUrlRequestInfoPrivate>));
+
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::TypedNavigation, QWebEngineUrlRequestInfo::NavigationTypeTyped)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::FormSubmittedNavigation,
@@ -105,10 +77,11 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::RedirectNavigation
execution of this function is finished.
*/
-QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
- QWebEngineUrlRequestInfo::NavigationType navigation,
- const QUrl &u, const QUrl &fpu, const QUrl &i,
- const QByteArray &m)
+QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(
+ QWebEngineUrlRequestInfo::ResourceType resource,
+ QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu,
+ const QUrl &i, const QByteArray &m, QtWebEngineCore::ResourceRequestBody *const rb,
+ const QHash<QByteArray, QByteArray> &h)
: resourceType(resource)
, navigationType(navigation)
, shouldBlockRequest(false)
@@ -118,6 +91,8 @@ QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRe
, initiator(i)
, method(m)
, changed(false)
+ , extraHeaders(h)
+ , resourceRequestBody(rb)
{}
/*!
@@ -128,14 +103,17 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo() {}
/*!
\internal
*/
-QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfo &&p) : d_ptr(p.d_ptr.take()) {}
+QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfo &&p)
+ : d_ptr(std::move(p.d_ptr))
+{
+}
/*!
\internal
*/
QWebEngineUrlRequestInfo &QWebEngineUrlRequestInfo::operator=(QWebEngineUrlRequestInfo &&p)
{
- d_ptr.reset(p.d_ptr.take());
+ d_ptr = std::move(p.d_ptr);
return *this;
}
@@ -181,6 +159,7 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva
\value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7)
\value ResourceTypeNavigationPreloadMainFrame A main-frame service worker navigation preload request. (Added in Qt 5.14)
\value ResourceTypeNavigationPreloadSubFrame A sub-frame service worker navigation preload request. (Added in Qt 5.14)
+ \value ResourceTypeWebSocket A WebSocket request. (Added in Qt 6.4)
\value ResourceTypeUnknown Unknown request type.
\note For forward compatibility all values not matched should be treated as unknown,
@@ -264,6 +243,20 @@ QByteArray QWebEngineUrlRequestInfo::requestMethod() const
}
/*!
+ Returns a pointer to a QIODevice that gives access to the request body.
+ The request body can contain data for example when the request is
+ a POST request. If the request body is empty the QIODevice reflects this
+ and does not return any data when performing read operations on it.
+
+ \since 6.7
+*/
+
+QIODevice *QWebEngineUrlRequestInfo::requestBody() const
+{
+ return d_ptr->resourceRequestBody;
+}
+
+/*!
\internal
*/
bool QWebEngineUrlRequestInfo::changed() const
@@ -309,8 +302,36 @@ void QWebEngineUrlRequestInfo::block(bool shouldBlock)
void QWebEngineUrlRequestInfo::setHttpHeader(const QByteArray &name, const QByteArray &value)
{
- d_ptr->changed = true;
+ // Headers are case insentive, so we need to compare manually
+ for (auto it = d_ptr->extraHeaders.begin(); it != d_ptr->extraHeaders.end(); ++it) {
+ if (it.key().compare(name, Qt::CaseInsensitive) == 0) {
+ d_ptr->extraHeaders.erase(it);
+ break;
+ }
+ }
+
d_ptr->extraHeaders.insert(name, value);
}
+/*!
+ Returns the request headers.
+ \since 6.5
+ \note Not all headers are visible at this stage as Chromium will add
+ security and proxy headers at a later stage.
+*/
+
+QHash<QByteArray, QByteArray> QWebEngineUrlRequestInfo::httpHeaders() const
+{
+ return d_ptr->extraHeaders;
+}
+
+/*!
+ \internal
+*/
+void QWebEngineUrlRequestInfoPrivate::appendFileToResourceRequestBodyForTest(const QString &path)
+{
+ if (resourceRequestBody)
+ resourceRequestBody->appendFilesForTest(path);
+}
+
QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index 658386632..33efcbeda 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -1,54 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEURLREQUESTINFO_H
#define QWEBENGINEURLREQUESTINFO_H
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
-#include <QtCore/qscopedpointer.h>
#include <QtCore/qurl.h>
+#include <QtCore/qiodevice.h>
+
+#include <memory>
namespace QtWebEngineCore {
+class ContentBrowserClientQt;
class InterceptedRequest;
} // namespace QtWebEngineCore
+class TestPostRequestInterceptor;
+
QT_BEGIN_NAMESPACE
class QWebEngineUrlRequestInfoPrivate;
@@ -81,6 +50,7 @@ public:
#ifndef Q_QDOC
ResourceTypeLast = ResourceTypeNavigationPreloadSubFrame,
#endif
+ ResourceTypeWebSocket = 254,
ResourceTypeUnknown = 255
};
@@ -101,14 +71,18 @@ public:
QUrl firstPartyUrl() const;
QUrl initiator() const;
QByteArray requestMethod() const;
+ QIODevice *requestBody() const;
bool changed() const;
void block(bool shouldBlock);
void redirect(const QUrl &url);
void setHttpHeader(const QByteArray &name, const QByteArray &value);
+ QHash<QByteArray, QByteArray> httpHeaders() const;
private:
+ friend class QtWebEngineCore::ContentBrowserClientQt;
friend class QtWebEngineCore::InterceptedRequest;
+ friend class ::TestPostRequestInterceptor;
Q_DISABLE_COPY(QWebEngineUrlRequestInfo)
Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo)
@@ -119,7 +93,7 @@ private:
QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfo &&p);
QWebEngineUrlRequestInfo &operator=(QWebEngineUrlRequestInfo &&p);
~QWebEngineUrlRequestInfo();
- QScopedPointer<QWebEngineUrlRequestInfoPrivate> d_ptr;
+ std::unique_ptr<QWebEngineUrlRequestInfoPrivate> d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h
index 05a89c5cf..95cc72362 100644
--- a/src/core/api/qwebengineurlrequestinfo_p.h
+++ b/src/core/api/qwebengineurlrequestinfo_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEURLREQUESTINFO_P_H
#define QWEBENGINEURLREQUESTINFO_P_H
@@ -63,15 +27,22 @@ namespace net {
class URLRequest;
}
+namespace QtWebEngineCore {
+class ResourceRequestBody;
+}
+
QT_BEGIN_NAMESPACE
-class QWebEngineUrlRequestInfoPrivate
+class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestInfoPrivate
{
Q_DECLARE_PUBLIC(QWebEngineUrlRequestInfo)
public:
QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
- QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu,
- const QUrl &i, const QByteArray &m);
+ QWebEngineUrlRequestInfo::NavigationType navigation,
+ const QUrl &u, const QUrl &fpu, const QUrl &i,
+ const QByteArray &m,
+ QtWebEngineCore::ResourceRequestBody *const rb = nullptr,
+ const QHash<QByteArray, QByteArray> &h = {});
QWebEngineUrlRequestInfo::ResourceType resourceType;
QWebEngineUrlRequestInfo::NavigationType navigationType;
@@ -83,8 +54,11 @@ public:
const QByteArray method;
bool changed;
QHash<QByteArray, QByteArray> extraHeaders;
+ QtWebEngineCore::ResourceRequestBody *const resourceRequestBody;
QWebEngineUrlRequestInfo *q_ptr;
+
+ void appendFileToResourceRequestBodyForTest(const QString &path);
};
QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlrequestinterceptor.cpp b/src/core/api/qwebengineurlrequestinterceptor.cpp
new file mode 100644
index 000000000..c3cd49a5b
--- /dev/null
+++ b/src/core/api/qwebengineurlrequestinterceptor.cpp
@@ -0,0 +1,11 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebengineurlrequestinterceptor.h"
+
+QT_BEGIN_NAMESPACE
+
+// Has to stay empty till Qt7
+QWebEngineUrlRequestInterceptor::~QWebEngineUrlRequestInterceptor() = default;
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h
index a96ded1a3..2ca8ee914 100644
--- a/src/core/api/qwebengineurlrequestinterceptor.h
+++ b/src/core/api/qwebengineurlrequestinterceptor.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENINGEURLREQUESTINTERCEPTOR_H
#define QWEBENINGEURLREQUESTINTERCEPTOR_H
@@ -50,10 +14,9 @@ QT_BEGIN_NAMESPACE
class Q_WEBENGINECORE_EXPORT QWebEngineUrlRequestInterceptor : public QObject
{
Q_OBJECT
- Q_DISABLE_COPY(QWebEngineUrlRequestInterceptor)
public:
explicit QWebEngineUrlRequestInterceptor(QObject *p = nullptr) : QObject(p) {}
-
+ ~QWebEngineUrlRequestInterceptor() override;
virtual void interceptRequest(QWebEngineUrlRequestInfo &info) = 0;
};
diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index 3bb9d1732..b3997a49d 100644
--- a/src/core/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineurlrequestjob.h"
@@ -148,7 +112,36 @@ QMap<QByteArray, QByteArray> QWebEngineUrlRequestJob::requestHeaders() const
}
/*!
- Replies to the request with \a device and the MIME type \a contentType.
+ Returns a pointer to a QIODevice that gives access to the request body.
+ The request body can contain data for example when the request is
+ a POST request. If the request body is empty the QIODevice reflects this
+ and does not return any data when performing read operations on it.
+
+ \since 6.7
+ \sa QIODevice
+*/
+QIODevice *QWebEngineUrlRequestJob::requestBody() const
+{
+ return d_ptr->requestBody();
+}
+
+/*!
+ \since 6.6
+ Set \a additionalResponseHeaders. These additional headers of the response
+ are only used when QWebEngineUrlRequestJob::reply(const QByteArray&, QIODevice*)
+ is called.
+*/
+void QWebEngineUrlRequestJob::setAdditionalResponseHeaders(
+ const QMultiMap<QByteArray, QByteArray> &additionalResponseHeaders) const
+{
+ d_ptr->setAdditionalResponseHeaders(additionalResponseHeaders);
+}
+
+/*!
+ Replies to the request with \a device and the content type \a contentType.
+ Content type is similar to the HTTP Content-Type header, and can either be
+ a MIME type, or a MIME type and charset encoding combined like this:
+ "text/html; charset=utf-8".
The user has to be aware that \a device will be used on another thread
until the job is deleted. In case simultaneous access from the main thread
@@ -189,3 +182,5 @@ void QWebEngineUrlRequestJob::redirect(const QUrl &url)
}
QT_END_NAMESPACE
+
+#include "moc_qwebengineurlrequestjob.cpp"
diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h
index c7128fd3c..a0cb48b8b 100644
--- a/src/core/api/qwebengineurlrequestjob.h
+++ b/src/core/api/qwebengineurlrequestjob.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEURLREQUESTJOB_H
#define QWEBENGINEURLREQUESTJOB_H
@@ -75,10 +39,13 @@ public:
QByteArray requestMethod() const;
QUrl initiator() const;
QMap<QByteArray, QByteArray> requestHeaders() const;
+ QIODevice *requestBody() const;
void reply(const QByteArray &contentType, QIODevice *device);
void fail(Error error);
void redirect(const QUrl &url);
+ void setAdditionalResponseHeaders(
+ const QMultiMap<QByteArray, QByteArray> &additionalResponseHeaders) const;
private:
QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *);
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index f73992c6b..3093c2b8e 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineurlscheme.h"
@@ -171,12 +135,12 @@ public:
Indicates that the URL scheme provides access to local resources. The purpose
of this flag is to prevent network content from accessing local resources.
Only schemes with the \c LocalAccessAllowed flag may load resources from a
- scheme with the \c Local flag. The only builtin schemes with this flag are \c
- file and \c qrc.
+ scheme with the \c LocalScheme flag. The only builtin scheme with this flag is \c
+ file.
\value LocalAccessAllowed
Indicates that content from this scheme should be allowed to load resources
- from schemes with the \c Local flag.
+ from schemes with the \c LocalScheme flag.
\value NoAccessAllowed
Indicates that all content from this scheme should be forced to have unique
@@ -194,10 +158,15 @@ public:
\value CorsEnabled
Enables cross-origin resource sharing (CORS) for this scheme. This flag is
- required in order to, for example, use the scheme with the \l
- {https://fetch.spec.whatwg.org/}{Fetch API}, or to deliver CSS fonts to a
- different origin. The appropriate CORS headers are generated automatically by
- the QWebEngineUrlRequestJob class. (Added in Qt 5.14)
+ required in order for content to be loaded by documents of a different origin,
+ this includes access from other schemes. The appropriate CORS headers are
+ generated automatically by the QWebEngineUrlRequestJob class. By default only
+ \c http and \c https are CORS enabled. (Added in Qt 5.14)
+
+ \value [since 6.6] FetchApiAllowed
+ Enables a URL scheme to be used by the HTML5 fetch API and \c XMLHttpRequest.send with
+ a body. By default only \c http and \c https can be send to using the Fetch API or with
+ an XMLHttpRequest with a body.
*/
QWebEngineUrlScheme::QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d) : d(d) {}
@@ -415,3 +384,5 @@ void QWebEngineUrlScheme::lockSchemes()
}
QT_END_NAMESPACE
+
+#include "moc_qwebengineurlscheme.cpp"
diff --git a/src/core/api/qwebengineurlscheme.h b/src/core/api/qwebengineurlscheme.h
index e934f39d5..35498a68e 100644
--- a/src/core/api/qwebengineurlscheme.h
+++ b/src/core/api/qwebengineurlscheme.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEURLSCHEME_H
#define QWEBENGINEURLSCHEME_H
@@ -78,6 +42,7 @@ public:
ViewSourceAllowed = 0x20,
ContentSecurityPolicyIgnored = 0x40,
CorsEnabled = 0x80,
+ FetchApiAllowed = 0x100,
};
Q_DECLARE_FLAGS(Flags, Flag)
Q_FLAG(Flags)
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index aecee5044..e01ecef49 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineurlschemehandler.h"
@@ -48,9 +12,23 @@ QT_BEGIN_NAMESPACE
\brief The QWebEngineUrlSchemeHandler class is a base class for handling custom URL schemes.
\since 5.6
+ A custom scheme handler is, broadly speaking, similar to a web application
+ served over HTTP. However, because custom schemes are integrated directly
+ into the web engine, they have the advantage in terms of efficiency and security:
+ There is no need for generating and parsing HTTP messages or for transferring data
+ over sockets, nor any way to intercept or monitor the traffic.
+
To implement a custom URL scheme for QtWebEngine, you first have to create an instance of
QWebEngineUrlScheme and register it using QWebEngineUrlScheme::registerScheme().
+ As custom schemes are integrated directly into the web engine, they do not
+ necessarily need to follow the standard security rules which apply to
+ ordinary web content. Depending on the chosen configuration, content served
+ over a custom scheme may be given access to local resources, be set to
+ ignore Content-Security-Policy rules, or conversely, be denied access to any
+ other content entirely. If it is to be accessed by normal content, ensure cross-origin
+ access is enabled, and if accessed from HTTPS that it is marked as secure.
+
\note Make sure that you create and register the scheme object \e before the QGuiApplication
or QApplication object is instantiated.
@@ -66,10 +44,23 @@ QT_BEGIN_NAMESPACE
{
public:
MySchemeHandler(QObject *parent = nullptr);
- void requestStarted(QWebEngineUrlRequestJob *request)
+ void requestStarted(QWebEngineUrlRequestJob *job)
{
- // ....
+ const QByteArray method = job->requestMethod();
+ const QUrl url = job->requestUrl();
+
+ if (isValidUrl(url)) {
+ if (method == QByteArrayLiteral("GET")) {
+ job->reply(QByteArrayLiteral("text/html"), makeReply(url));
+ else // Unsupported method
+ job->fail(QWebEngineUrlRequestJob::RequestDenied);
+ } else {
+ // Invalid URL
+ job->fail(QWebEngineUrlRequestJob::UrlNotFound);
+ }
}
+ bool isValidUrl(const QUrl &url) const // ....
+ QIODevice *makeReply(const QUrl &url) // ....
};
int main(int argc, char **argv)
@@ -92,7 +83,7 @@ QT_BEGIN_NAMESPACE
\inmodule QtWebEngineCore
- \sa {QWebEngineUrlScheme}, {WebEngine Widgets WebUI Example}
+ \sa {QWebEngineUrlScheme}
*/
/*!
@@ -125,3 +116,5 @@ QWebEngineUrlSchemeHandler::~QWebEngineUrlSchemeHandler()
*/
QT_END_NAMESPACE
+
+#include "moc_qwebengineurlschemehandler.cpp"
diff --git a/src/core/api/qwebengineurlschemehandler.h b/src/core/api/qwebengineurlschemehandler.h
index c1625d9d7..848904719 100644
--- a/src/core/api/qwebengineurlschemehandler.h
+++ b/src/core/api/qwebengineurlschemehandler.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEURLSCHEMEHANDLER_H
#define QWEBENGINEURLSCHEMEHANDLER_H
diff --git a/src/core/api/qwebenginewebauthuxrequest.cpp b/src/core/api/qwebenginewebauthuxrequest.cpp
new file mode 100644
index 000000000..6a79daec9
--- /dev/null
+++ b/src/core/api/qwebenginewebauthuxrequest.cpp
@@ -0,0 +1,427 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebenginewebauthuxrequest.h"
+#include "qwebenginewebauthuxrequest_p.h"
+#include "authenticator_request_dialog_controller.h"
+
+/*!
+ \qmltype WebEngineWebAuthUxRequest
+ \instantiates QWebEngineWebAuthUxRequest
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 6.7
+ \brief Encapsulates the data of a WebAuth UX request.
+
+ Web engine's WebAuth UX requests are passed to the user in the
+ \l WebEngineView::webAuthUxRequested() signal.
+
+ For more information about how to handle web engine authenticator requests, see the
+ \l{WebEngine Quick Nano Browser}{Nano Browser}.
+*/
+
+/*!
+ \class QWebEngineWebAuthUxRequest
+ \brief The QWebEngineWebAuthUxRequest class encapsulates the data of a WebAuth UX request.
+ \since 6.7
+
+ \inmodule QtWebEngineCore
+
+ This class contains the information and API for WebAuth UX. WebAuth may require user
+ interaction during the authentication process. These requests are handled by displaying a
+ dialog to users. QtWebEngine currently supports user verification, resident credentials,
+ and display request failure UX requests.
+
+ QWebEngineWebAuthUxRequest models a WebAuth UX request throughout its life cycle,
+ starting with showing a UX dialog, updating it's content through state changes, and
+ finally closing the dialog.
+
+ WebAuth UX requests are normally triggered when the authenticator requires user interaction.
+ It is the QWebEnginePage's responsibility to notify the application of the new WebAuth UX
+ requests, which it does by emitting the
+ \l{QWebEnginePage::webAuthUxRequested}{webAuthUxRequested} signal together with a newly
+ created QWebEngineWebAuthUxRequest. The application can then examine this request and
+ display a WebAuth UX dialog.
+
+ The QWebEngineWebAuthUxRequest object periodically emits the \l
+ {QWebEngineWebAuthUxRequest::}{stateChanged} signal to notify potential
+ observers of the current WebAuth UX states. The observers update the WebAuth dialog
+ accordingly.
+
+ For more information about how to handle web engine authenticator requests, see the
+ \l{WebEngine Widgets Simple Browser Example}{Simple Browser}.
+*/
+
+/*!
+ \struct QWebEngineWebAuthPinRequest
+ \brief The QWebEngineWebAuthPinRequest class encapsulates the data of a PIN WebAuth UX request.
+ \since 6.7
+
+ \inmodule QtWebEngineCore
+
+ This encapsulates the following information related to a PIN request made by an authenticator.
+ \list
+ \li The reason for the PIN prompt.
+ \li The error details for the PIN prompt.
+ \li The number of attempts remaining before a hard lock. Should be ignored unless
+ \l{QWebEngineWebAuthPinRequest::reason} is
+ \l{QWebEngineWebAuthUxRequest::PinEntryReason::Challenge}.
+ \li The minimum PIN length the authenticator will accept for the PIN.
+ \endlist
+ Use this structure to update the WebAuth UX dialog when the WebAuth UX state is \l
+ QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin.
+*/
+
+/*!
+ \property QWebEngineWebAuthPinRequest::reason
+ \brief The reason for the PIN prompt.
+*/
+
+/*!
+ \property QWebEngineWebAuthPinRequest::error
+ \brief The error details for the PIN prompt.
+*/
+
+/*!
+ \property QWebEngineWebAuthPinRequest::remainingAttempts
+ \brief The number of attempts remaining before a hard lock. Should be ignored unless
+ \l{QWebEngineWebAuthPinRequest::reason} is
+ \l{QWebEngineWebAuthUxRequest::PinEntryReason::Challenge}.
+*/
+
+/*!
+ \property QWebEngineWebAuthPinRequest::minPinLength
+ \brief The minimum PIN length the authenticator will accept for the PIN.
+*/
+
+/*!
+ \enum QWebEngineWebAuthUxRequest::WebAuthUxState
+
+ This enum describes the state of the current WebAuth UX request.
+
+ \value NotStarted WebAuth UX request not started yet.
+ \value SelectAccount The authenticator requires resident credential details.
+ The application needs to display an account details dialog, and
+ the user needs to select an account to proceed.
+ \value CollectPin The authenticator requires user verification.
+ The application needs to display a PIN request dialog.
+ \value FinishTokenCollection The authenticator requires token/user verification (like tap on
+ the FIDO key) to complete the process.
+ \value RequestFailed WebAuth request failed. Display error details.
+ \value Cancelled WebAuth request is cancelled. Close the WebAuth dialog.
+ \value Completed WebAuth request is completed. Close the WebAuth dialog.
+*/
+
+/*!
+ \enum QWebEngineWebAuthUxRequest::PinEntryReason
+
+ This enum describes the reasons that may prompt the authenticator to ask for a PIN.
+
+ \value Set A new PIN is being set.
+ \value Change The existing PIN must be changed before using this authenticator.
+ \value Challenge The existing PIN is being collected to prove user verification.
+*/
+
+/*!
+ \enum QWebEngineWebAuthUxRequest::PinEntryError
+
+ This enum describes the errors that may prompt the authenticator to ask for a PIN.
+
+ \value NoError No error has occurred.
+ \value InternalUvLocked Internal UV is locked, so we are falling back to PIN.
+ \value WrongPin The PIN the user entered does not match the authenticator PIN.
+ \value TooShort The new PIN the user entered is too short.
+ \value InvalidCharacters The new PIN the user entered contains invalid characters.
+ \value SameAsCurrentPin The new PIN the user entered is the same as the currently set PIN.
+*/
+
+/*!
+ \enum QWebEngineWebAuthUxRequest::RequestFailureReason
+
+ This enum describes the reason for WebAuth request failure.
+
+ \value Timeout The authentication session has timed out.
+ \value KeyNotRegistered Key is not registered with the authenticator.
+ \value KeyAlreadyRegistered Key is already registered with the authenticator.
+ Try to register with another Key or use another authenticator.
+ \value SoftPinBlock The authenticator is blocked as the user entered the wrong key many times.
+ \value HardPinBlock The authenticator is blocked as the user entered the wrong key many times
+ and reset the PIN to use the specific authenticator again.
+ \value AuthenticatorRemovedDuringPinEntry Authenticator removed during PIN entry.
+ \value AuthenticatorMissingResidentKeys Authenticator doesn't have resident key support.
+ \value AuthenticatorMissingUserVerification Authenticator doesn't
+ have user verification support.
+ \value AuthenticatorMissingLargeBlob Authenticator doesn't have large blob support.
+ \value NoCommonAlgorithms No common algorithm.
+ \value StorageFull The resident credential could not be created because the
+ authenticator has insufficient storage.
+ \value UserConsentDenied User consent denied.
+ \value WinUserCancelled The user clicked \uicontrol Cancel in the native windows UI.
+*/
+
+/*!
+ \fn void QWebEngineWebAuthUxRequest::stateChanged(WebAuthUxState state)
+
+ This signal is emitted whenever the WebAuth UX's \a state changes.
+
+ \sa state, WebAuthUxState
+*/
+
+/*!
+ \qmlsignal void WebEngineWebAuthUxRequest::stateChanged(WebAuthUxState state)
+ This signal is emitted whenever the WebAuth UX's \a state changes.
+
+ \sa state, QWebEngineWebAuthUxRequest::WebAuthUxState
+*/
+
+/*! \internal
+ */
+QWebEngineWebAuthUxRequestPrivate::QWebEngineWebAuthUxRequestPrivate(
+ QtWebEngineCore::AuthenticatorRequestDialogController *controller)
+ : webAuthDialogController(controller)
+{
+ m_currentState = controller->state();
+}
+
+/*! \internal
+ */
+QWebEngineWebAuthUxRequestPrivate::~QWebEngineWebAuthUxRequestPrivate() { }
+
+/*! \internal
+ */
+QWebEngineWebAuthUxRequest::QWebEngineWebAuthUxRequest(QWebEngineWebAuthUxRequestPrivate *p)
+ : d_ptr(p)
+{
+ connect(d_ptr->webAuthDialogController,
+ &QtWebEngineCore::AuthenticatorRequestDialogController::stateChanged,
+ [this](WebAuthUxState currentState) {
+ Q_D(QWebEngineWebAuthUxRequest);
+ d->m_currentState = currentState;
+ Q_EMIT stateChanged(d->m_currentState);
+ });
+}
+
+/*! \internal
+ */
+QWebEngineWebAuthUxRequest::~QWebEngineWebAuthUxRequest() { }
+
+/*!
+ \qmlproperty stringlist WebEngineWebAuthUxRequest::userNames
+ \brief The available user names for the resident credential support.
+
+ This is needed when the current WebAuth request's UX state is
+ WebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount. The
+ WebAuth dialog displays user names. The user needs to select an
+ account to proceed.
+
+ \sa state setSelectedAccount() QWebEngineWebAuthUxRequest::userNames
+*/
+/*!
+ \property QWebEngineWebAuthUxRequest::userNames
+ \brief The available user names for the resident credential support.
+ This is needed when the current WebAuth request's UX state is \l SelectAccount.
+ The WebAuth dialog displays user names. The user needs to select an account to proceed.
+
+ \sa SelectAccount setSelectedAccount()
+*/
+QStringList QWebEngineWebAuthUxRequest::userNames() const
+{
+ const Q_D(QWebEngineWebAuthUxRequest);
+
+ return d->webAuthDialogController->userNames();
+}
+
+/*!
+ \qmlproperty string WebEngineWebAuthUxRequest::relyingPartyId
+ \brief The WebAuth request's relying party id.
+*/
+/*!
+ \property QWebEngineWebAuthUxRequest::relyingPartyId
+ \brief The WebAuth request's relying party id.
+*/
+QString QWebEngineWebAuthUxRequest::relyingPartyId() const
+{
+ const Q_D(QWebEngineWebAuthUxRequest);
+
+ return d->webAuthDialogController->relyingPartyId();
+}
+
+/*!
+ \qmlproperty QWebEngineWebAuthPinRequest WebEngineWebAuthUxRequest::pinRequest
+ \brief The WebAuth request's PIN request information.
+
+ \sa QWebEngineWebAuthPinRequest
+*/
+/*!
+ \property QWebEngineWebAuthUxRequest::pinRequest
+ \brief The WebAuth request's PIN request information.
+
+ This is needed when the current WebAuth request state is \l CollectPin.
+ WebAuth Dialog displays a PIN request dialog. The user needs to enter a PIN and
+ invoke \l setPin() to proceed.
+
+ \sa QWebEngineWebAuthPinRequest CollectPin setPin()
+*/
+QWebEngineWebAuthPinRequest QWebEngineWebAuthUxRequest::pinRequest() const
+{
+ const Q_D(QWebEngineWebAuthUxRequest);
+
+ return d->webAuthDialogController->pinRequest();
+}
+
+/*!
+ \qmlproperty enumeration WebEngineWebAuthUxRequest::state
+ \brief The WebAuth request's current UX state.
+
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.NotStarted WebAuth UX request not started yet.
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount The authenticator requires
+ resident credential details. The application needs to display an account details dialog,
+ and the user needs to select an account to proceed.
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin The authenticator requires user verification.
+ The application needs to display a PIN request dialog.
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.FinishTokenCollection The authenticator requires
+ token/user verification (like tap on the FIDO key) to complete the process.
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.RequestFailed WebAuth request failed. Display error details.
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.Cancelled WebAuth request is cancelled.
+ Close the WebAuth dialog.
+ \value WebEngineWebAuthUxRequest.WebAuthUxState.Completed WebAuth request is completed.
+ Close the WebAuth dialog.
+*/
+/*!
+ \property QWebEngineWebAuthUxRequest::state
+ \brief The WebAuth request's current UX state.
+
+ \l stateChanged() is emitted when the current state changes.
+ Update the WebAuth dialog in reponse to the changes in state.
+*/
+QWebEngineWebAuthUxRequest::WebAuthUxState QWebEngineWebAuthUxRequest::state() const
+{
+ return d_ptr->m_currentState;
+}
+
+/*!
+ \qmlmethod void WebEngineWebAuthUxRequest::setSelectedAccount(const QString &selectedAccount)
+
+ Sends the \a selectedAccount name to the authenticator.
+ This is needed when the current WebAuth request's UX state is
+ WebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount. The
+ WebAuth request is blocked until the user selects an account and
+ invokes this method.
+
+ \sa WebEngineWebAuthUxRequest::userNames state
+*/
+/*!
+ Sends the \a selectedAccount name to the authenticator.
+ This is needed when the current WebAuth request's UX state is \l SelectAccount.
+ The WebAuth request is blocked until the user selects an account and invokes this method.
+
+ \sa userNames SelectAccount
+*/
+void QWebEngineWebAuthUxRequest::setSelectedAccount(const QString &selectedAccount)
+{
+ Q_D(QWebEngineWebAuthUxRequest);
+
+ d->webAuthDialogController->sendSelectAccountResponse(selectedAccount);
+}
+
+/*!
+ \qmlmethod void WebEngineWebAuthUxRequest::setPin(const QString &pin)
+ Sends the \a pin to the authenticator that prompts for a PIN.
+ This is needed when the current WebAuth request's UX state is
+ WebEngineWebAuthUxRequest.WebAuthUxState.CollectPin. The WebAuth
+ request is blocked until the user responds with a PIN.
+
+ \sa QWebEngineWebAuthPinRequest state
+*/
+/*!
+ Sends the \a pin to the authenticator that prompts for a PIN.
+ This is needed when the current WebAuth request's UX state is \l CollectPin.
+ The WebAuth request is blocked until the user responds with a PIN.
+
+ \sa QWebEngineWebAuthPinRequest CollectPin
+*/
+void QWebEngineWebAuthUxRequest::setPin(const QString &pin)
+{
+ Q_D(QWebEngineWebAuthUxRequest);
+ d->webAuthDialogController->sendCollectPinResponse(pin);
+}
+
+/*!
+ \qmlmethod void WebEngineWebAuthUxRequest::cancel()
+ Cancels the current WebAuth request.
+
+ \sa QWebEngineWebAuthUxRequest::Cancelled, WebEngineWebAuthUxRequest::stateChanged()
+*/
+/*!
+ Cancels the current WebAuth request.
+
+ \sa QWebEngineWebAuthUxRequest::Cancelled, stateChanged()
+*/
+void QWebEngineWebAuthUxRequest::cancel()
+{
+ Q_D(QWebEngineWebAuthUxRequest);
+
+ d->webAuthDialogController->reject();
+}
+
+/*!
+ \qmlmethod void WebEngineWebAuthUxRequest::retry()
+ Retries the current WebAuth request.
+
+ \sa stateChanged()
+*/
+/*!
+ Retries the current WebAuth request.
+
+ \sa stateChanged()
+*/
+void QWebEngineWebAuthUxRequest::retry()
+{
+ const Q_D(QWebEngineWebAuthUxRequest);
+
+ d->webAuthDialogController->retryRequest();
+}
+
+/*!
+ \qmlproperty enumeration WebEngineWebAuthUxRequest::requestFailureReason
+ \brief The WebAuth request's failure reason.
+
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.Timeout The authentication session has timed out.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.KeyNotRegistered Key is not registered with the authenticator.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.KeyAlreadyRegistered Key is already registered with
+ the authenticator. Try to register with another key or use another authenticator.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.SoftPinBlock The authenticator is blocked as the user
+ entered the wrong key many times.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.HardPinBlock The authenticator is blocked as the user entered
+ the wrong key many times and reset the PIN to use the specific authenticator again.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorRemovedDuringPinEntry Authenticator
+ removed during PIN entry.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingResidentKeys Authenticator doesn't
+ have resident key support.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingUserVerification Authenticator doesn't
+ have user verification support.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingLargeBlob Authenticator doesn't have
+ large blob support.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.NoCommonAlgorithms No common algorithm.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.StorageFull The resident credential could not be created
+ because the authenticator has insufficient storage.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.UserConsentDenied User consent denied.
+ \value WebEngineWebAuthUxRequest.RequestFailureReason.WinUserCancelled The user clicked \uicontrol Cancel
+ in the native windows UI.
+
+ \sa stateChanged()
+*/
+/*!
+ \property QWebEngineWebAuthUxRequest::requestFailureReason
+ \brief The WebAuth request's failure reason.
+
+ \sa stateChanged() QWebEngineWebAuthUxRequest::RequestFailureReason
+*/
+QWebEngineWebAuthUxRequest::RequestFailureReason
+QWebEngineWebAuthUxRequest::requestFailureReason() const
+{
+ const Q_D(QWebEngineWebAuthUxRequest);
+
+ return d->webAuthDialogController->requestFailureReason();
+}
+
+#include "moc_qwebenginewebauthuxrequest.cpp"
diff --git a/src/core/api/qwebenginewebauthuxrequest.h b/src/core/api/qwebenginewebauthuxrequest.h
new file mode 100644
index 000000000..111f52847
--- /dev/null
+++ b/src/core/api/qwebenginewebauthuxrequest.h
@@ -0,0 +1,117 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEWEBAUTHUXREQUEST_H
+#define QWEBENGINEWEBAUTHUXREQUEST_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtCore/qobject.h>
+
+namespace QtWebEngineCore {
+class AuthenticatorRequestDialogControllerPrivate;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineWebAuthUxRequestPrivate;
+struct QWebEngineWebAuthPinRequest;
+
+class Q_WEBENGINECORE_EXPORT QWebEngineWebAuthUxRequest : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QStringList userNames READ userNames CONSTANT FINAL)
+ Q_PROPERTY(WebAuthUxState state READ state NOTIFY stateChanged FINAL)
+ Q_PROPERTY(QString relyingPartyId READ relyingPartyId CONSTANT FINAL)
+ Q_PROPERTY(QWebEngineWebAuthPinRequest pinRequest READ pinRequest CONSTANT FINAL)
+ Q_PROPERTY(RequestFailureReason requestFailureReason READ requestFailureReason CONSTANT FINAL)
+ Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
+public:
+ enum class WebAuthUxState {
+ NotStarted,
+ SelectAccount,
+ CollectPin,
+ FinishTokenCollection,
+ RequestFailed,
+ Cancelled,
+ Completed,
+ };
+ Q_ENUM(WebAuthUxState)
+
+ enum class PinEntryReason {
+ Set,
+ Change,
+ Challenge,
+ };
+ Q_ENUM(PinEntryReason)
+
+ enum class PinEntryError {
+ NoError,
+ InternalUvLocked,
+ WrongPin,
+ TooShort,
+ InvalidCharacters,
+ SameAsCurrentPin,
+ };
+ Q_ENUM(PinEntryError)
+
+ enum class RequestFailureReason {
+ Timeout,
+ KeyNotRegistered,
+ KeyAlreadyRegistered,
+ SoftPinBlock,
+ HardPinBlock,
+ AuthenticatorRemovedDuringPinEntry,
+ AuthenticatorMissingResidentKeys,
+ AuthenticatorMissingUserVerification,
+ AuthenticatorMissingLargeBlob,
+ NoCommonAlgorithms,
+ StorageFull,
+ UserConsentDenied,
+ WinUserCancelled,
+ };
+ Q_ENUM(RequestFailureReason)
+
+ ~QWebEngineWebAuthUxRequest() override;
+
+ QStringList userNames() const;
+ QString relyingPartyId() const;
+ QWebEngineWebAuthPinRequest pinRequest() const;
+ WebAuthUxState state() const;
+ RequestFailureReason requestFailureReason() const;
+
+Q_SIGNALS:
+ void stateChanged(QWebEngineWebAuthUxRequest::WebAuthUxState state);
+
+public Q_SLOTS:
+ void cancel();
+ void retry();
+ void setSelectedAccount(const QString &selectedAccount);
+ void setPin(const QString &pin);
+
+protected:
+ explicit QWebEngineWebAuthUxRequest(QWebEngineWebAuthUxRequestPrivate *);
+
+ std::unique_ptr<QWebEngineWebAuthUxRequestPrivate> d_ptr;
+ friend class QtWebEngineCore::AuthenticatorRequestDialogControllerPrivate;
+ Q_DECLARE_PRIVATE(QWebEngineWebAuthUxRequest)
+};
+
+struct QWebEngineWebAuthPinRequest
+{
+ Q_GADGET_EXPORT(Q_WEBENGINECORE_EXPORT)
+
+ Q_PROPERTY(QWebEngineWebAuthUxRequest::PinEntryReason reason MEMBER reason CONSTANT FINAL)
+ Q_PROPERTY(QWebEngineWebAuthUxRequest::PinEntryError error MEMBER error CONSTANT FINAL)
+ Q_PROPERTY(qint32 minPinLength MEMBER minPinLength CONSTANT FINAL)
+ Q_PROPERTY(int remainingAttempts MEMBER remainingAttempts CONSTANT FINAL)
+public:
+ QWebEngineWebAuthUxRequest::PinEntryReason reason;
+ QWebEngineWebAuthUxRequest::PinEntryError error;
+ qint32 minPinLength;
+ int remainingAttempts;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEWEBAUTHUXREQUEST_H
diff --git a/src/core/api/qwebenginewebauthuxrequest_p.h b/src/core/api/qwebenginewebauthuxrequest_p.h
new file mode 100644
index 000000000..4c685bac7
--- /dev/null
+++ b/src/core/api/qwebenginewebauthuxrequest_p.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINEWEBAUTHUXREQUEST_P_H
+#define QWEBENGINEWEBAUTHUXREQUEST_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 "qwebenginewebauthuxrequest.h"
+#include <QtCore/QSharedPointer>
+
+namespace QtWebEngineCore {
+class WebContentsAdapterClient;
+class AuthenticatorRequestDialogController;
+}
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINECORE_EXPORT QWebEngineWebAuthUxRequestPrivate
+{
+
+public:
+ QWebEngineWebAuthUxRequestPrivate(
+ QtWebEngineCore::AuthenticatorRequestDialogController *controller);
+ ~QWebEngineWebAuthUxRequestPrivate();
+
+ QWebEngineWebAuthUxRequest::WebAuthUxState m_currentState =
+ QWebEngineWebAuthUxRequest::WebAuthUxState::NotStarted;
+ QtWebEngineCore::AuthenticatorRequestDialogController *webAuthDialogController;
+};
+
+QT_END_NAMESPACE
+#endif // QWEBENGINEWEBAUTHUXREQUEST_P_H
diff --git a/src/core/authentication_dialog_controller.cpp b/src/core/authentication_dialog_controller.cpp
index e37ffab44..4efd5dad3 100644
--- a/src/core/authentication_dialog_controller.cpp
+++ b/src/core/authentication_dialog_controller.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "authentication_dialog_controller.h"
#include "authentication_dialog_controller_p.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browser_task_traits.h"
@@ -53,7 +16,7 @@ AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(bas
void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted, const QString &user, const QString &password)
{
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&LoginDelegateQt::sendAuthToRequester,
loginDelegate, accepted, user, password));
}
diff --git a/src/core/authentication_dialog_controller.h b/src/core/authentication_dialog_controller.h
index ef2f2c724..944ec4d15 100644
--- a/src/core/authentication_dialog_controller.h
+++ b/src/core/authentication_dialog_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -58,7 +22,7 @@ namespace QtWebEngineCore {
class AuthenticationDialogControllerPrivate;
-class Q_WEBENGINECORE_PRIVATE_EXPORT AuthenticationDialogController : public QObject {
+class Q_WEBENGINECORE_EXPORT AuthenticationDialogController : public QObject {
Q_OBJECT
public:
~AuthenticationDialogController();
diff --git a/src/core/authentication_dialog_controller_p.h b/src/core/authentication_dialog_controller_p.h
index 1abff576d..6c35a60dc 100644
--- a/src/core/authentication_dialog_controller_p.h
+++ b/src/core/authentication_dialog_controller_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef AUTHENTICATION_DIALOG_CONTROLLER_P_H
#define AUTHENTICATION_DIALOG_CONTROLLER_P_H
diff --git a/src/core/authenticator_request_client_delegate_qt.cpp b/src/core/authenticator_request_client_delegate_qt.cpp
new file mode 100644
index 000000000..5f9fd9ca3
--- /dev/null
+++ b/src/core/authenticator_request_client_delegate_qt.cpp
@@ -0,0 +1,247 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "authenticator_request_client_delegate_qt.h"
+#include "authenticator_request_dialog_controller.h"
+#include "authenticator_request_dialog_controller_p.h"
+#include "base/base64.h"
+#include "profile_adapter_client.h"
+#include "profile_qt.h"
+#include "content/public/browser/web_contents.h"
+#include "web_contents_delegate_qt.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+using RequestFailureReason = QWebEngineWebAuthUxRequest::RequestFailureReason;
+
+WebAuthenticationDelegateQt::WebAuthenticationDelegateQt() = default;
+
+WebAuthenticationDelegateQt::~WebAuthenticationDelegateQt() = default;
+
+bool WebAuthenticationDelegateQt::SupportsResidentKeys(content::RenderFrameHost *render_frame_host)
+{
+ return true;
+}
+
+AuthenticatorRequestClientDelegateQt::AuthenticatorRequestClientDelegateQt(
+ content::RenderFrameHost *render_frame_host)
+ : m_renderFrameHost(render_frame_host), m_weakFactory(this)
+{
+ m_dialogController.reset(new AuthenticatorRequestDialogController(
+ new AuthenticatorRequestDialogControllerPrivate(m_renderFrameHost,
+ m_weakFactory.GetWeakPtr())));
+}
+
+AuthenticatorRequestClientDelegateQt::~AuthenticatorRequestClientDelegateQt()
+{
+ // Currently WebAuth request is completed. Now it is possible to delete the dialog if displayed
+ m_dialogController->finishRequest();
+}
+
+void AuthenticatorRequestClientDelegateQt::SetRelyingPartyId(const std::string &rp_id)
+{
+ m_dialogController->setRelyingPartyId(rp_id);
+}
+
+bool AuthenticatorRequestClientDelegateQt::DoesBlockRequestOnFailure(
+ InterestingFailureReason reason)
+{
+ if (!IsWebAuthnUIEnabled())
+ return false;
+
+ switch (reason) {
+ case InterestingFailureReason::kTimeout:
+ m_dialogController->handleRequestFailure(RequestFailureReason::Timeout);
+ break;
+ case InterestingFailureReason::kAuthenticatorMissingResidentKeys:
+ m_dialogController->handleRequestFailure(
+ RequestFailureReason::AuthenticatorMissingResidentKeys);
+ break;
+ case InterestingFailureReason::kAuthenticatorMissingUserVerification:
+ m_dialogController->handleRequestFailure(
+ RequestFailureReason::AuthenticatorMissingUserVerification);
+ break;
+ case InterestingFailureReason::kAuthenticatorMissingLargeBlob:
+ m_dialogController->handleRequestFailure(
+ RequestFailureReason::AuthenticatorMissingLargeBlob);
+ break;
+ case InterestingFailureReason::kAuthenticatorRemovedDuringPINEntry:
+ m_dialogController->handleRequestFailure(
+ RequestFailureReason::AuthenticatorRemovedDuringPinEntry);
+ break;
+ case InterestingFailureReason::kHardPINBlock:
+ m_dialogController->handleRequestFailure(RequestFailureReason::HardPinBlock);
+ break;
+ case InterestingFailureReason::kSoftPINBlock:
+ m_dialogController->handleRequestFailure(RequestFailureReason::SoftPinBlock);
+ break;
+ case InterestingFailureReason::kKeyAlreadyRegistered:
+ m_dialogController->handleRequestFailure(RequestFailureReason::KeyAlreadyRegistered);
+ break;
+ case InterestingFailureReason::kKeyNotRegistered:
+ m_dialogController->handleRequestFailure(RequestFailureReason::KeyNotRegistered);
+ break;
+ case InterestingFailureReason::kNoCommonAlgorithms:
+ m_dialogController->handleRequestFailure(RequestFailureReason::NoCommonAlgorithms);
+ break;
+ case InterestingFailureReason::kStorageFull:
+ m_dialogController->handleRequestFailure(RequestFailureReason::StorageFull);
+ break;
+ case InterestingFailureReason::kUserConsentDenied:
+ m_dialogController->handleRequestFailure(RequestFailureReason::UserConsentDenied);
+ break;
+ case InterestingFailureReason::kWinUserCancelled:
+#if BUILDFLAG(IS_WIN)
+ m_dialogController->handleRequestFailure(RequestFailureReason::WinUserCancelled);
+#else
+ return false;
+#endif
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+void AuthenticatorRequestClientDelegateQt::RegisterActionCallbacks(
+ base::OnceClosure cancel_callback, base::RepeatingClosure start_over_callback,
+ AccountPreselectedCallback account_preselected_callback,
+ device::FidoRequestHandlerBase::RequestCallback request_callback,
+ base::RepeatingClosure bluetooth_adapter_power_on_callback)
+{
+ m_cancelCallback = std::move(cancel_callback);
+ m_startOverCallback = std::move(start_over_callback);
+ m_accountPreselectedCallback = std::move(account_preselected_callback);
+ m_requestCallback = std::move(request_callback);
+ m_bluetoothAdapterPowerOnCallback = std::move(bluetooth_adapter_power_on_callback);
+}
+
+void AuthenticatorRequestClientDelegateQt::ShouldReturnAttestation(
+ const std::string &relying_party_id, const device::FidoAuthenticator *authenticator,
+ bool is_enterprise_attestation, base::OnceCallback<void(bool)> callback)
+{
+ std::move(callback).Run(!is_enterprise_attestation);
+}
+
+void AuthenticatorRequestClientDelegateQt::SelectAccount(
+ std::vector<device::AuthenticatorGetAssertionResponse> responses,
+ base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)> callback)
+{
+ if (m_isUiDisabled) {
+ // Requests with UI disabled should never reach account selection.
+ DCHECK(IsVirtualEnvironmentEnabled());
+ std::move(callback).Run(std::move(responses.at(0)));
+ return;
+ }
+
+ if (m_isConditionalRequest) {
+ return;
+ }
+
+ m_authenticatorGetAssertionResponse = std::move(responses);
+ m_selectAccountCallback = std::move(callback);
+
+ QStringList userList;
+ int nIndex = -1;
+ for (const auto &response : m_authenticatorGetAssertionResponse) {
+ nIndex++;
+ const auto &user_entity = response.user_entity;
+ const bool has_user_identifying_info = user_entity && user_entity->name;
+ if (has_user_identifying_info) {
+ QString userName = toQt(*response.user_entity->name);
+ m_userMap[userName] = nIndex;
+ userList.append(userName);
+ }
+ }
+ m_dialogController->selectAccount(userList);
+}
+
+void AuthenticatorRequestClientDelegateQt::DisableUI()
+{
+ m_isUiDisabled = true;
+}
+
+bool AuthenticatorRequestClientDelegateQt::IsWebAuthnUIEnabled()
+{
+ return !m_isUiDisabled;
+}
+
+void AuthenticatorRequestClientDelegateQt::SetConditionalRequest(bool is_conditional)
+{
+ m_isConditionalRequest = is_conditional;
+}
+
+// This method will not be invoked until the observer is set.
+void AuthenticatorRequestClientDelegateQt::OnTransportAvailabilityEnumerated(
+ device::FidoRequestHandlerBase::TransportAvailabilityInfo data)
+{
+ // Show dialog only after this step;
+ // If m_isUiDisabled is set or another UI request in progress return
+ if (m_isUiDisabled
+ || m_dialogController->state() != QWebEngineWebAuthUxRequest::WebAuthUxState::NotStarted)
+ return;
+
+ // Start WebAuth UX
+ // we may need to pass data as well. for SelectAccount and SupportPin it is not required,
+ // skipping that for the timebeing.
+ m_dialogController->startRequest(m_isConditionalRequest);
+}
+
+bool AuthenticatorRequestClientDelegateQt::SupportsPIN() const
+{
+ return true;
+}
+
+void AuthenticatorRequestClientDelegateQt::CollectPIN(
+ CollectPINOptions options, base::OnceCallback<void(std::u16string)> provide_pin_cb)
+{
+
+ m_providePinCallback = std::move(provide_pin_cb);
+ QWebEngineWebAuthPinRequest pinRequestInfo;
+
+ pinRequestInfo.reason = static_cast<QWebEngineWebAuthUxRequest::PinEntryReason>(options.reason);
+ pinRequestInfo.error = static_cast<QWebEngineWebAuthUxRequest::PinEntryError>(options.error);
+ pinRequestInfo.remainingAttempts = options.attempts;
+ pinRequestInfo.minPinLength = options.min_pin_length;
+ m_dialogController->collectPin(pinRequestInfo);
+}
+
+void AuthenticatorRequestClientDelegateQt::FinishCollectToken()
+{
+ m_dialogController->finishCollectToken();
+}
+
+void AuthenticatorRequestClientDelegateQt::onCancelRequest()
+{
+ if (!m_cancelCallback)
+ return;
+
+ std::move(m_cancelCallback).Run();
+}
+
+void AuthenticatorRequestClientDelegateQt::onSelectAccount(const QString &selectedAccount)
+{
+ if (!m_selectAccountCallback)
+ return;
+
+ if (m_userMap.find(selectedAccount) != m_userMap.end()) {
+ std::move(m_selectAccountCallback)
+ .Run(std::move(m_authenticatorGetAssertionResponse.at(m_userMap[selectedAccount])));
+ } else {
+ onCancelRequest();
+ }
+}
+
+void AuthenticatorRequestClientDelegateQt::onCollectPin(const QString &pin)
+{
+ if (!m_providePinCallback)
+ return;
+ std::move(m_providePinCallback).Run(pin.toStdU16String());
+}
+
+void AuthenticatorRequestClientDelegateQt::onRetryRequest()
+{
+ DCHECK(m_startOverCallback);
+ m_startOverCallback.Run();
+}
+}
diff --git a/src/core/authenticator_request_client_delegate_qt.h b/src/core/authenticator_request_client_delegate_qt.h
new file mode 100644
index 000000000..05c6136bd
--- /dev/null
+++ b/src/core/authenticator_request_client_delegate_qt.h
@@ -0,0 +1,96 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_QT_H
+#define AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_QT_H
+
+#include "qtwebenginecoreglobal_p.h"
+#include "content/public/browser/authenticator_request_client_delegate.h"
+#include <unordered_map>
+#include <QSharedPointer>
+
+namespace QtWebEngineCore {
+
+class AuthenticatorRequestDialogController;
+
+class WebAuthenticationDelegateQt : public content::WebAuthenticationDelegate
+{
+public:
+ WebAuthenticationDelegateQt();
+ virtual ~WebAuthenticationDelegateQt();
+
+ bool SupportsResidentKeys(content::RenderFrameHost *render_frame_host) override;
+};
+
+class AuthenticatorRequestClientDelegateQt : public content::AuthenticatorRequestClientDelegate
+{
+public:
+ explicit AuthenticatorRequestClientDelegateQt(content::RenderFrameHost *render_frame_host);
+ AuthenticatorRequestClientDelegateQt(const AuthenticatorRequestClientDelegateQt &) = delete;
+ AuthenticatorRequestClientDelegateQt &
+ operator=(const AuthenticatorRequestClientDelegateQt &) = delete;
+ ~AuthenticatorRequestClientDelegateQt();
+
+ // content::AuthenticatorRequestClientDelegate ovverrides
+ void SetRelyingPartyId(const std::string &rp_id) override;
+ bool DoesBlockRequestOnFailure(InterestingFailureReason reason) override;
+ void RegisterActionCallbacks(base::OnceClosure cancel_callback,
+ base::RepeatingClosure start_over_callback,
+ AccountPreselectedCallback account_preselected_callback,
+ device::FidoRequestHandlerBase::RequestCallback request_callback,
+ base::RepeatingClosure bluetooth_adapter_power_on_callback) override;
+ void ShouldReturnAttestation(const std::string &relying_party_id,
+ const device::FidoAuthenticator *authenticator,
+ bool is_enterprise_attestation,
+ base::OnceCallback<void(bool)> callback) override;
+ void SelectAccount(
+ std::vector<device::AuthenticatorGetAssertionResponse> responses,
+ base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)> callback) override;
+ void DisableUI() override;
+ bool IsWebAuthnUIEnabled() override;
+ void SetConditionalRequest(bool is_conditional) override;
+
+ // device::FidoRequestHandlerBase::Observer overrides:
+ // This method will not be invoked until the observer is set.
+ void OnTransportAvailabilityEnumerated(
+ device::FidoRequestHandlerBase::TransportAvailabilityInfo data) override;
+
+ bool SupportsPIN() const override;
+ void CollectPIN(CollectPINOptions options,
+ base::OnceCallback<void(std::u16string)> provide_pin_cb) override;
+ void FinishCollectToken() override;
+
+ // Dialog helper
+ void onCancelRequest();
+ void onSelectAccount(const QString &selectedAccount);
+ void onCollectPin(const QString &pin);
+ void onRetryRequest();
+
+private:
+ content::RenderFrameHost *m_renderFrameHost;
+ bool m_isUiDisabled = false;
+ bool m_isConditionalRequest = false;
+
+ base::OnceClosure m_cancelCallback;
+ base::RepeatingClosure m_startOverCallback;
+ AccountPreselectedCallback m_accountPreselectedCallback;
+ device::FidoRequestHandlerBase::RequestCallback m_requestCallback;
+ base::RepeatingClosure m_bluetoothAdapterPowerOnCallback;
+
+ // Select account details;
+ std::vector<device::AuthenticatorGetAssertionResponse> m_authenticatorGetAssertionResponse;
+ std::unordered_map<QString, int> m_userMap;
+ base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)> m_selectAccountCallback;
+
+ // collect pin
+ base::OnceCallback<void(std::u16string)> m_providePinCallback;
+
+ // This member is used to keep authenticator request dialog controller alive until
+ // authenticator request is completed or cancelled.
+ QSharedPointer<AuthenticatorRequestDialogController> m_dialogController;
+ base::WeakPtrFactory<AuthenticatorRequestClientDelegateQt> m_weakFactory;
+};
+
+}
+
+#endif // AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_QT_H
diff --git a/src/core/authenticator_request_dialog_controller.cpp b/src/core/authenticator_request_dialog_controller.cpp
new file mode 100644
index 000000000..73fb4e7f3
--- /dev/null
+++ b/src/core/authenticator_request_dialog_controller.cpp
@@ -0,0 +1,302 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "authenticator_request_dialog_controller.h"
+#include "authenticator_request_dialog_controller_p.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "web_contents_delegate_qt.h"
+#include "qwebenginewebauthuxrequest_p.h"
+#include "qwebenginewebauthuxrequest.h"
+
+using PinEntryError = QWebEngineWebAuthUxRequest::PinEntryError;
+using PinEntryReason = QWebEngineWebAuthUxRequest::PinEntryReason;
+using WebAuthUxState = QWebEngineWebAuthUxRequest::WebAuthUxState;
+
+namespace QtWebEngineCore {
+
+ASSERT_ENUMS_MATCH(PinEntryReason::Set, device::pin::PINEntryReason::kSet)
+ASSERT_ENUMS_MATCH(PinEntryReason::Change, device::pin::PINEntryReason::kChange)
+ASSERT_ENUMS_MATCH(PinEntryReason::Challenge, device::pin::PINEntryReason::kChallenge)
+ASSERT_ENUMS_MATCH(PinEntryError::WrongPin, device::pin::PINEntryError::kWrongPIN)
+ASSERT_ENUMS_MATCH(PinEntryError::TooShort, device::pin::PINEntryError::kTooShort)
+ASSERT_ENUMS_MATCH(PinEntryError::SameAsCurrentPin, device::pin::PINEntryError::kSameAsCurrentPIN)
+ASSERT_ENUMS_MATCH(PinEntryError::NoError, device::pin::PINEntryError::kNoError)
+ASSERT_ENUMS_MATCH(PinEntryError::InvalidCharacters, device::pin::PINEntryError::kInvalidCharacters)
+ASSERT_ENUMS_MATCH(PinEntryError::InternalUvLocked, device::pin::PINEntryError::kInternalUvLocked)
+
+AuthenticatorRequestDialogControllerPrivate::AuthenticatorRequestDialogControllerPrivate(
+ content::RenderFrameHost *renderFrameHost,
+ base::WeakPtr<AuthenticatorRequestClientDelegateQt> authenticatorRequestDelegate)
+ : m_renderFrameHost(renderFrameHost)
+ , m_authenticatorRequestDelegate(authenticatorRequestDelegate)
+{
+}
+
+AuthenticatorRequestDialogControllerPrivate::~AuthenticatorRequestDialogControllerPrivate()
+{
+ if (m_request) {
+ delete m_request;
+ m_request = nullptr;
+ }
+}
+
+void AuthenticatorRequestDialogControllerPrivate::showWebAuthDialog()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ content::WebContents *webContent = content::WebContents::FromRenderFrameHost(m_renderFrameHost);
+
+ if (!webContent)
+ return;
+
+ WebContentsAdapterClient *adapterClient = nullptr;
+ if (webContent)
+ adapterClient =
+ static_cast<WebContentsDelegateQt *>(webContent->GetDelegate())->adapterClient();
+
+ if (adapterClient) {
+
+ QWebEngineWebAuthUxRequestPrivate *itemPrivate =
+ new QWebEngineWebAuthUxRequestPrivate(q_ptr);
+
+ m_request = new QWebEngineWebAuthUxRequest(itemPrivate);
+
+ adapterClient->showWebAuthDialog(m_request);
+ m_isDialogCreated = true;
+ } else {
+ cancelRequest();
+ }
+}
+
+void AuthenticatorRequestDialogControllerPrivate::selectAccount(const QStringList &userList)
+{
+ m_userList.clear();
+ m_userList = userList;
+ setCurrentState(WebAuthUxState::SelectAccount);
+}
+
+void AuthenticatorRequestDialogControllerPrivate::collectPin(QWebEngineWebAuthPinRequest pinRequest)
+{
+ m_pinRequest = pinRequest;
+ setCurrentState(WebAuthUxState::CollectPin);
+}
+
+void AuthenticatorRequestDialogControllerPrivate::finishCollectToken()
+{
+ setCurrentState(WebAuthUxState::FinishTokenCollection);
+}
+
+QStringList AuthenticatorRequestDialogControllerPrivate::userNames() const
+{
+ return m_userList;
+}
+
+void AuthenticatorRequestDialogControllerPrivate::finishRequest()
+{
+ if (!m_isDialogCreated)
+ return;
+ setCurrentState(WebAuthUxState::Completed);
+}
+
+void AuthenticatorRequestDialogControllerPrivate::setCurrentState(
+ QWebEngineWebAuthUxRequest::WebAuthUxState uxState)
+{
+ if (!m_isStarted) {
+ // Dialog isn't showing yet. Remember to show this step when it appears.
+ m_pendingState = uxState;
+ return;
+ }
+
+ m_currentState = uxState;
+
+ if (m_isConditionalRequest)
+ return;
+
+ if (!m_isDialogCreated) {
+ showWebAuthDialog();
+ } else {
+ Q_EMIT q_ptr->stateChanged(m_currentState);
+
+ if (m_currentState == QWebEngineWebAuthUxRequest::WebAuthUxState::Cancelled
+ || m_currentState == QWebEngineWebAuthUxRequest::WebAuthUxState::Completed) {
+ m_isDialogCreated = false;
+ }
+ }
+}
+
+void AuthenticatorRequestDialogControllerPrivate::cancelRequest()
+{
+ setCurrentState(WebAuthUxState::Cancelled);
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&AuthenticatorRequestClientDelegateQt::onCancelRequest,
+ m_authenticatorRequestDelegate));
+}
+
+void AuthenticatorRequestDialogControllerPrivate::retryRequest()
+{
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&AuthenticatorRequestClientDelegateQt::onRetryRequest,
+ m_authenticatorRequestDelegate));
+}
+
+void AuthenticatorRequestDialogControllerPrivate::sendSelectAccountResponse(
+ const QString &selectedAccount)
+{
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&AuthenticatorRequestClientDelegateQt::onSelectAccount,
+ m_authenticatorRequestDelegate, selectedAccount));
+}
+
+QWebEngineWebAuthUxRequest::WebAuthUxState
+AuthenticatorRequestDialogControllerPrivate::state() const
+{
+ return m_currentState;
+}
+
+void AuthenticatorRequestDialogControllerPrivate::startRequest(bool isConditionalRequest)
+{
+ DCHECK(!m_isStarted);
+
+ m_isStarted = true;
+ m_isConditionalRequest = isConditionalRequest;
+
+ if (m_pendingState) {
+ setCurrentState(*m_pendingState);
+ m_pendingState.reset();
+ }
+}
+
+void AuthenticatorRequestDialogControllerPrivate::setRelyingPartyId(const QString &rpId)
+{
+ m_relyingPartyId = rpId;
+}
+
+QString AuthenticatorRequestDialogControllerPrivate::relyingPartyId() const
+{
+ return m_relyingPartyId;
+}
+
+QWebEngineWebAuthPinRequest AuthenticatorRequestDialogControllerPrivate::pinRequest()
+{
+ return m_pinRequest;
+}
+
+void AuthenticatorRequestDialogControllerPrivate::handleRequestFailure(
+ QWebEngineWebAuthUxRequest::RequestFailureReason reason)
+{
+ m_requestFailureReason = reason;
+ setCurrentState(WebAuthUxState::RequestFailed);
+}
+
+void AuthenticatorRequestDialogControllerPrivate::sendCollectPinResponse(const QString &pin)
+{
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&AuthenticatorRequestClientDelegateQt::onCollectPin,
+ m_authenticatorRequestDelegate, pin));
+}
+
+QWebEngineWebAuthUxRequest::RequestFailureReason
+AuthenticatorRequestDialogControllerPrivate::requestFailureReason() const
+{
+ return m_requestFailureReason;
+}
+
+AuthenticatorRequestDialogController::AuthenticatorRequestDialogController(
+ AuthenticatorRequestDialogControllerPrivate *dd)
+{
+ Q_ASSERT(dd);
+ d_ptr.reset(dd);
+ d_ptr->q_ptr = this;
+}
+
+AuthenticatorRequestDialogController::~AuthenticatorRequestDialogController() { }
+
+void AuthenticatorRequestDialogController::selectAccount(const QStringList &userList)
+{
+ d_ptr->selectAccount(userList);
+}
+
+void AuthenticatorRequestDialogController::collectPin(QWebEngineWebAuthPinRequest pinRequest)
+{
+ d_ptr->collectPin(pinRequest);
+}
+
+QStringList AuthenticatorRequestDialogController::userNames() const
+{
+ return d_ptr->userNames();
+}
+
+QWebEngineWebAuthPinRequest AuthenticatorRequestDialogController::pinRequest()
+{
+ return d_ptr->pinRequest();
+}
+
+void AuthenticatorRequestDialogController::reject()
+{
+ d_ptr->cancelRequest();
+}
+
+void AuthenticatorRequestDialogController::sendSelectAccountResponse(const QString &account)
+{
+ d_ptr->sendSelectAccountResponse(account);
+}
+
+void AuthenticatorRequestDialogController::finishCollectToken()
+{
+ d_ptr->finishCollectToken();
+}
+
+void AuthenticatorRequestDialogController::finishRequest()
+{
+ d_ptr->finishRequest();
+}
+
+QWebEngineWebAuthUxRequest::WebAuthUxState AuthenticatorRequestDialogController::state() const
+{
+ return d_ptr->state();
+}
+
+void AuthenticatorRequestDialogController::startRequest(bool bIsConditionalRequest)
+{
+ d_ptr->startRequest(bIsConditionalRequest);
+}
+
+void AuthenticatorRequestDialogController::setRelyingPartyId(const std::string &rpId)
+{
+ d_ptr->setRelyingPartyId(QString::fromStdString(rpId));
+}
+
+QString AuthenticatorRequestDialogController::relyingPartyId() const
+{
+ return d_ptr->relyingPartyId();
+}
+
+void AuthenticatorRequestDialogController::handleRequestFailure(
+ QWebEngineWebAuthUxRequest::RequestFailureReason reason)
+{
+ d_ptr->handleRequestFailure(reason);
+}
+
+void AuthenticatorRequestDialogController::retryRequest()
+{
+ d_ptr->retryRequest();
+}
+
+void AuthenticatorRequestDialogController::sendCollectPinResponse(const QString &pin)
+{
+ d_ptr->sendCollectPinResponse(pin);
+}
+
+QWebEngineWebAuthUxRequest::RequestFailureReason
+AuthenticatorRequestDialogController::requestFailureReason() const
+{
+ return d_ptr->requestFailureReason();
+}
+}
diff --git a/src/core/authenticator_request_dialog_controller.h b/src/core/authenticator_request_dialog_controller.h
new file mode 100644
index 000000000..98e8dcf90
--- /dev/null
+++ b/src/core/authenticator_request_dialog_controller.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef AUTHENTICATOR_REQUEST_DIALOG_CONTROLLER_H
+#define AUTHENTICATOR_REQUEST_DIALOG_CONTROLLER_H
+
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtCore/qobject.h>
+#include "qwebenginewebauthuxrequest.h"
+
+namespace content {
+class WebContents;
+class RenderFrameHost;
+}
+namespace QtWebEngineCore {
+
+class AuthenticatorRequestDialogControllerPrivate;
+
+class Q_WEBENGINECORE_EXPORT AuthenticatorRequestDialogController : public QObject
+{
+ Q_OBJECT
+public:
+ ~AuthenticatorRequestDialogController();
+ void sendSelectAccountResponse(const QString &account);
+ void sendCollectPinResponse(const QString &pin);
+ QStringList userNames() const;
+ QWebEngineWebAuthPinRequest pinRequest();
+ void reject();
+ AuthenticatorRequestDialogController(AuthenticatorRequestDialogControllerPrivate *);
+
+ QWebEngineWebAuthUxRequest::WebAuthUxState state() const;
+ QString relyingPartyId() const;
+ void retryRequest();
+ QWebEngineWebAuthUxRequest::RequestFailureReason requestFailureReason() const;
+
+Q_SIGNALS:
+ void stateChanged(QWebEngineWebAuthUxRequest::WebAuthUxState state);
+
+private:
+ void selectAccount(const QStringList &userList);
+ void collectPin(QWebEngineWebAuthPinRequest pinRequest);
+ void finishCollectToken();
+ void startRequest(bool bIsConditionalRequest);
+ void finishRequest();
+ void setRelyingPartyId(const std::string &rpId);
+ void handleRequestFailure(QWebEngineWebAuthUxRequest::RequestFailureReason reason);
+
+ QScopedPointer<AuthenticatorRequestDialogControllerPrivate> d_ptr;
+ friend class AuthenticatorRequestClientDelegateQt;
+};
+}
+
+#endif // AUTHENTICATOR_REQUEST_DIALOG_CONTROLLER_H
diff --git a/src/core/authenticator_request_dialog_controller_p.h b/src/core/authenticator_request_dialog_controller_p.h
new file mode 100644
index 000000000..5e7333d56
--- /dev/null
+++ b/src/core/authenticator_request_dialog_controller_p.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef AUTHENTICATOR_REQUEST_DIALOG_CONTROLLER_P_H
+#define AUTHENTICATOR_REQUEST_DIALOG_CONTROLLER_P_H
+#include <QStringList>
+#include <QSharedPointer>
+#include "authenticator_request_client_delegate_qt.h"
+#include "authenticator_request_dialog_controller.h"
+
+namespace content {
+class WebContents;
+class RenderFrameHost;
+}
+
+namespace QtWebEngineCore {
+
+class AuthenticatorRequestDialogControllerPrivate
+{
+
+public:
+ AuthenticatorRequestDialogControllerPrivate(
+ content::RenderFrameHost *renderFrameHost,
+ base::WeakPtr<AuthenticatorRequestClientDelegateQt> authenticatorRequestDelegate);
+ ~AuthenticatorRequestDialogControllerPrivate();
+ void showWebAuthDialog();
+ void selectAccount(const QStringList &userList);
+ QStringList userNames() const;
+ QString relyingPartyId() const;
+ QWebEngineWebAuthUxRequest::WebAuthUxState state() const;
+ QWebEngineWebAuthPinRequest pinRequest();
+ QWebEngineWebAuthUxRequest::RequestFailureReason requestFailureReason() const;
+ void sendSelectAccountResponse(const QString &selectedAccount);
+ void setCurrentState(QWebEngineWebAuthUxRequest::WebAuthUxState uxState);
+ void setRelyingPartyId(const QString &rpId);
+
+ // Support pin functionality
+ void collectPin(QWebEngineWebAuthPinRequest pinRequestInfo);
+ void finishCollectToken();
+ void handleRequestFailure(QWebEngineWebAuthUxRequest::RequestFailureReason reason);
+ void sendCollectPinResponse(const QString &pin);
+
+ // Deleting dialog;
+ void finishRequest();
+
+ // cancel request
+ void cancelRequest();
+ void retryRequest();
+ void startRequest(bool isConditionalRequest);
+
+ AuthenticatorRequestDialogController *q_ptr;
+
+private:
+ content::RenderFrameHost *m_renderFrameHost;
+ QStringList m_userList;
+ QString m_pin;
+ QString m_relyingPartyId;
+
+ bool m_isStarted = false;
+ bool m_isConditionalRequest = false;
+ QWebEngineWebAuthUxRequest::WebAuthUxState m_currentState =
+ QWebEngineWebAuthUxRequest::WebAuthUxState::NotStarted;
+ base::WeakPtr<AuthenticatorRequestClientDelegateQt> m_authenticatorRequestDelegate;
+ bool m_isDialogCreated = false;
+ QWebEngineWebAuthPinRequest m_pinRequest;
+
+ QWebEngineWebAuthUxRequest *m_request = nullptr;
+ QWebEngineWebAuthUxRequest::RequestFailureReason m_requestFailureReason;
+
+ // m_pendingState holds requested steps until the UI is shown. The UI is only
+ // shown once the TransportAvailabilityInfo is available, but authenticators
+ // may request, e.g., PIN entry prior to that.
+ absl::optional<QWebEngineWebAuthUxRequest::WebAuthUxState> m_pendingState;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // AUTHENTICATOR_REQUEST_DIALOG_CONTROLLER_P_H
diff --git a/src/core/autofill_client_qt.cpp b/src/core/autofill_client_qt.cpp
new file mode 100644
index 000000000..3bdc62e19
--- /dev/null
+++ b/src/core/autofill_client_qt.cpp
@@ -0,0 +1,147 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "autofill_client_qt.h"
+
+#include "autofill_popup_controller.h"
+#include "autofill_popup_controller_p.h"
+#include "render_widget_host_view_qt.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "components/autofill/core/common/autofill_prefs.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+
+namespace QtWebEngineCore {
+
+void AutofillClientQt::CreateForWebContents(content::WebContents *contents)
+{
+ DCHECK(contents);
+ if (!FromWebContents(contents))
+ contents->SetUserData(UserDataKey(), base::WrapUnique(new AutofillClientQt(contents)));
+}
+
+AutofillClientQt::AutofillClientQt(content::WebContents *webContents)
+ : autofill::ContentAutofillClient(
+ webContents, base::BindRepeating(&autofill::BrowserDriverInitHook, this, ""))
+ , content::WebContentsObserver(webContents)
+ , m_popupController(new AutofillPopupController(new AutofillPopupControllerPrivate))
+{
+}
+
+AutofillClientQt::~AutofillClientQt() { }
+
+autofill::PersonalDataManager *AutofillClientQt::GetPersonalDataManager()
+{
+ return nullptr;
+}
+
+autofill::AutocompleteHistoryManager *AutofillClientQt::GetAutocompleteHistoryManager()
+{
+ return nullptr;
+}
+
+PrefService *AutofillClientQt::GetPrefs()
+{
+ return const_cast<PrefService *>(std::as_const(*this).GetPrefs());
+}
+
+const PrefService *AutofillClientQt::GetPrefs() const
+{
+ Profile *profile = Profile::FromBrowserContext(web_contents()->GetBrowserContext());
+ return profile->GetPrefs();
+}
+
+void AutofillClientQt::ShowAutofillPopup(const autofill::AutofillClient::PopupOpenArgs &open_args,
+ base::WeakPtr<autofill::AutofillPopupDelegate> delegate)
+{
+ m_popupController->d->delegate = delegate;
+ m_popupController->d->suggestions = open_args.suggestions;
+ m_popupController->updateModel();
+
+ bool autoSelectFirstSuggestion =
+ open_args.trigger_source == autofill::AutofillSuggestionTriggerSource::kTextFieldDidReceiveKeyDown;
+
+ adapterClient()->showAutofillPopup(m_popupController.data(),
+ QRect(toQt(gfx::ToEnclosingRect(open_args.element_bounds))),
+ autoSelectFirstSuggestion);
+}
+
+void AutofillClientQt::UpdateAutofillPopupDataListValues(const std::vector<std::u16string> &values,
+ const std::vector<std::u16string> &labels)
+{
+ Q_UNUSED(labels);
+
+ if (values.empty())
+ HideAutofillPopup(autofill::PopupHidingReason::kNoSuggestions);
+}
+
+void AutofillClientQt::PinPopupView()
+{
+ // Called by password_manager component only.
+ NOTIMPLEMENTED();
+}
+
+autofill::AutofillClient::PopupOpenArgs AutofillClientQt::GetReopenPopupArgs(autofill::AutofillSuggestionTriggerSource trigger_source) const
+{
+ // Called by password_manager component only.
+ NOTIMPLEMENTED();
+ return autofill::AutofillClient::PopupOpenArgs();
+}
+
+std::vector<autofill::Suggestion> AutofillClientQt::GetPopupSuggestions() const
+{
+ // Called by password_manager component only.
+ NOTIMPLEMENTED();
+ return {};
+}
+
+void AutofillClientQt::UpdatePopup(const std::vector<autofill::Suggestion> &, autofill::PopupType, autofill::AutofillSuggestionTriggerSource)
+{
+ // Called by password_manager component only.
+ NOTIMPLEMENTED();
+}
+
+void AutofillClientQt::HideAutofillPopup(autofill::PopupHidingReason)
+{
+ adapterClient()->hideAutofillPopup();
+}
+
+bool AutofillClientQt::IsAutocompleteEnabled() const
+{
+ return autofill::prefs::IsAutocompleteEnabled(GetPrefs());
+}
+
+bool AutofillClientQt::IsPasswordManagerEnabled()
+{
+ return false;
+}
+
+bool AutofillClientQt::IsOffTheRecord()
+{
+ return web_contents()->GetBrowserContext()->IsOffTheRecord();
+}
+
+scoped_refptr<network::SharedURLLoaderFactory> AutofillClientQt::GetURLLoaderFactory()
+{
+ return nullptr;
+}
+
+void AutofillClientQt::PropagateAutofillPredictionsDeprecated(autofill::AutofillDriver *,
+ const std::vector<autofill::FormStructure *> &)
+{
+ // For testing purposes only.
+ NOTIMPLEMENTED();
+}
+
+WebContentsAdapterClient *AutofillClientQt::adapterClient()
+{
+ return WebContentsViewQt::from(
+ static_cast<content::WebContentsImpl *>(web_contents())->GetView())
+ ->client();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/autofill_client_qt.h b/src/core/autofill_client_qt.h
new file mode 100644
index 000000000..cd38de462
--- /dev/null
+++ b/src/core/autofill_client_qt.h
@@ -0,0 +1,76 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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.
+//
+
+#ifndef AUTOFILL_CLIENT_QT_H
+#define AUTOFILL_CLIENT_QT_H
+
+#include <string>
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "components/autofill/content/browser/content_autofill_client.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+#include <QScopedPointer>
+
+namespace QtWebEngineCore {
+
+class AutofillPopupController;
+class WebContentsAdapterClient;
+
+class AutofillClientQt : public autofill::ContentAutofillClient,
+ public content::WebContentsObserver
+{
+public:
+ ~AutofillClientQt() override;
+
+ static void CreateForWebContents(content::WebContents *contents);
+
+ // autofill::AutofillClient overrides:
+ autofill::PersonalDataManager *GetPersonalDataManager() override;
+ autofill::AutocompleteHistoryManager *GetAutocompleteHistoryManager() override;
+ PrefService *GetPrefs() override;
+ const PrefService *GetPrefs() const override;
+
+ void ShowAutofillPopup(const autofill::AutofillClient::PopupOpenArgs &open_args,
+ base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override;
+ void UpdateAutofillPopupDataListValues(const std::vector<std::u16string> &values,
+ const std::vector<std::u16string> &labels) override;
+ void PinPopupView() override;
+ PopupOpenArgs GetReopenPopupArgs(
+ autofill::AutofillSuggestionTriggerSource trigger_source) const override;
+ std::vector<autofill::Suggestion> GetPopupSuggestions() const override;
+ void UpdatePopup(const std::vector<autofill::Suggestion>& suggestions,
+ autofill::PopupType popup_type,
+ autofill::AutofillSuggestionTriggerSource trigger_source) override;
+ void HideAutofillPopup(autofill::PopupHidingReason reason) override;
+ bool IsAutocompleteEnabled() const override;
+ bool IsPasswordManagerEnabled() override;
+ void PropagateAutofillPredictionsDeprecated(autofill::AutofillDriver *,
+ const std::vector<autofill::FormStructure *> &) override;
+ bool IsOffTheRecord() override;
+ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
+
+private:
+ explicit AutofillClientQt(content::WebContents *webContents);
+
+ WebContentsAdapterClient *adapterClient();
+
+ QScopedPointer<AutofillPopupController> m_popupController;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // AUTOFILL_CLIENT_QT_H
diff --git a/src/core/autofill_popup_controller.cpp b/src/core/autofill_popup_controller.cpp
new file mode 100644
index 000000000..a6baf5fc2
--- /dev/null
+++ b/src/core/autofill_popup_controller.cpp
@@ -0,0 +1,113 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "autofill_popup_controller.h"
+#include "autofill_popup_controller_p.h"
+
+#include "components/autofill/core/browser/ui/autofill_popup_delegate.h"
+#include "components/autofill/core/browser/ui/suggestion.h"
+
+namespace QtWebEngineCore {
+
+AutofillPopupController::AutofillPopupController(AutofillPopupControllerPrivate *dd)
+{
+ Q_ASSERT(dd);
+ d.reset(dd);
+}
+
+AutofillPopupController::~AutofillPopupController() { }
+
+void AutofillPopupController::setCurrentIndex(const QModelIndex &index)
+{
+ if (m_currentIndex == index)
+ return;
+
+ m_currentIndex = index;
+
+ if (m_currentIndex.isValid()) {
+ const autofill::Suggestion &suggestion = d->suggestions[m_currentIndex.row()];
+ d->delegate->DidSelectSuggestion(suggestion, autofill::AutofillSuggestionTriggerSource::kFormControlElementClicked);
+ }
+
+ Q_EMIT currentIndexChanged(index);
+}
+
+void AutofillPopupController::selectPreviousSuggestion()
+{
+ if (!m_currentIndex.isValid()) {
+ setCurrentIndex(m_model.index(m_model.rowCount() - 1, 0));
+ return;
+ }
+
+ if (m_currentIndex.row() == 0) {
+ selectLastSuggestion();
+ return;
+ }
+
+ setCurrentIndex(m_model.index(m_currentIndex.row() - 1, 0));
+}
+
+void AutofillPopupController::selectNextSuggestion()
+{
+ if (!m_currentIndex.isValid()) {
+ setCurrentIndex(m_model.index(0, 0));
+ return;
+ }
+
+ if (m_currentIndex.row() == m_model.rowCount() - 1) {
+ selectFirstSuggestion();
+ return;
+ }
+
+ setCurrentIndex(m_model.index(m_currentIndex.row() + 1, 0));
+}
+
+void AutofillPopupController::selectFirstSuggestion()
+{
+ setCurrentIndex(m_model.index(0, 0));
+}
+
+void AutofillPopupController::selectLastSuggestion()
+{
+ setCurrentIndex(m_model.index(m_model.rowCount() - 1, 0));
+}
+
+void AutofillPopupController::acceptSuggestion()
+{
+ if (!m_currentIndex.isValid())
+ return;
+
+ const int index = m_currentIndex.row();
+ const autofill::Suggestion &suggestion = d->suggestions[index];
+ d->delegate->DidAcceptSuggestion(suggestion, index, autofill::AutofillSuggestionTriggerSource::kFormControlElementClicked);
+}
+
+void AutofillPopupController::notifyPopupShown()
+{
+ d->delegate->OnPopupShown();
+}
+
+void AutofillPopupController::notifyPopupHidden()
+{
+ d->delegate->OnPopupHidden();
+}
+
+void AutofillPopupController::selectSuggestion(int index)
+{
+ if (index < 0)
+ setCurrentIndex(QModelIndex());
+ else
+ setCurrentIndex(m_model.index(index, 0));
+}
+
+void AutofillPopupController::updateModel()
+{
+ QStringList values;
+ for (size_t i = 0; i < d->suggestions.size(); ++i) {
+ values.append(QString::fromStdU16String(d->suggestions[i].main_text.value));
+ }
+ m_model.setStringList(values);
+ setCurrentIndex(QModelIndex());
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/autofill_popup_controller.h b/src/core/autofill_popup_controller.h
new file mode 100644
index 000000000..1b4d8d7e8
--- /dev/null
+++ b/src/core/autofill_popup_controller.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef AUTOFILL_POPUP_CONTROLLER_H
+#define AUTOFILL_POPUP_CONTROLLER_H
+
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+
+#include <QModelIndex>
+#include <QObject>
+#include <QScopedPointer>
+#include <QStringListModel>
+
+namespace QtWebEngineCore {
+
+class AutofillPopupControllerPrivate;
+
+class Q_WEBENGINECORE_EXPORT AutofillPopupController : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QStringListModel *model READ model CONSTANT FINAL)
+
+public:
+ ~AutofillPopupController();
+
+ QStringListModel *model() { return &m_model; }
+
+ void selectPreviousSuggestion();
+ void selectNextSuggestion();
+ void selectFirstSuggestion();
+ void selectLastSuggestion();
+
+ void notifyPopupShown();
+ void notifyPopupHidden();
+
+public Q_SLOTS:
+ void selectSuggestion(int index);
+ void acceptSuggestion();
+
+Q_SIGNALS:
+ void currentIndexChanged(const QModelIndex &index);
+
+private:
+ AutofillPopupController(AutofillPopupControllerPrivate *);
+ QScopedPointer<AutofillPopupControllerPrivate> d;
+
+ void setCurrentIndex(const QModelIndex &index);
+
+ // Only called by AutofillClientQt:
+ void updateModel();
+
+ QStringListModel m_model;
+ QModelIndex m_currentIndex;
+
+ friend class AutofillClientQt;
+};
+
+} // namespace QtWebEngineCore
+
+Q_DECLARE_METATYPE(QtWebEngineCore::AutofillPopupController *)
+
+#endif // AUTOFILL_POPUP_CONTROLLER_H
diff --git a/src/core/autofill_popup_controller_p.h b/src/core/autofill_popup_controller_p.h
new file mode 100644
index 000000000..886fe4dcd
--- /dev/null
+++ b/src/core/autofill_popup_controller_p.h
@@ -0,0 +1,40 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef AUTOFILL_POPUP_CONTROLLER_P_H
+#define AUTOFILL_POPUP_CONTROLLER_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 <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "components/autofill/core/browser/ui/suggestion.h"
+
+namespace autofill {
+class AutofillPopupDelegate;
+}
+
+namespace QtWebEngineCore {
+
+class AutofillPopupControllerPrivate
+{
+public:
+ AutofillPopupControllerPrivate() = default;
+
+ base::WeakPtr<autofill::AutofillPopupDelegate> delegate = nullptr;
+ std::vector<autofill::Suggestion> suggestions;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // AUTOFILL_POPUP_CONTROLLER_P_H
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp
index b1d7f1a22..077856266 100644
--- a/src/core/browser_accessibility_manager_qt.cpp
+++ b/src/core/browser_accessibility_manager_qt.cpp
@@ -1,88 +1,67 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "browser_accessibility_manager_qt.h"
+#include "qtwebenginecoreglobal.h"
-#include "ui/accessibility/ax_enums.mojom.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include <QtGui/qtguiglobal.h>
+
+#if QT_CONFIG(accessibility)
#include "browser_accessibility_qt.h"
-#include "render_widget_host_view_qt.h"
+#include "browser_accessibility_manager_qt.h"
+#include "render_widget_host_view_qt.h" // WebContentsAccessibilityQt
-using namespace blink;
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+
+#include <QtGui/qaccessible.h>
+#endif // QT_CONFIG(accessibility)
namespace content {
// static
BrowserAccessibilityManager *BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate *delegate)
+ WebAXPlatformTreeManagerDelegate *delegate)
{
#if QT_CONFIG(accessibility)
Q_ASSERT(delegate);
- QObject *parent = nullptr;
- if (delegate->AccessibilityIsMainFrame()) {
- auto *access = static_cast<QtWebEngineCore::WebContentsAccessibilityQt *>(delegate->AccessibilityGetWebContentsAccessibility());
- parent = access ? access->accessibilityParentObject() : nullptr;
+ QtWebEngineCore::WebContentsAccessibilityQt *access = nullptr;
+ access = static_cast<QtWebEngineCore::WebContentsAccessibilityQt *>(delegate->AccessibilityGetWebContentsAccessibility());
+
+ // Accessibility is not supported for guest views and child frames.
+ if (!access) {
+ return nullptr;
}
- return new BrowserAccessibilityManagerQt(parent, initialTree, delegate);
+
+ return new BrowserAccessibilityManagerQt(access, initialTree, delegate);
#else
+ Q_UNUSED(initialTree);
+ Q_UNUSED(delegate);
return nullptr;
#endif // QT_CONFIG(accessibility)
}
// static
BrowserAccessibilityManager *BrowserAccessibilityManager::Create(
- BrowserAccessibilityDelegate *delegate)
+ WebAXPlatformTreeManagerDelegate *delegate)
{
#if QT_CONFIG(accessibility)
return BrowserAccessibilityManager::Create(BrowserAccessibilityManagerQt::GetEmptyDocument(), delegate);
#else
+ Q_UNUSED(delegate);
return nullptr;
#endif
}
#if QT_CONFIG(accessibility)
BrowserAccessibilityManagerQt::BrowserAccessibilityManagerQt(
- QObject *parentObject, const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate* delegate)
+ QtWebEngineCore::WebContentsAccessibilityQt *webContentsAccessibility,
+ const ui::AXTreeUpdate &initialTree,
+ WebAXPlatformTreeManagerDelegate* delegate)
: BrowserAccessibilityManager(delegate)
- , m_parentObject(parentObject)
+ , m_webContentsAccessibility(webContentsAccessibility)
{
Initialize(initialTree);
m_valid = true; // BrowserAccessibilityQt can start using the AXTree
@@ -95,17 +74,28 @@ BrowserAccessibilityManagerQt::~BrowserAccessibilityManagerQt()
QAccessibleInterface *BrowserAccessibilityManagerQt::rootParentAccessible()
{
- return QAccessible::queryAccessibleInterface(m_parentObject);
+ content::BrowserAccessibility *parent_node = GetParentNodeFromParentTreeAsBrowserAccessibility();
+ if (!parent_node) {
+ Q_ASSERT(m_webContentsAccessibility);
+ return QAccessible::queryAccessibleInterface(m_webContentsAccessibility->accessibilityParentObject());
+ }
+
+ auto *parent_manager =
+ static_cast<BrowserAccessibilityManagerQt *>(parent_node->manager());
+ return parent_manager->rootParentAccessible();
}
void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
- BrowserAccessibility* node)
+ BrowserAccessibility *node,
+ int action_request_id)
{
- BrowserAccessibilityQt *iface = static_cast<BrowserAccessibilityQt*>(node);
+ auto *iface = toQAccessibleInterface(node);
switch (event_type) {
case ax::mojom::Event::kFocus: {
QAccessibleEvent event(iface, QAccessible::Focus);
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
break;
}
@@ -113,6 +103,8 @@ void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
QAccessible::State change;
change.checked = true;
QAccessibleStateChangeEvent event(iface, change);
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
break;
}
@@ -121,6 +113,8 @@ void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
if (QAccessibleValueInterface *valueIface = iface->valueInterface())
value = valueIface->currentValue();
QAccessibleValueChangeEvent event(iface, value);
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
break;
}
@@ -132,6 +126,8 @@ void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
break;
case ax::mojom::Event::kTextChanged: {
QAccessibleTextUpdateEvent event(iface, -1, QString(), QString());
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
break;
}
@@ -143,9 +139,13 @@ void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
textIface->selection(0, &start, &end);
if (start == end) {
QAccessibleTextCursorEvent event(iface, start);
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
} else {
QAccessibleTextSelectionEvent event(iface, start, end);
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
}
}
@@ -157,14 +157,20 @@ void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type,
}
void BrowserAccessibilityManagerQt::FireGeneratedEvent(ui::AXEventGenerator::Event event_type,
- BrowserAccessibility* node)
+ const ui::AXNode *node)
{
- BrowserAccessibilityQt *iface = static_cast<BrowserAccessibilityQt*>(node);
+ BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
+
+ BrowserAccessibility *wrapper = GetFromAXNode(node);
+ DCHECK(wrapper);
+ auto *iface = toQAccessibleInterface(wrapper);
switch (event_type) {
case ui::AXEventGenerator::Event::VALUE_IN_TEXT_FIELD_CHANGED:
if (iface->role() == QAccessible::EditableText) {
QAccessibleTextUpdateEvent event(iface, -1, QString(), QString());
+ if (event.object())
+ event.setChild(-1);
QAccessible::updateAccessibility(&event);
}
break;
diff --git a/src/core/browser_accessibility_manager_qt.h b/src/core/browser_accessibility_manager_qt.h
index 2a1d273b9..e36edd979 100644
--- a/src/core/browser_accessibility_manager_qt.h
+++ b/src/core/browser_accessibility_manager_qt.h
@@ -1,78 +1,44 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef BROWSER_ACCESSIBILITY_MANAGER_QT_H
#define BROWSER_ACCESSIBILITY_MANAGER_QT_H
#include "content/browser/accessibility/browser_accessibility_manager.h"
-#include <QtCore/qobject.h>
-#include <QtGui/qtgui-config.h>
-
-#if QT_CONFIG(accessibility)
+#include <QtCore/qtclasshelpermacros.h>
+#include <QtCore/qtconfigmacros.h>
QT_FORWARD_DECLARE_CLASS(QAccessibleInterface)
+namespace QtWebEngineCore {
+class WebContentsAccessibilityQt;
+}
+
namespace content {
class BrowserAccessibilityManagerQt : public BrowserAccessibilityManager
{
public:
- BrowserAccessibilityManagerQt(QObject *parentObject,
+ BrowserAccessibilityManagerQt(QtWebEngineCore::WebContentsAccessibilityQt *webContentsAccessibility,
const ui::AXTreeUpdate &initialTree,
- BrowserAccessibilityDelegate *delegate);
+ WebAXPlatformTreeManagerDelegate *delegate);
~BrowserAccessibilityManagerQt() override;
void FireBlinkEvent(ax::mojom::Event event_type,
- BrowserAccessibility* node) override;
+ BrowserAccessibility *node,
+ int action_request_id) override;
void FireGeneratedEvent(ui::AXEventGenerator::Event event_type,
- BrowserAccessibility* node) override;
+ const ui::AXNode *node) override;
QAccessibleInterface *rootParentAccessible();
bool isValid() const { return m_valid; }
private:
Q_DISABLE_COPY(BrowserAccessibilityManagerQt)
- QObject *m_parentObject;
+ QtWebEngineCore::WebContentsAccessibilityQt *m_webContentsAccessibility;
bool m_valid = false;
};
}
-#endif // QT_CONFIG(accessibility)
-#endif
+#endif // BROWSER_ACCESSIBILITY_MANAGER_QT_H
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index bf11646b2..de3347df3 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -1,98 +1,197 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// 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.Chromium file.
#include "browser_accessibility_qt.h"
-
-#if QT_CONFIG(accessibility)
-
-#include "ui/accessibility/ax_enums.mojom.h"
-
#include "browser_accessibility_manager_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
-using namespace blink;
-using QtWebEngineCore::toQt;
+#if QT_CONFIG(accessibility)
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "ui/accessibility/ax_enums.mojom.h"
-namespace content {
+#include <QtGui/qaccessible.h>
+
+namespace QtWebEngineCore {
+class BrowserAccessibilityInterface;
+
+class BrowserAccessibilityQt
+ : public content::BrowserAccessibility
+{
+public:
+ BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node);
+ ~BrowserAccessibilityQt();
+
+ bool isReady() const;
+
+ QtWebEngineCore::BrowserAccessibilityInterface *interface = nullptr;
+};
+
+class BrowserAccessibilityInterface
+ : public QAccessibleInterface
+ , public QAccessibleActionInterface
+ , public QAccessibleTextInterface
+ , public QAccessibleValueInterface
+ , public QAccessibleTableInterface
+ , public QAccessibleTableCellInterface
+{
+public:
+ BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface);
+ ~BrowserAccessibilityInterface() override;
+
+ void destroy();
+
+ // QAccessibleInterface
+ bool isValid() const override;
+ QObject *object() const override;
+ QAccessibleInterface *childAt(int x, int y) const override;
+ void *interface_cast(QAccessible::InterfaceType type) override;
+
+ // navigation, hierarchy
+ QAccessibleInterface *parent() const override;
+ QAccessibleInterface *child(int index) const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ int indexOfChild(const QAccessibleInterface *) const override;
+
+ // properties and state
+ QString text(QAccessible::Text t) const override;
+ void setText(QAccessible::Text t, const QString &text) override;
+ QRect rect() const override;
+ QAccessible::Role role() const override;
+ QAccessible::State state() const override;
+
+ // QAccessibleActionInterface
+ QStringList actionNames() const override;
+ void doAction(const QString &actionName) override;
+ QStringList keyBindingsForAction(const QString &actionName) const override;
+
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset) override;
+ QString attributes(int offset, int *startOffset, int *endOffset) const override;
+ int cursorPosition() const override;
+ QRect characterRect(int offset) const override;
+ int selectionCount() const override;
+ int offsetAtPoint(const QPoint &point) const override;
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const override;
+ QString text(int startOffset, int endOffset) const override;
+ void removeSelection(int selectionIndex) override;
+ void setCursorPosition(int position) override;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) override;
+ int characterCount() const override;
+ void scrollToSubstring(int startIndex, int endIndex) override;
+
+ // QAccessibleValueInterface
+ QVariant currentValue() const override;
+ void setCurrentValue(const QVariant &value) override;
+ QVariant maximumValue() const override;
+ QVariant minimumValue() const override;
+ QVariant minimumStepSize() const override;
+
+ // QAccessibleTableInterface
+ QAccessibleInterface *cellAt(int row, int column) const override;
+ QAccessibleInterface *caption() const override;
+ QAccessibleInterface *summary() const override;
+ QString columnDescription(int column) const override;
+ QString rowDescription(int row) const override;
+ int columnCount() const override;
+ int rowCount() const override;
+ // selection
+ int selectedCellCount() const override;
+ int selectedColumnCount() const override;
+ int selectedRowCount() const override;
+ QList<QAccessibleInterface *> selectedCells() const override;
+ QList<int> selectedColumns() const override;
+ QList<int> selectedRows() const override;
+ bool isColumnSelected(int column) const override;
+ bool isRowSelected(int row) const override;
+ bool selectRow(int row) override;
+ bool selectColumn(int column) override;
+ bool unselectRow(int row) override;
+ bool unselectColumn(int column) override;
+
+ // QAccessibleTableCellInterface
+ int columnExtent() const override;
+ QList<QAccessibleInterface *> columnHeaderCells() const override;
+ int columnIndex() const override;
+ int rowExtent() const override;
+ QList<QAccessibleInterface *> rowHeaderCells() const override;
+ int rowIndex() const override;
+ bool isSelected() const override;
+ QAccessibleInterface *table() const override;
+
+ void modelChange(QAccessibleTableModelChangeEvent *event) override;
+
+private:
+ content::BrowserAccessibility *findTable() const;
+
+ QObject *m_object = nullptr;
+ QAccessible::Id m_id = 0;
+ BrowserAccessibilityQt *q;
+};
+
+BrowserAccessibilityQt::BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager,
+ ui::AXNode *node)
+ : content::BrowserAccessibility(manager, node)
+ , interface(new BrowserAccessibilityInterface(this))
+{
+}
+
+BrowserAccessibilityQt::~BrowserAccessibilityQt()
+{
+ if (interface)
+ interface->destroy();
+}
+
+bool BrowserAccessibilityQt::isReady() const
+{
+ // FIXME: This is just a workaround, remove this when the commented out assert in
+ // BrowserAccessibilityManager::GetFromID(int32_t id) gets fixed.
+ return manager()->GetFromID(node()->id()) != nullptr;
+}
+
+BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface)
+ : q(chromiumInterface)
+{
+ if (parent() && parent()->object()) {
+ m_object = new QObject(parent()->object());
+ QString name = toQt(q->GetAuthorUniqueId());
+ if (!name.isEmpty())
+ m_object->setObjectName(name);
+ }
-// static
-BrowserAccessibility *BrowserAccessibility::Create()
-{
-#if QT_CONFIG(accessibility)
- return new BrowserAccessibilityQt();
-#else
- return nullptr;
-#endif // QT_CONFIG(accessibility)
+ m_id = QAccessible::registerAccessibleInterface(this);
}
-const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj)
+BrowserAccessibilityInterface::~BrowserAccessibilityInterface()
{
- return static_cast<const BrowserAccessibilityQt *>(obj);
+ q->interface = nullptr;
}
-QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj)
+void BrowserAccessibilityInterface::destroy()
{
- return static_cast<BrowserAccessibilityQt *>(obj);
+ QAccessible::deleteAccessibleInterface(m_id);
}
-BrowserAccessibilityQt::BrowserAccessibilityQt()
+bool BrowserAccessibilityInterface::isValid() const
{
- QAccessible::registerAccessibleInterface(this);
-}
+ if (!q->isReady())
+ return false;
-bool BrowserAccessibilityQt::isValid() const
-{
- auto managerQt = static_cast<BrowserAccessibilityManagerQt *>(manager_);
+ auto managerQt = static_cast<content::BrowserAccessibilityManagerQt *>(q->manager());
return managerQt && managerQt->isValid();
}
-QObject *BrowserAccessibilityQt::object() const
+QObject *BrowserAccessibilityInterface::object() const
{
- return nullptr;
+ return m_object;
}
-QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
+QAccessibleInterface *BrowserAccessibilityInterface::childAt(int x, int y) const
{
for (int i = 0; i < childCount(); ++i) {
QAccessibleInterface *childIface = child(i);
@@ -103,7 +202,7 @@ QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
return nullptr;
}
-void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
+void *BrowserAccessibilityInterface::interface_cast(QAccessible::InterfaceType type)
{
switch (type) {
case QAccessible::ActionInterface:
@@ -111,7 +210,7 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
return static_cast<QAccessibleActionInterface*>(this);
break;
case QAccessible::TextInterface:
- if (HasState(ax::mojom::State::kEditable))
+ if (q->HasState(ax::mojom::State::kEditable))
return static_cast<QAccessibleTextInterface*>(this);
break;
case QAccessible::ValueInterface: {
@@ -133,10 +232,10 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
}
case QAccessible::TableCellInterface: {
QAccessible::Role r = role();
- if (r == QAccessible::Cell ||
- r == QAccessible::ListItem ||
- r == QAccessible::TreeItem)
- return static_cast<QAccessibleTableCellInterface*>(this);
+ if (r == QAccessible::Cell || r == QAccessible::ListItem || r == QAccessible::TreeItem) {
+ if (findTable())
+ return static_cast<QAccessibleTableCellInterface *>(this);
+ }
break;
}
default:
@@ -145,23 +244,24 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
return nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::parent() const
+QAccessibleInterface *BrowserAccessibilityInterface::parent() const
{
- BrowserAccessibility *p = PlatformGetParent();
- if (p)
- return static_cast<BrowserAccessibilityQt*>(p);
- return static_cast<BrowserAccessibilityManagerQt*>(manager())->rootParentAccessible();
+ content::BrowserAccessibility *chromiumParent = q->PlatformGetParent();
+ if (chromiumParent)
+ return toQAccessibleInterface(chromiumParent);
+ return static_cast<content::BrowserAccessibilityManagerQt*>(q->manager())->rootParentAccessible();
}
-QAccessibleInterface *BrowserAccessibilityQt::child(int index) const
+QAccessibleInterface *BrowserAccessibilityInterface::child(int index) const
{
- return static_cast<BrowserAccessibilityQt*>(BrowserAccessibility::PlatformGetChild(index));
+ content::BrowserAccessibility *chromiumChild = q->PlatformGetChild(index);
+ return chromiumChild ? toQAccessibleInterface(chromiumChild) : nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::focusChild() const
+QAccessibleInterface *BrowserAccessibilityInterface::focusChild() const
{
if (state().focused)
- return const_cast<BrowserAccessibilityQt *>(this);
+ return const_cast<BrowserAccessibilityInterface *>(this);
for (int i = 0; i < childCount(); ++i) {
if (QAccessibleInterface *iface = child(i)->focusChild())
@@ -171,59 +271,61 @@ QAccessibleInterface *BrowserAccessibilityQt::focusChild() const
return nullptr;
}
-int BrowserAccessibilityQt::childCount() const
+int BrowserAccessibilityInterface::childCount() const
{
- return PlatformChildCount();
+ return q->PlatformChildCount();
}
-int BrowserAccessibilityQt::indexOfChild(const QAccessibleInterface *iface) const
+int BrowserAccessibilityInterface::indexOfChild(const QAccessibleInterface *iface) const
{
- const BrowserAccessibilityQt *child = static_cast<const BrowserAccessibilityQt*>(iface);
- return const_cast<BrowserAccessibilityQt *>(child)->GetIndexInParent();
+ const BrowserAccessibilityInterface *child = static_cast<const BrowserAccessibilityInterface *>(iface);
+ return const_cast<BrowserAccessibilityInterface *>(child)->q->GetIndexInParent().value();
}
-QString BrowserAccessibilityQt::text(QAccessible::Text t) const
+QString BrowserAccessibilityInterface::text(QAccessible::Text t) const
{
+ if (!q->isReady())
+ return QString();
+
switch (t) {
case QAccessible::Name:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kName));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kName));
case QAccessible::Description:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kDescription));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kDescription));
case QAccessible::Value:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kValue));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kValue));
case QAccessible::Accelerator:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts));
default:
break;
}
return QString();
}
-void BrowserAccessibilityQt::setText(QAccessible::Text t, const QString &text)
+void BrowserAccessibilityInterface::setText(QAccessible::Text t, const QString &text)
{
}
-QRect BrowserAccessibilityQt::rect() const
+QRect BrowserAccessibilityInterface::rect() const
{
- if (!manager()) // needed implicitly by GetScreenBoundsRect()
+ if (!q->manager() || !q->isReady()) // needed implicitly by GetScreenBoundsRect()
return QRect();
- gfx::Rect bounds = GetUnclippedScreenBoundsRect();
+ gfx::Rect bounds = q->GetUnclippedScreenBoundsRect();
+ bounds = gfx::ScaleToRoundedRect(bounds, 1.f / q->manager()->device_scale_factor()); // FIXME: check
return QRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
}
-QAccessible::Role BrowserAccessibilityQt::role() const
+QAccessible::Role BrowserAccessibilityInterface::role() const
{
- switch (GetRole()) {
+ switch (q->GetRole()) {
case ax::mojom::Role::kNone:
case ax::mojom::Role::kUnknown:
return QAccessible::NoRole;
// Internal roles (matching auralinux and win)
case ax::mojom::Role::kKeyboard:
- case ax::mojom::Role::kIgnored:
case ax::mojom::Role::kImeCandidate:
- case ax::mojom::Role::kPresentational:
return QAccessible::NoRole;
// Used by Chromium to distinguish between the root of the tree
@@ -239,8 +341,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kAlert:
case ax::mojom::Role::kAlertDialog:
return QAccessible::AlertMessage;
- case ax::mojom::Role::kAnchor:
- return QAccessible::Link;
case ax::mojom::Role::kApplication:
return QAccessible::Document; // returning Application here makes Qt return the top level app object
case ax::mojom::Role::kArticle:
@@ -277,6 +377,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kComboBoxMenuButton:
case ax::mojom::Role::kTextFieldWithComboBox:
return QAccessible::ComboBox;
+ case ax::mojom::Role::kComboBoxSelect:
+ return QAccessible::PopupMenu;
case ax::mojom::Role::kComplementary:
return QAccessible::ComplementaryContent;
case ax::mojom::Role::kComment:
@@ -400,8 +502,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Grouping;
case ax::mojom::Role::kImage:
return QAccessible::Graphic;
- case ax::mojom::Role::kImageMap:
- return QAccessible::Document;
case ax::mojom::Role::kInlineTextBox:
return QAccessible::StaticText;
case ax::mojom::Role::kInputTime:
@@ -439,7 +539,50 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kMarquee:
return QAccessible::Section;
case ax::mojom::Role::kMath:
+ case ax::mojom::Role::kMathMLMath:
return QAccessible::Equation;
+ case ax::mojom::Role::kMathMLFraction:
+ return QAccessible::Grouping;
+ case ax::mojom::Role::kMathMLIdentifier:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLMultiscripts:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLNoneScript:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLNumber:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLOperator:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLOver:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLPrescriptDelimiter:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLRoot:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLRow:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLSquareRoot:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLStringLiteral:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLSub:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLSubSup:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLSup:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLTable:
+ return QAccessible::Table;
+ case ax::mojom::Role::kMathMLTableCell:
+ return QAccessible::Cell;
+ case ax::mojom::Role::kMathMLTableRow:
+ return QAccessible::Row;
+ case ax::mojom::Role::kMathMLText:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLUnder:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLUnderOver:
+ return QAccessible::Section;
case ax::mojom::Role::kMenu:
return QAccessible::PopupMenu;
case ax::mojom::Role::kMenuBar:
@@ -516,10 +659,14 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Indicator;
case ax::mojom::Role::kStrong:
return QAccessible::StaticText;
+ case ax::mojom::Role::kSubscript:
+ return QAccessible::Grouping;
case ax::mojom::Role::kSuggestion:
return QAccessible::Section;
+ case ax::mojom::Role::kSuperscript:
+ return QAccessible::Grouping;
case ax::mojom::Role::kSvgRoot:
- return QAccessible::Graphic;
+ return QAccessible::WebDocument;
case ax::mojom::Role::kSwitch:
return QAccessible::Button;
case ax::mojom::Role::kTable:
@@ -561,63 +708,68 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::NoRole;
}
-QAccessible::State BrowserAccessibilityQt::state() const
+QAccessible::State BrowserAccessibilityInterface::state() const
{
QAccessible::State state = QAccessible::State();
- if (HasState(ax::mojom::State::kCollapsed))
+ if (!q->isReady()) {
+ state.invalid = true;
+ return state;
+ }
+
+ if (q->HasState(ax::mojom::State::kCollapsed))
state.collapsed = true;
- if (HasState(ax::mojom::State::kDefault))
+ if (q->HasState(ax::mojom::State::kDefault))
state.defaultButton = true;
- if (HasState(ax::mojom::State::kEditable))
+ if (q->HasState(ax::mojom::State::kEditable))
state.editable = true;
- if (HasState(ax::mojom::State::kExpanded))
+ if (q->HasState(ax::mojom::State::kExpanded))
state.expanded = true;
- if (HasState(ax::mojom::State::kFocusable))
+ if (q->HasState(ax::mojom::State::kFocusable))
state.focusable = true;
- if (HasState(ax::mojom::State::kHorizontal))
+ if (q->HasState(ax::mojom::State::kHorizontal))
{} // FIXME
- if (HasState(ax::mojom::State::kHovered))
+ if (q->HasState(ax::mojom::State::kHovered))
state.hotTracked = true;
- if (HasState(ax::mojom::State::kIgnored))
+ if (q->HasState(ax::mojom::State::kIgnored))
{} // FIXME
- if (HasState(ax::mojom::State::kInvisible))
+ if (q->HasState(ax::mojom::State::kInvisible))
state.invisible = true;
- if (HasState(ax::mojom::State::kLinked))
+ if (q->HasState(ax::mojom::State::kLinked))
state.linked = true;
- if (HasState(ax::mojom::State::kMultiline))
+ if (q->HasState(ax::mojom::State::kMultiline))
state.multiLine = true;
- if (HasState(ax::mojom::State::kMultiselectable))
+ if (q->HasState(ax::mojom::State::kMultiselectable))
state.multiSelectable = true;
- if (HasState(ax::mojom::State::kProtected))
+ if (q->HasState(ax::mojom::State::kProtected))
state.passwordEdit = true;
- if (HasState(ax::mojom::State::kRequired))
+ if (q->HasState(ax::mojom::State::kRequired))
{} // FIXME
- if (HasState(ax::mojom::State::kRichlyEditable))
+ if (q->HasState(ax::mojom::State::kRichlyEditable))
{} // FIXME
- if (HasState(ax::mojom::State::kVertical))
+ if (q->HasState(ax::mojom::State::kVertical))
{} // FIXME
- if (HasState(ax::mojom::State::kVisited))
+ if (q->HasState(ax::mojom::State::kVisited))
state.traversed = true;
- if (IsOffscreen())
+ if (q->IsOffscreen())
state.offscreen = true;
- if (manager()->GetFocus() == this)
+ if (q->manager()->GetFocus() == q)
state.focused = true;
- if (GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
+ if (q->GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
state.busy = true;
- if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
+ if (q->GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
state.modal = true;
- if (HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
+ if (q->HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
state.selectable = true;
- state.selected = GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
+ state.selected = q->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
}
- if (HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) {
+ if (q->HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) {
state.checkable = true;
const ax::mojom::CheckedState checkedState =
- static_cast<ax::mojom::CheckedState>(GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
+ static_cast<ax::mojom::CheckedState>(q->GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
switch (checkedState) {
case ax::mojom::CheckedState::kTrue:
- if (GetRole() == ax::mojom::Role::kToggleButton)
+ if (q->GetRole() == ax::mojom::Role::kToggleButton)
state.pressed = true;
else
state.checked = true;
@@ -630,8 +782,8 @@ QAccessible::State BrowserAccessibilityQt::state() const
break;
}
}
- if (HasIntAttribute(ax::mojom::IntAttribute::kRestriction)) {
- const ax::mojom::Restriction restriction = static_cast<ax::mojom::Restriction>(GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
+ if (q->HasIntAttribute(ax::mojom::IntAttribute::kRestriction)) {
+ const ax::mojom::Restriction restriction = static_cast<ax::mojom::Restriction>(q->GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
switch (restriction) {
case ax::mojom::Restriction::kReadOnly:
state.readOnly = true;
@@ -643,8 +795,8 @@ QAccessible::State BrowserAccessibilityQt::state() const
break;
}
}
- if (HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) {
- const ax::mojom::HasPopup hasPopup = static_cast<ax::mojom::HasPopup>(GetIntAttribute(ax::mojom::IntAttribute::kHasPopup));
+ if (q->HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) {
+ const ax::mojom::HasPopup hasPopup = static_cast<ax::mojom::HasPopup>(q->GetIntAttribute(ax::mojom::IntAttribute::kHasPopup));
switch (hasPopup) {
case ax::mojom::HasPopup::kFalse:
break;
@@ -661,347 +813,370 @@ QAccessible::State BrowserAccessibilityQt::state() const
return state;
}
-void BrowserAccessibilityQt::Destroy()
-{
- // delete this
- QAccessible::Id interfaceId = QAccessible::uniqueId(this);
- QAccessible::deleteAccessibleInterface(interfaceId);
-}
-
-QStringList BrowserAccessibilityQt::actionNames() const
+QStringList BrowserAccessibilityInterface::actionNames() const
{
QStringList actions;
- if (HasState(ax::mojom::State::kFocusable))
+ if (q->HasState(ax::mojom::State::kFocusable))
actions << QAccessibleActionInterface::setFocusAction();
return actions;
}
-void BrowserAccessibilityQt::doAction(const QString &actionName)
+void BrowserAccessibilityInterface::doAction(const QString &actionName)
{
if (actionName == QAccessibleActionInterface::setFocusAction())
- manager()->SetFocus(*this);
+ q->manager()->SetFocus(*q);
}
-QStringList BrowserAccessibilityQt::keyBindingsForAction(const QString &actionName) const
+QStringList
+BrowserAccessibilityInterface::keyBindingsForAction(const QString & /*actionName*/) const
{
QT_NOT_YET_IMPLEMENTED
return QStringList();
}
-void BrowserAccessibilityQt::addSelection(int startOffset, int endOffset)
+void BrowserAccessibilityInterface::addSelection(int startOffset, int endOffset)
{
- manager()->SetSelection(AXRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(startOffset), q->CreatePositionAt(endOffset)));
}
-QString BrowserAccessibilityQt::attributes(int offset, int *startOffset, int *endOffset) const
+QString BrowserAccessibilityInterface::attributes(int offset, int *startOffset, int *endOffset) const
{
*startOffset = offset;
*endOffset = offset;
return QString();
}
-int BrowserAccessibilityQt::cursorPosition() const
+int BrowserAccessibilityInterface::cursorPosition() const
{
int pos = 0;
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &pos);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &pos);
return pos;
}
-QRect BrowserAccessibilityQt::characterRect(int /*offset*/) const
+QRect BrowserAccessibilityInterface::characterRect(int /*offset*/) const
{
QT_NOT_YET_IMPLEMENTED
return QRect();
}
-int BrowserAccessibilityQt::selectionCount() const
+int BrowserAccessibilityInterface::selectionCount() const
{
int start = 0;
int end = 0;
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &start);
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &end);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &start);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &end);
if (start != end)
return 1;
return 0;
}
-int BrowserAccessibilityQt::offsetAtPoint(const QPoint &/*point*/) const
+int BrowserAccessibilityInterface::offsetAtPoint(const QPoint &/*point*/) const
{
QT_NOT_YET_IMPLEMENTED
return 0;
}
-void BrowserAccessibilityQt::selection(int selectionIndex, int *startOffset, int *endOffset) const
+void BrowserAccessibilityInterface::selection(int selectionIndex, int *startOffset, int *endOffset) const
{
Q_ASSERT(startOffset && endOffset);
*startOffset = 0;
*endOffset = 0;
if (selectionIndex != 0)
return;
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, startOffset);
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, endOffset);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, startOffset);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, endOffset);
}
-QString BrowserAccessibilityQt::text(int startOffset, int endOffset) const
+QString BrowserAccessibilityInterface::text(int startOffset, int endOffset) const
{
return text(QAccessible::Value).mid(startOffset, endOffset - startOffset);
}
-void BrowserAccessibilityQt::removeSelection(int selectionIndex)
+void BrowserAccessibilityInterface::removeSelection(int selectionIndex)
{
- manager()->SetSelection(AXRange(CreatePositionAt(0), CreatePositionAt(0)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(0), q->CreatePositionAt(0)));
}
-void BrowserAccessibilityQt::setCursorPosition(int position)
+void BrowserAccessibilityInterface::setCursorPosition(int position)
{
- manager()->SetSelection(AXRange(CreatePositionAt(position), CreatePositionAt(position)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(position), q->CreatePositionAt(position)));
}
-void BrowserAccessibilityQt::setSelection(int selectionIndex, int startOffset, int endOffset)
+void BrowserAccessibilityInterface::setSelection(int selectionIndex, int startOffset, int endOffset)
{
if (selectionIndex != 0)
return;
- manager()->SetSelection(AXRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(startOffset), q->CreatePositionAt(endOffset)));
}
-int BrowserAccessibilityQt::characterCount() const
+int BrowserAccessibilityInterface::characterCount() const
{
return text(QAccessible::Value).length();
}
-void BrowserAccessibilityQt::scrollToSubstring(int startIndex, int endIndex)
+void BrowserAccessibilityInterface::scrollToSubstring(int startIndex, int endIndex)
{
int count = characterCount();
if (startIndex < endIndex && endIndex < count)
- manager()->ScrollToMakeVisible(*this,
- GetRootFrameHypertextRangeBoundsRect(
- startIndex,
- endIndex - startIndex,
- ui::AXClippingBehavior::kUnclipped));
+ q->manager()->ScrollToMakeVisible(*q,
+ q->GetRootFrameHypertextRangeBoundsRect(
+ startIndex,
+ endIndex - startIndex,
+ ui::AXClippingBehavior::kUnclipped));
}
-QVariant BrowserAccessibilityQt::currentValue() const
+QVariant BrowserAccessibilityInterface::currentValue() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &value)) {
result = (double) value;
}
return result;
}
-void BrowserAccessibilityQt::setCurrentValue(const QVariant &value)
+void BrowserAccessibilityInterface::setCurrentValue(const QVariant &value)
{
// not yet implemented anywhere in blink
QT_NOT_YET_IMPLEMENTED
}
-QVariant BrowserAccessibilityQt::maximumValue() const
+QVariant BrowserAccessibilityInterface::maximumValue() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, &value)) {
result = (double) value;
}
return result;
}
-QVariant BrowserAccessibilityQt::minimumValue() const
+QVariant BrowserAccessibilityInterface::minimumValue() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, &value)) {
result = (double) value;
}
return result;
}
-QVariant BrowserAccessibilityQt::minimumStepSize() const
+QVariant BrowserAccessibilityInterface::minimumStepSize() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, &value)) {
result = (double) value;
}
return result;
}
-QAccessibleInterface *BrowserAccessibilityQt::cellAt(int row, int column) const
+QAccessibleInterface *BrowserAccessibilityInterface::cellAt(int row, int column) const
{
int columns = 0;
int rows = 0;
- if (!GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns) ||
- !GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows) ||
- columns <= 0 ||
- rows <= 0) {
- return 0;
+ if (!q->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns)
+ || !q->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows)
+ || columns <= 0
+ || rows <= 0) {
+ return nullptr;
}
if (row < 0 || row >= rows || column < 0 || column >= columns)
- return 0;
+ return nullptr;
- base::Optional<int> cell_id = GetCellId(row, column);
- BrowserAccessibility* cell = cell_id ? manager()->GetFromID(*cell_id) : nullptr;
- if (cell) {
- QAccessibleInterface *iface = static_cast<BrowserAccessibilityQt*>(cell);
- return iface;
- }
+ absl::optional<int> cell_id = q->GetCellId(row, column);
+ content::BrowserAccessibility *cell = cell_id ? q->manager()->GetFromID(*cell_id) : nullptr;
+ if (cell)
+ return content::toQAccessibleInterface(cell);
return nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::caption() const
+QAccessibleInterface *BrowserAccessibilityInterface::caption() const
{
return nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::summary() const
+QAccessibleInterface *BrowserAccessibilityInterface::summary() const
{
return nullptr;
}
-QString BrowserAccessibilityQt::columnDescription(int column) const
+QString BrowserAccessibilityInterface::columnDescription(int column) const
{
return QString();
}
-QString BrowserAccessibilityQt::rowDescription(int row) const
+QString BrowserAccessibilityInterface::rowDescription(int row) const
{
return QString();
}
-int BrowserAccessibilityQt::columnCount() const
+int BrowserAccessibilityInterface::columnCount() const
{
int columns = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns))
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns))
return columns;
-
return 0;
}
-int BrowserAccessibilityQt::rowCount() const
+int BrowserAccessibilityInterface::rowCount() const
{
int rows = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows))
- return rows;
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows))
+ return rows;
return 0;
}
-int BrowserAccessibilityQt::selectedCellCount() const
+int BrowserAccessibilityInterface::selectedCellCount() const
{
return 0;
}
-int BrowserAccessibilityQt::selectedColumnCount() const
+int BrowserAccessibilityInterface::selectedColumnCount() const
{
return 0;
}
-int BrowserAccessibilityQt::selectedRowCount() const
+int BrowserAccessibilityInterface::selectedRowCount() const
{
return 0;
}
-QList<QAccessibleInterface *> BrowserAccessibilityQt::selectedCells() const
+QList<QAccessibleInterface *> BrowserAccessibilityInterface::selectedCells() const
{
return QList<QAccessibleInterface *>();
}
-QList<int> BrowserAccessibilityQt::selectedColumns() const
+QList<int> BrowserAccessibilityInterface::selectedColumns() const
{
return QList<int>();
}
-QList<int> BrowserAccessibilityQt::selectedRows() const
+QList<int> BrowserAccessibilityInterface::selectedRows() const
{
return QList<int>();
}
-bool BrowserAccessibilityQt::isColumnSelected(int /*column*/) const
+bool BrowserAccessibilityInterface::isColumnSelected(int /*column*/) const
{
return false;
}
-bool BrowserAccessibilityQt::isRowSelected(int /*row*/) const
+bool BrowserAccessibilityInterface::isRowSelected(int /*row*/) const
{
return false;
}
-bool BrowserAccessibilityQt::selectRow(int /*row*/)
+bool BrowserAccessibilityInterface::selectRow(int /*row*/)
{
return false;
}
-bool BrowserAccessibilityQt::selectColumn(int /*column*/)
+bool BrowserAccessibilityInterface::selectColumn(int /*column*/)
{
return false;
}
-bool BrowserAccessibilityQt::unselectRow(int /*row*/)
+bool BrowserAccessibilityInterface::unselectRow(int /*row*/)
{
return false;
}
-bool BrowserAccessibilityQt::unselectColumn(int /*column*/)
+bool BrowserAccessibilityInterface::unselectColumn(int /*column*/)
{
return false;
}
-int BrowserAccessibilityQt::columnExtent() const
+int BrowserAccessibilityInterface::columnExtent() const
{
return 1;
}
-QList<QAccessibleInterface *> BrowserAccessibilityQt::columnHeaderCells() const
+QList<QAccessibleInterface *> BrowserAccessibilityInterface::columnHeaderCells() const
{
return QList<QAccessibleInterface*>();
}
-int BrowserAccessibilityQt::columnIndex() const
+int BrowserAccessibilityInterface::columnIndex() const
{
int column = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex, &column))
- return column;
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex, &column))
+ return column;
return 0;
}
-int BrowserAccessibilityQt::rowExtent() const
+int BrowserAccessibilityInterface::rowExtent() const
{
return 1;
}
-QList<QAccessibleInterface *> BrowserAccessibilityQt::rowHeaderCells() const
+QList<QAccessibleInterface *> BrowserAccessibilityInterface::rowHeaderCells() const
{
return QList<QAccessibleInterface*>();
}
-int BrowserAccessibilityQt::rowIndex() const
+int BrowserAccessibilityInterface::rowIndex() const
{
int row = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row))
- return row;
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row))
+ return row;
return 0;
}
-bool BrowserAccessibilityQt::isSelected() const
+bool BrowserAccessibilityInterface::isSelected() const
{
return false;
}
-QAccessibleInterface *BrowserAccessibilityQt::table() const
+content::BrowserAccessibility *BrowserAccessibilityInterface::findTable() const
{
- BrowserAccessibility* find_table = PlatformGetParent();
- while (find_table && find_table->GetRole() != ax::mojom::Role::kTable)
- find_table = find_table->PlatformGetParent();
- if (!find_table)
- return nullptr;
- return static_cast<BrowserAccessibilityQt*>(find_table);
+ content::BrowserAccessibility *parent = q->PlatformGetParent();
+ while (parent && parent->GetRole() != ax::mojom::Role::kTable)
+ parent = parent->PlatformGetParent();
+
+ return parent;
}
-void BrowserAccessibilityQt::modelChange(QAccessibleTableModelChangeEvent *)
+QAccessibleInterface *BrowserAccessibilityInterface::table() const
{
+ content::BrowserAccessibility *table = findTable();
+ Q_ASSERT(table);
+ return content::toQAccessibleInterface(table);
+}
+void BrowserAccessibilityInterface::modelChange(QAccessibleTableModelChangeEvent *)
+{
}
-} // namespace content
+} // namespace QtWebEngineCore
#endif // QT_CONFIG(accessibility)
+namespace content {
+
+// static
+std::unique_ptr<BrowserAccessibility> BrowserAccessibility::Create(BrowserAccessibilityManager *man, ui::AXNode *node)
+{
+#if QT_CONFIG(accessibility)
+ return std::unique_ptr<BrowserAccessibility>(new QtWebEngineCore::BrowserAccessibilityQt(man, node));
+#else
+ Q_UNUSED(man);
+ Q_UNUSED(node);
+ return nullptr;
+#endif // #if QT_CONFIG(accessibility)
+}
+
+#if QT_CONFIG(accessibility)
+QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj)
+{
+ return static_cast<QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface;
+}
+
+const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *obj)
+{
+ return static_cast<const QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface;
+}
+#endif // #if QT_CONFIG(accessibility)
+
+} // namespace content
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 32a4fc76b..598aa3ef5 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -1,153 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef BROWSER_ACCESSIBILITY_QT_H
#define BROWSER_ACCESSIBILITY_QT_H
-#include <QtGui/qaccessible.h>
-#include "content/browser/accessibility/browser_accessibility.h"
+#include <QtGui/qtguiglobal.h>
#if QT_CONFIG(accessibility)
+QT_FORWARD_DECLARE_CLASS(QAccessibleInterface)
namespace content {
+class BrowserAccessibility;
-class BrowserAccessibilityQt
- : public BrowserAccessibility
- , public QAccessibleInterface
- , public QAccessibleActionInterface
- , public QAccessibleTextInterface
- , public QAccessibleValueInterface
- , public QAccessibleTableInterface
- , public QAccessibleTableCellInterface
-{
-public:
- BrowserAccessibilityQt();
-
- // QAccessibleInterface
- bool isValid() const override;
- QObject *object() const override;
- QAccessibleInterface *childAt(int x, int y) const override;
- void *interface_cast(QAccessible::InterfaceType type) override;
-
- // navigation, hierarchy
- QAccessibleInterface *parent() const override;
- QAccessibleInterface *child(int index) const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- int indexOfChild(const QAccessibleInterface *) const override;
-
- // properties and state
- QString text(QAccessible::Text t) const override;
- void setText(QAccessible::Text t, const QString &text) override;
- QRect rect() const override;
- QAccessible::Role role() const override;
- QAccessible::State state() const override;
-
- // BrowserAccessible
- void Destroy() override;
-
- // QAccessibleActionInterface
- QStringList actionNames() const override;
- void doAction(const QString &actionName) override;
- QStringList keyBindingsForAction(const QString &actionName) const override;
-
- // QAccessibleTextInterface
- void addSelection(int startOffset, int endOffset) override;
- QString attributes(int offset, int *startOffset, int *endOffset) const override;
- int cursorPosition() const override;
- QRect characterRect(int offset) const override;
- int selectionCount() const override;
- int offsetAtPoint(const QPoint &point) const override;
- void selection(int selectionIndex, int *startOffset, int *endOffset) const override;
- QString text(int startOffset, int endOffset) const override;
- void removeSelection(int selectionIndex) override;
- void setCursorPosition(int position) override;
- void setSelection(int selectionIndex, int startOffset, int endOffset) override;
- int characterCount() const override;
- void scrollToSubstring(int startIndex, int endIndex) override;
-
- // QAccessibleValueInterface
- QVariant currentValue() const override;
- void setCurrentValue(const QVariant &value) override;
- QVariant maximumValue() const override;
- QVariant minimumValue() const override;
- QVariant minimumStepSize() const override;
-
- // QAccessibleTableInterface
- QAccessibleInterface *cellAt(int row, int column) const override;
- QAccessibleInterface *caption() const override;
- QAccessibleInterface *summary() const override;
- QString columnDescription(int column) const override;
- QString rowDescription(int row) const override;
- int columnCount() const override;
- int rowCount() const override;
- // selection
- int selectedCellCount() const override;
- int selectedColumnCount() const override;
- int selectedRowCount() const override;
- QList<QAccessibleInterface*> selectedCells() const override;
- QList<int> selectedColumns() const override;
- QList<int> selectedRows() const override;
- bool isColumnSelected(int column) const override;
- bool isRowSelected(int row) const override;
- bool selectRow(int row) override;
- bool selectColumn(int column) override;
- bool unselectRow(int row) override;
- bool unselectColumn(int column) override;
-
- // QAccessibleTableCellInterface
- int columnExtent() const override;
- QList<QAccessibleInterface*> columnHeaderCells() const override;
- int columnIndex() const override;
- int rowExtent() const override;
- QList<QAccessibleInterface*> rowHeaderCells() const override;
- int rowIndex() const override;
- bool isSelected() const override;
- QAccessibleInterface* table() const override;
-
- void modelChange(QAccessibleTableModelChangeEvent *event) override;
-};
-
-const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj);
-QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc);
+QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj);
+const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *obj);
} // namespace content
-
#endif // QT_CONFIG(accessibility)
-#endif
+
+#endif // BROWSER_ACCESSIBILITY_QT_H
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index 51a910018..9021dbb98 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -1,46 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "browser_main_parts_qt.h"
#include "api/qwebenginemessagepumpscheduler_p.h"
+#include "base/message_loop/message_pump.h"
#include "base/message_loop/message_pump_for_ui.h"
#include "base/process/process.h"
#include "base/task/current_thread.h"
@@ -51,8 +16,8 @@
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
#include "components/device_event_log/device_event_log.h"
+#include "components/performance_manager/embedder/graph_features.h"
#include "components/performance_manager/embedder/performance_manager_lifetime.h"
-#include "components/performance_manager/embedder/performance_manager_registry.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/performance_manager.h"
#include "content/public/browser/browser_main_parts.h"
@@ -60,33 +25,44 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/result_codes.h"
#include "extensions/buildflags/buildflags.h"
+#include "ppapi/buildflags/buildflags.h"
+#include "select_file_dialog_factory_qt.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "type_conversion.h"
+#include "ui/display/screen.h"
+
#if BUILDFLAG(ENABLE_EXTENSIONS)
-#include "content/public/browser/plugin_service.h"
#include "extensions/common/constants.h"
#include "extensions/common/extensions_client.h"
#include "extensions/extensions_browser_client_qt.h"
#include "extensions/extension_system_factory_qt.h"
-#include "extensions/plugin_service_filter_qt.h"
#include "common/extensions/extensions_client_qt.h"
-#endif //BUILDFLAG(ENABLE_EXTENSIONS)
-#include "select_file_dialog_factory_qt.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/service.h"
-#include "ui/display/screen.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
+#if BUILDFLAG(ENABLE_PLUGINS)
+#include "content/public/browser/plugin_service.h"
+#include "extensions/plugin_service_filter_qt.h"
+#endif // BUILDFLAG(ENABLE_PLUGINS)
#include "web_engine_context.h"
#include "web_usb_detector_qt.h"
+#include <QDeadlineTimer>
#include <QtGui/qtgui-config.h>
+#include <QStandardPaths>
#if QT_CONFIG(opengl)
#include "ui/gl/gl_context.h"
#include <QOpenGLContext>
#endif
-#if defined(OS_MAC)
-#include "base/message_loop/message_pump_mac.h"
+#if BUILDFLAG(IS_MAC)
+#include "base/message_loop/message_pump_apple.h"
+#include "services/device/public/cpp/geolocation/geolocation_manager.h"
+#include "services/device/public/cpp/geolocation/system_geolocation_source.h"
#include "ui/base/idle/idle.h"
#endif
@@ -96,6 +72,10 @@
#include "desktop_screen_qt.h"
#endif
+#if defined(Q_OS_LINUX)
+#include "components/os_crypt/sync/key_storage_config_linux.h"
+#include "components/os_crypt/sync/os_crypt.h"
+#endif
namespace QtWebEngineCore {
@@ -142,12 +122,17 @@ public:
{
// NOTE: This method may called from any thread at any time.
ensureDelegate();
- m_scheduler.scheduleWork();
+ m_scheduler.scheduleImmediateWork();
}
- void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override
+ void ScheduleDelayedWork(const Delegate::NextWorkInfo &next_work_info) override
{
// NOTE: This method may called from any thread at any time.
+ ScheduleDelayedWork(next_work_info.delayed_run_time);
+ }
+
+ void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time)
+ {
ensureDelegate();
m_scheduler.scheduleDelayedWork(GetTimeIntervalMilliseconds(delayed_work_time));
}
@@ -161,62 +146,19 @@ private:
seqMan->controller_.get());
}
}
- // Both Qt and Chromium keep track of the current GL context by using
- // thread-local variables, and naturally they are completely unaware of each
- // other. As a result, when a QOpenGLContext is made current, the previous
- // gl::GLContext is not released, and vice-versa. This is fine as long as
- // each thread uses exclusively either Qt or Chromium GL bindings, which is
- // usually the case.
- //
- // The only exception is when the GL driver is considered thread-unsafe
- // (QOpenGLContext::supportsThreadedOpenGL() is false), in which case we
- // have to run all GL operations, including Chromium's GPU service, on the
- // UI thread. Now the bindings are being mixed and both Qt and Chromium get
- // quite confused regarding the current state of the surface.
- //
- // To get this to work we have to release the current QOpenGLContext before
- // executing any tasks from Chromium's GPU service and the gl::GLContext
- // afterwards. Since GPU service just posts tasks to the UI thread task
- // runner, we'll have to instrument the entire UI thread message pump.
- class ScopedGLContextChecker
- {
-#if QT_CONFIG(opengl)
- public:
- ScopedGLContextChecker()
- {
- if (!m_enabled)
- return;
-
- if (QOpenGLContext *context = QOpenGLContext::currentContext())
- context->doneCurrent();
- }
-
- ~ScopedGLContextChecker()
- {
- if (!m_enabled)
- return;
-
- if (gl::GLContext *context = gl::GLContext::GetCurrent())
- context->ReleaseCurrent(nullptr);
- }
-
- private:
- bool m_enabled = WebEngineContext::isGpuServiceOnUIThread();
-#endif // QT_CONFIG(opengl)
- };
-
void handleScheduledWork()
{
- ScopedGLContextChecker glContextChecker;
-
+ QDeadlineTimer timer(std::chrono::milliseconds(2));
base::MessagePump::Delegate::NextWorkInfo more_work_info = m_delegate->DoWork();
+ while (more_work_info.is_immediate() && !timer.hasExpired())
+ more_work_info = m_delegate->DoWork();
if (more_work_info.is_immediate())
- return ScheduleWork();
+ return m_scheduler.scheduleImmediateWork();
if (m_delegate->DoIdleWork())
- return ScheduleWork();
+ return m_scheduler.scheduleIdleWork();
ScheduleDelayedWork(more_work_info.delayed_run_time);
}
@@ -225,6 +167,25 @@ private:
QWebEngineMessagePumpScheduler m_scheduler;
};
+#if BUILDFLAG(IS_MAC)
+class FakeGeolocationSource : public device::SystemGeolocationSource
+{
+public:
+ FakeGeolocationSource() = default;
+ ~FakeGeolocationSource() override = default;
+
+ // SystemGeolocationSource implementation:
+ void StartWatchingPosition(bool) override {}
+ void StopWatchingPosition() override {}
+ void RegisterPermissionUpdateCallback(PermissionUpdateCallback callback)
+ {
+ callback.Run(device::LocationSystemPermissionStatus::kDenied);
+ }
+ void RegisterPositionUpdateCallback(PositionUpdateCallback callback) {}
+ void RequestPermission() override {}
+};
+#endif // BUILDFLAG(IS_MAC)
+
std::unique_ptr<base::MessagePump> messagePumpFactory()
{
static bool madePrimaryPump = false;
@@ -232,8 +193,8 @@ std::unique_ptr<base::MessagePump> messagePumpFactory()
madePrimaryPump = true;
return std::make_unique<MessagePumpForUIQt>();
}
-#if defined(OS_MAC)
- return base::MessagePumpMac::Create();
+#if BUILDFLAG(IS_MAC)
+ return base::message_pump_apple::Create();
#else
return std::make_unique<base::MessagePumpForUI>();
#endif
@@ -244,31 +205,44 @@ int BrowserMainPartsQt::PreEarlyInitialization()
#if BUILDFLAG(ENABLE_EXTENSIONS)
content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(extensions::kExtensionScheme);
#endif //ENABLE_EXTENSIONS
- return 0;
+ return content::RESULT_CODE_NORMAL_EXIT;
}
-void BrowserMainPartsQt::PreMainMessageLoopStart()
+void BrowserMainPartsQt::PreCreateMainMessageLoop()
{
+#if BUILDFLAG(IS_MAC)
+ m_geolocationManager = std::make_unique<device::GeolocationManager>(std::make_unique<FakeGeolocationSource>());
+#endif
}
-void BrowserMainPartsQt::PostMainMessageLoopStart()
+void BrowserMainPartsQt::PostCreateMainMessageLoop()
{
if (!device_event_log::IsInitialized())
device_event_log::Initialize(0 /* default max entries */);
+
+#if defined(Q_OS_LINUX)
+ auto config = std::make_unique<os_crypt::Config>();
+ config->product_name = "Qt WebEngine";
+ config->should_use_preference = false;
+ config->user_data_path = toFilePath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
+ OSCrypt::SetConfig(std::move(config));
+#endif
}
-void BrowserMainPartsQt::PreMainMessageLoopRun()
+int BrowserMainPartsQt::PreMainMessageLoopRun()
{
- ui::SelectFileDialog::SetFactory(new SelectFileDialogFactoryQt());
+ ui::SelectFileDialog::SetFactory(std::make_unique<SelectFileDialogFactoryQt>());
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionsClient::Set(new extensions::ExtensionsClientQt());
extensions::ExtensionsBrowserClient::Set(new extensions::ExtensionsBrowserClientQt());
extensions::ExtensionSystemFactoryQt::GetInstance();
+#if BUILDFLAG(ENABLE_PLUGINS)
content::PluginService *plugin_service = content::PluginService::GetInstance();
plugin_service->SetFilter(extensions::PluginServiceFilterQt::GetInstance());
-#endif //ENABLE_EXTENSIONS
+#endif // BUILDFLAG(ENABLE_PLUGINS)
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
if (base::FeatureList::IsEnabled(features::kWebUsb)) {
m_webUsbDetector.reset(new WebUsbDetectorQt());
@@ -277,13 +251,12 @@ void BrowserMainPartsQt::PreMainMessageLoopRun()
base::BindOnce(&WebUsbDetectorQt::Initialize,
base::Unretained(m_webUsbDetector.get())));
}
+ return content::RESULT_CODE_NORMAL_EXIT;
}
void BrowserMainPartsQt::PostMainMessageLoopRun()
{
- performance_manager_registry_->TearDown();
- performance_manager_registry_.reset();
- performance_manager::DestroyPerformanceManager(std::move(performance_manager_));
+ performance_manager_lifetime_.reset();
m_webUsbDetector.reset();
@@ -294,19 +267,19 @@ void BrowserMainPartsQt::PostMainMessageLoopRun()
int BrowserMainPartsQt::PreCreateThreads()
{
- base::ThreadRestrictions::SetIOAllowed(true);
-
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
ui::InitIdleMonitor();
#endif
// Like ChromeBrowserMainExtraPartsViews::PreCreateThreads does.
#if defined(Q_OS_WIN)
display::Screen::SetScreenInstance(new display::win::ScreenWin);
+#elif defined(Q_OS_DARWIN)
+ display::Screen::SetScreenInstance(display::CreateNativeScreen());
#else
display::Screen::SetScreenInstance(new DesktopScreenQt);
#endif
- return 0;
+ return content::RESULT_CODE_NORMAL_EXIT;
}
static void CreatePoliciesAndDecorators(performance_manager::Graph *graph)
@@ -316,10 +289,17 @@ static void CreatePoliciesAndDecorators(performance_manager::Graph *graph)
void BrowserMainPartsQt::PostCreateThreads()
{
- performance_manager_ =
- performance_manager::CreatePerformanceManagerWithDefaultDecorators(
- base::BindOnce(&QtWebEngineCore::CreatePoliciesAndDecorators));
- performance_manager_registry_ = performance_manager::PerformanceManagerRegistry::Create();
+ performance_manager_lifetime_ =
+ std::make_unique<performance_manager::PerformanceManagerLifetime>(
+ performance_manager::GraphFeatures::WithDefault(),
+ base::BindOnce(&QtWebEngineCore::CreatePoliciesAndDecorators));
}
+#if BUILDFLAG(IS_MAC)
+device::GeolocationManager *BrowserMainPartsQt::GetGeolocationManager()
+{
+ return m_geolocationManager.get();
+}
+#endif
+
} // namespace QtWebEngineCore
diff --git a/src/core/browser_main_parts_qt.h b/src/core/browser_main_parts_qt.h
index 07e8ffe98..6828552b7 100644
--- a/src/core/browser_main_parts_qt.h
+++ b/src/core/browser_main_parts_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef BROWSER_MAIN_PARTS_QT_H
#define BROWSER_MAIN_PARTS_QT_H
@@ -52,9 +16,12 @@ namespace content {
class ServiceManagerConnection;
}
+namespace device {
+class GeolocationManager;
+}
+
namespace performance_manager {
-class PerformanceManager;
-class PerformanceManagerRegistry;
+class PerformanceManagerLifetime;
}
namespace QtWebEngineCore {
@@ -68,18 +35,23 @@ public:
~BrowserMainPartsQt() override = default;
int PreEarlyInitialization() override;
- void PreMainMessageLoopStart() override;
- void PostMainMessageLoopStart() override;
- void PreMainMessageLoopRun() override;
+ void PreCreateMainMessageLoop() override;
+ void PostCreateMainMessageLoop() override;
+ int PreMainMessageLoopRun() override;
void PostMainMessageLoopRun() override;
int PreCreateThreads() override;
void PostCreateThreads() override;
+#if BUILDFLAG(IS_MAC)
+ device::GeolocationManager *GetGeolocationManager();
+#endif
+
private:
- DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt);
- std::unique_ptr<performance_manager::PerformanceManager> performance_manager_;
- std::unique_ptr<performance_manager::PerformanceManagerRegistry> performance_manager_registry_;
+ std::unique_ptr<performance_manager::PerformanceManagerLifetime> performance_manager_lifetime_;
std::unique_ptr<WebUsbDetectorQt> m_webUsbDetector;
+#if BUILDFLAG(IS_MAC)
+ std::unique_ptr<device::GeolocationManager> m_geolocationManager;
+#endif
};
} // namespace QtWebEngineCore
diff --git a/src/core/browser_message_filter_qt.cpp b/src/core/browser_message_filter_qt.cpp
index 500644593..e8fcb994a 100644
--- a/src/core/browser_message_filter_qt.cpp
+++ b/src/core/browser_message_filter_qt.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "browser_message_filter_qt.h"
#include "chrome/browser/profiles/profile.h"
-#include "content/public/browser/plugin_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
@@ -85,14 +48,14 @@ void BrowserMessageFilterQt::OnRequestStorageAccessSync(int render_frame_id,
IPC::Message* reply_msg)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- base::Callback<void(bool)> callback = base::Bind(
+ auto callback = base::BindOnce(
&BrowserMessageFilterQt::OnRequestStorageAccessSyncResponse,
base::WrapRefCounted(this), reply_msg);
OnRequestStorageAccess(render_frame_id,
origin_url,
top_origin_url,
storage_type,
- callback);
+ std::move(callback));
}
void BrowserMessageFilterQt::OnRequestStorageAccessSyncResponse(IPC::Message *reply_msg, bool allowed)
@@ -108,14 +71,14 @@ void BrowserMessageFilterQt::OnRequestStorageAccessAsync(int render_frame_id,
int storage_type)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- base::Callback<void(bool)> callback = base::Bind(
+ auto callback = base::BindOnce(
&BrowserMessageFilterQt::OnRequestStorageAccessAsyncResponse,
base::WrapRefCounted(this), render_frame_id, request_id);
OnRequestStorageAccess(render_frame_id,
origin_url,
top_origin_url,
storage_type,
- callback);
+ std::move(callback));
}
void BrowserMessageFilterQt::OnRequestStorageAccessAsyncResponse(int render_frame_id,
@@ -129,12 +92,12 @@ void BrowserMessageFilterQt::OnRequestStorageAccess(int /*render_frame_id*/,
const GURL &origin_url,
const GURL &top_origin_url,
int /*storage_type*/,
- base::Callback<void(bool)> callback)
+ base::OnceCallback<void(bool)> callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
bool allowed = m_profileData->canGetCookies(toQt(top_origin_url), toQt(origin_url));
- callback.Run(allowed);
+ std::move(callback).Run(allowed);
}
} // namespace QtWebEngineCore
diff --git a/src/core/browser_message_filter_qt.h b/src/core/browser_message_filter_qt.h
index 85de0486a..0f5721c82 100644
--- a/src/core/browser_message_filter_qt.h
+++ b/src/core/browser_message_filter_qt.h
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef BROWSER_MESSAGE_FILTER_QT_H
#define BROWSER_MESSAGE_FILTER_QT_H
-#include "base/callback.h"
+#include "base/functional/callback.h"
#include "content/public/browser/browser_message_filter.h"
class GURL;
@@ -84,7 +48,7 @@ private:
const GURL &origin_url,
const GURL &top_origin_url,
int storage_type,
- base::Callback<void(bool)> callback);
+ base::OnceCallback<void(bool)> callback);
ProfileIODataQt *m_profileData;
};
diff --git a/src/core/browsing_data_remover_delegate_qt.cpp b/src/core/browsing_data_remover_delegate_qt.cpp
index 6e79ab6c6..eb33fb992 100644
--- a/src/core/browsing_data_remover_delegate_qt.cpp
+++ b/src/core/browsing_data_remover_delegate_qt.cpp
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "browsing_data_remover_delegate_qt.h"
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/public/browser/browsing_data_remover.h"
@@ -86,7 +50,8 @@ void BrowsingDataRemoverDelegateQt::RemoveEmbedderData(const base::Time &delete_
std::move(callback).Run(0);
}
-std::vector<std::string> BrowsingDataRemoverDelegateQt::GetDomainsForDeferredCookieDeletion(uint64_t)
+std::vector<std::string> BrowsingDataRemoverDelegateQt::GetDomainsForDeferredCookieDeletion(
+ content::StoragePartition *, uint64_t)
{
return {};
}
diff --git a/src/core/browsing_data_remover_delegate_qt.h b/src/core/browsing_data_remover_delegate_qt.h
index a10409f39..d33af4acb 100644
--- a/src/core/browsing_data_remover_delegate_qt.h
+++ b/src/core/browsing_data_remover_delegate_qt.h
@@ -1,45 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef BROWSING_DATA_REMOVER_DELEGATE_QT_H
#define BROWSING_DATA_REMOVER_DELEGATE_QT_H
+#include <cstdint>
+
#include "content/public/browser/browsing_data_remover_delegate.h"
namespace QtWebEngineCore {
@@ -53,13 +19,15 @@ public:
content::BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher GetOriginTypeMatcher() override;
bool MayRemoveDownloadHistory() override;
void RemoveEmbedderData(
- const base::Time &delete_begin,
- const base::Time &delete_end,
- uint64_t remove_mask,
- content::BrowsingDataFilterBuilder *filter_builder,
- uint64_t origin_type_mask,
- base::OnceCallback<void(/*failed_data_types=*/uint64_t)> callback) override;
- std::vector<std::string> GetDomainsForDeferredCookieDeletion(uint64_t) override;
+ const base::Time &delete_begin,
+ const base::Time &delete_end,
+ uint64_t remove_mask,
+ content::BrowsingDataFilterBuilder *filter_builder,
+ uint64_t origin_type_mask,
+ base::OnceCallback<void(/*failed_data_types=*/uint64_t)> callback) override;
+ std::vector<std::string> GetDomainsForDeferredCookieDeletion(
+ content::StoragePartition *storage_partition,
+ uint64_t remove_mask) override;
};
} // namespace QtWebEngineCore
diff --git a/src/core/build_config_qt.h b/src/core/build_config_qt.h
index 9c7a77d65..5f6978e13 100644
--- a/src/core/build_config_qt.h
+++ b/src/core/build_config_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef BUILD_CONFIG_QT
#define BUILD_CONFIG_QT
diff --git a/src/core/certificate_error_controller.cpp b/src/core/certificate_error_controller.cpp
index d9a07ae47..014d74500 100644
--- a/src/core/certificate_error_controller.cpp
+++ b/src/core/certificate_error_controller.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "certificate_error_controller.h"
@@ -78,9 +42,10 @@ ASSERT_ENUMS_MATCH(QWebEngineCertificateError::CertificateSymantecLegacy,
net::ERR_CERT_SYMANTEC_LEGACY)
ASSERT_ENUMS_MATCH(QWebEngineCertificateError::CertificateKnownInterceptionBlocked,
net::ERR_CERT_KNOWN_INTERCEPTION_BLOCKED)
-ASSERT_ENUMS_MATCH(QWebEngineCertificateError::SslObsoleteVersion,
- net::ERR_SSL_OBSOLETE_VERSION)
-// ASSERT_ENUMS_MATCH(QWebEngineCertificateError::CertificateErrorEnd, net::ERR_CERT_END)
+// net::ERR_SSL_OBSOLETE_VERSION was removed again in Chromium 98
+//ASSERT_ENUMS_MATCH(QWebEngineCertificateError::SslObsoleteVersion,
+// net::ERR_SSL_OBSOLETE_VERSION)
+//ASSERT_ENUMS_MATCH(QWebEngineCertificateError::CertificateErrorEnd, net::ERR_CERT_END)
// Copied from chrome/browser/ssl/ssl_error_handler.cc:
static int IsCertErrorFatal(int cert_error)
@@ -98,7 +63,6 @@ static int IsCertErrorFatal(int cert_error)
case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED:
case net::ERR_CERT_SYMANTEC_LEGACY:
case net::ERR_CERT_KNOWN_INTERCEPTION_BLOCKED:
- case net::ERR_SSL_OBSOLETE_VERSION:
return false;
case net::ERR_CERT_CONTAINS_ERRORS:
case net::ERR_CERT_REVOKED:
@@ -182,7 +146,7 @@ void CertificateErrorController::deactivate()
}
static QString getQStringForMessageId(int message_id) {
- base::string16 string = l10n_util::GetStringUTF16(message_id);
+ std::u16string string = l10n_util::GetStringUTF16(message_id);
return toQt(string);
}
diff --git a/src/core/certificate_error_controller.h b/src/core/certificate_error_controller.h
index ec3e26806..cbcb60f8a 100644
--- a/src/core/certificate_error_controller.h
+++ b/src/core/certificate_error_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -52,8 +16,10 @@
#define CERTIFICATE_ERROR_CONTROLLER_H
#include "qtwebenginecoreglobal_p.h"
-#include "base/callback.h"
+
+#include "base/functional/callback.h"
#include "content/public/browser/certificate_request_result_type.h"
+
#include "qwebenginecertificateerror.h"
#include <QtCore/QDateTime>
#include <QtCore/QScopedPointer>
@@ -67,7 +33,7 @@ class GURL;
namespace QtWebEngineCore {
-class Q_WEBENGINECORE_PRIVATE_EXPORT CertificateErrorController {
+class Q_WEBENGINECORE_EXPORT CertificateErrorController {
public:
CertificateErrorController(
int cert_error, const net::SSLInfo &ssl_info, const GURL &request_url,
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 4be528f58..28917e6c5 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -1,141 +1,132 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "type_conversion.h"
#include "ozone/gl_context_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "web_contents_view_qt.h"
+#include "web_engine_library_info.h"
#include "base/values.h"
-#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/font_list.h"
+#include "content/public/browser/web_contents_view_delegate.h"
+#include "extensions/buildflags/buildflags.h"
+#include "extensions/common/constants.h"
+#include "gpu/vulkan/buildflags.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
-#include "ui/events/devices/device_data_manager.h"
-#include "ui/events/platform/platform_event_source.h"
-#include "ppapi/buildflags/buildflags.h"
#include <QGuiApplication>
-#include <QScreen>
-#include <QWindow>
#include <QFontDatabase>
-#include <QStringList>
#include <QLibraryInfo>
-#if defined(USE_AURA) && !defined(USE_OZONE)
-#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/gfx/render_text.h"
-#include "ui/gfx/platform_font.h"
-#endif
-
-#if defined(USE_OPENSSL_CERTS)
-#include "net/ssl/openssl_client_key_store.h"
-#endif
-
#if !QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
#include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h"
#endif
+#if BUILDFLAG(ENABLE_VULKAN)
+#include "compositor/vulkan_implementation_qt.h"
+
+#include "gpu/vulkan/init/vulkan_factory.h"
+
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
+#endif // defined(USE_OZONE)
+#endif // defined(ENABLE_VULKAN)
+
void *GetQtXDisplay()
{
return GLContextHelper::getXDisplay();
}
namespace content {
-class WebContentsImpl;
-class WebContentsView;
-class WebContentsViewDelegate;
class RenderViewHostDelegateView;
-WebContentsView* CreateWebContentsView(WebContentsImpl *web_contents,
- WebContentsViewDelegate *,
- RenderViewHostDelegateView **render_view_host_delegate_view)
+std::unique_ptr<WebContentsView> CreateWebContentsView(
+ WebContentsImpl *web_contents,
+ std::unique_ptr<WebContentsViewDelegate> delegate,
+ raw_ptr<RenderViewHostDelegateView>* render_view_host_delegate_view)
{
- QtWebEngineCore::WebContentsViewQt* rv = new QtWebEngineCore::WebContentsViewQt(web_contents);
+ QtWebEngineCore::WebContentsViewQt *rv = new QtWebEngineCore::WebContentsViewQt(web_contents);
*render_view_host_delegate_view = rv;
- return rv;
+ return std::unique_ptr<WebContentsView>(rv);
}
-#if defined(Q_OS_MACOS)
-std::string getQtPrefix()
+#if defined(Q_OS_DARWIN)
+#if defined(QT_MAC_FRAMEWORK_BUILD)
+base::FilePath getSandboxPath()
+{
+ return WebEngineLibraryInfo::getPath(QT_FRAMEWORK_BUNDLE);
+}
+#else
+base::FilePath getSandboxPath()
{
const QString prefix = QLibraryInfo::location(QLibraryInfo::PrefixPath);
- return prefix.toStdString();
+ return QtWebEngineCore::toFilePath(prefix);
}
#endif
-
+#endif
} // namespace content
#if defined(USE_AURA) || defined(USE_OZONE)
namespace content {
// content/common/font_list.h
-std::unique_ptr<base::ListValue> GetFontList_SlowBlocking()
+base::Value::List GetFontList_SlowBlocking()
{
- std::unique_ptr<base::ListValue> font_list(new base::ListValue);
+ base::Value::List font_list;
for (auto family : QFontDatabase::families()){
- std::unique_ptr<base::ListValue> font_item(new base::ListValue());
- font_item->AppendString(family.toStdString());
- font_item->AppendString(family.toStdString()); // localized name.
+ base::Value::List font_item;
+ font_item.Append(family.toStdString());
+ font_item.Append(family.toStdString()); // localized name.
// TODO(yusukes): Support localized family names.
- font_list->Append(std::move(font_item));
+ font_list.Append(std::move(font_item));
}
return font_list;
}
} // namespace content
+#endif // defined(USE_AURA) || defined(USE_OZONE)
-namespace aura {
-class Window;
-}
+#if BUILDFLAG(ENABLE_VULKAN)
+namespace gpu {
+std::unique_ptr<VulkanImplementation> CreateVulkanImplementation(bool use_swiftshader,
+ bool allow_protected_memory)
+{
+#if QT_CONFIG(webengine_vulkan)
+#if BUILDFLAG(IS_APPLE)
+ // TODO: Investigate if we can support MoltenVK.
+ NOTIMPLEMENTED();
+ return nullptr;
+#else
+#if defined(USE_OZONE)
+ return ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone()->CreateVulkanImplementation(
+ use_swiftshader, allow_protected_memory);
+#endif
-namespace wm {
-class ActivationClient;
+#if !BUILDFLAG(IS_WIN)
+ // TODO(samans): Support Swiftshader on more platforms.
+ // https://crbug.com/963988
+ DCHECK(!use_swiftshader) << "Vulkan Swiftshader is not supported on this platform.";
+#endif // !BUILDFLAG(IS_WIN)
-ActivationClient *GetActivationClient(aura::Window *)
-{
+ // Protected memory is supported only on Fuchsia, which uses Ozone, i.e.
+ // VulkanImplementation is initialized above.
+ DCHECK(!allow_protected_memory) << "Protected memory is not supported on this platform.";
+
+ return std::make_unique<VulkanImplementationQt>();
+#endif // BUILDFLAG(IS_APPLE)
+#else
+ NOTREACHED();
return nullptr;
+#endif // QT_CONFIG(webengine_vulkan)
}
-
-} // namespace wm
-#endif // defined(USE_AURA) || defined(USE_OZONE)
+} // namespace gpu
+#endif // BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<ui::OSExchangeDataProvider> ui::OSExchangeDataProviderFactory::CreateProvider()
{
diff --git a/src/core/client_cert_select_controller.cpp b/src/core/client_cert_select_controller.cpp
index 2f2d24716..d6af984c1 100644
--- a/src/core/client_cert_select_controller.cpp
+++ b/src/core/client_cert_select_controller.cpp
@@ -1,50 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "client_cert_select_controller.h"
-#include <base/bind.h>
+#include <base/functional/bind.h>
#include <content/public/browser/client_certificate_delegate.h>
#include <net/cert/x509_certificate.h>
#include <net/ssl/client_cert_identity.h>
#include <net/ssl/ssl_cert_request_info.h>
#include <net/ssl/ssl_info.h>
+#include "net/ssl/ssl_private_key.h"
#include "type_conversion.h"
@@ -93,8 +58,8 @@ void ClientCertSelectController::select(int index)
scoped_refptr<net::X509Certificate> cert = certInfo->certificate();
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
std::move(certInfo),
- base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate,
- base::Passed(std::move(m_delegate)), std::move(cert)));
+ base::BindOnce(&content::ClientCertificateDelegate::ContinueWithCertificate,
+ std::move(m_delegate), std::move(cert)));
return;
}
std::vector<std::string> pem_encoded;
@@ -112,15 +77,16 @@ void ClientCertSelectController::select(const QSslCertificate &certificate)
}
QByteArray derCertificate = certificate.toDer();
scoped_refptr<net::X509Certificate> selectedCert =
- net::X509Certificate::CreateFromBytes(derCertificate.constData(), derCertificate.length());
+ net::X509Certificate::CreateFromBytes(base::make_span((const unsigned char *)derCertificate.constData(),
+ (long unsigned)derCertificate.length()));
for (auto &certInfo : m_clientCerts) {
scoped_refptr<net::X509Certificate> cert = certInfo->certificate();
if (cert->EqualsExcludingChain(selectedCert.get())) {
m_selected = true;
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
std::move(certInfo),
- base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate,
- base::Passed(std::move(m_delegate)), std::move(cert)));
+ base::BindOnce(&content::ClientCertificateDelegate::ContinueWithCertificate,
+ std::move(m_delegate), std::move(cert)));
return;
}
}
diff --git a/src/core/client_cert_select_controller.h b/src/core/client_cert_select_controller.h
index e98c15802..8380a7845 100644
--- a/src/core/client_cert_select_controller.h
+++ b/src/core/client_cert_select_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -70,7 +34,7 @@ class SSLCertRequestInfo;
namespace QtWebEngineCore {
-class Q_WEBENGINECORE_PRIVATE_EXPORT ClientCertSelectController {
+class Q_WEBENGINECORE_EXPORT ClientCertSelectController {
public:
ClientCertSelectController(net::SSLCertRequestInfo *certRequestInfo,
std::vector<std::unique_ptr<net::ClientCertIdentity>> clientCerts,
diff --git a/src/core/client_hints.cpp b/src/core/client_hints.cpp
new file mode 100644
index 000000000..9fa7531da
--- /dev/null
+++ b/src/core/client_hints.cpp
@@ -0,0 +1,177 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "client_hints.h"
+
+#include "profile_qt.h"
+#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
+
+#include "components/embedder_support/user_agent_utils.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/network_service_instance.h"
+#include "extensions/buildflags/buildflags.h"
+#include "services/network/public/cpp/is_potentially_trustworthy.h"
+#include "services/network/public/cpp/network_quality_tracker.h"
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "components/guest_view/browser/guest_view_base.h"
+#endif
+
+namespace QtWebEngineCore {
+
+// based on weblayer/browser/client_hints_factory.cc:
+// Copyright 2020 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.
+
+// static
+ClientHints *ClientHintsFactory::GetForBrowserContext(content::BrowserContext *browser_context)
+{
+ return static_cast<ClientHints*>(GetInstance()->GetServiceForBrowserContext(browser_context, true));
+}
+
+// static
+ClientHintsFactory *ClientHintsFactory::GetInstance()
+{
+ static base::NoDestructor<ClientHintsFactory> factory;
+ return factory.get();
+}
+
+ClientHintsFactory::ClientHintsFactory()
+ : BrowserContextKeyedServiceFactory("ClientHints", BrowserContextDependencyManager::GetInstance())
+{
+}
+
+ClientHintsFactory::~ClientHintsFactory() = default;
+
+KeyedService *ClientHintsFactory::BuildServiceInstanceFor(content::BrowserContext *context) const
+{
+ return new ClientHints(context);
+}
+
+content::BrowserContext *ClientHintsFactory::GetBrowserContextToUse(content::BrowserContext *context) const
+{
+ return context;
+}
+
+// based on components/client_hints/browser/in_memory_client_hints_controller_delegate.cc:
+// Copyright 2022 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.
+
+ClientHints::ClientHints(content::BrowserContext *context)
+ : context_(context)
+{
+}
+
+ClientHints::~ClientHints() = default;
+
+// Enabled Client Hints are only cached and not persisted in this
+// implementation.
+void ClientHints::PersistClientHints(const url::Origin &primary_origin,
+ content::RenderFrameHost *parent_rfh,
+ const std::vector<network::mojom::WebClientHintsType> &client_hints)
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ const GURL primary_url = primary_origin.GetURL();
+ DCHECK(primary_url.is_valid());
+ if (!network::IsUrlPotentiallyTrustworthy(primary_url))
+ return;
+
+ // Client hints should only be enabled when JavaScript is enabled.
+ if (!IsJavaScriptAllowed(primary_url, parent_rfh))
+ return;
+
+ blink::EnabledClientHints enabled_hints;
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(context_)->profileAdapter();
+ for (auto hint : client_hints) {
+ enabled_hints.SetIsEnabled(hint, profileAdapter->clientHintsEnabled());
+ }
+ accept_ch_cache_[primary_origin] = enabled_hints;
+}
+
+// Looks up enabled Client Hints for the URL origin, and adds additional Client
+// Hints if set.
+void ClientHints::GetAllowedClientHintsFromSource(const url::Origin &origin,
+ blink::EnabledClientHints *client_hints)
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(client_hints);
+ // Can not assert this, as we get here for unregistered custom schemes:
+ if (!network::IsOriginPotentiallyTrustworthy(origin))
+ return;
+
+ const auto &it = accept_ch_cache_.find(origin);
+ if (it != accept_ch_cache_.end()) {
+ *client_hints = it->second;
+ }
+
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(context_)->profileAdapter();
+ for (auto hint : additional_hints_)
+ client_hints->SetIsEnabled(hint, profileAdapter->clientHintsEnabled());
+}
+
+void ClientHints::SetAdditionalClientHints(const std::vector<network::mojom::WebClientHintsType> &hints)
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ additional_hints_ = hints;
+}
+
+void ClientHints::ClearAdditionalClientHints()
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ additional_hints_.clear();
+}
+
+network::NetworkQualityTracker *ClientHints::GetNetworkQualityTracker()
+{
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!network_quality_tracker_) {
+ network_quality_tracker_ =
+ std::make_unique<network::NetworkQualityTracker>(
+ base::BindRepeating(&content::GetNetworkService));
+ }
+ return network_quality_tracker_.get();
+}
+
+bool ClientHints::IsJavaScriptAllowed(const GURL &url, content::RenderFrameHost *parent_rfh)
+{
+ content::WebContents *webContents = content::WebContents::FromRenderFrameHost(parent_rfh);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (webContents && guest_view::GuestViewBase::IsGuest(webContents))
+ webContents = guest_view::GuestViewBase::GetTopLevelWebContents(webContents);
+#endif
+
+ if (webContents) {
+ WebContentsDelegateQt* delegate =
+ static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ if (delegate) {
+ WebEngineSettings *settings = delegate->webEngineSettings();
+ if (settings)
+ return settings->testAttribute(QWebEngineSettings::JavascriptEnabled);
+ }
+ }
+ return true;
+}
+
+bool ClientHints::AreThirdPartyCookiesBlocked(const GURL &url, content::RenderFrameHost *rfh)
+{
+ return false; // we probably can not report anything more specific
+}
+
+blink::UserAgentMetadata ClientHints::GetUserAgentMetadata()
+{
+ return static_cast<ProfileQt *>(context_)->userAgentMetadata();
+}
+
+void ClientHints::SetMostRecentMainFrameViewportSize(
+ const gfx::Size& viewport_size) {
+ viewport_size_ = viewport_size;
+}
+
+gfx::Size
+ClientHints::GetMostRecentMainFrameViewportSize() {
+ return viewport_size_;
+}
+} // namespace
diff --git a/src/core/client_hints.h b/src/core/client_hints.h
new file mode 100644
index 000000000..193982d16
--- /dev/null
+++ b/src/core/client_hints.h
@@ -0,0 +1,102 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CLIENT_HINTS_H_
+#define CLIENT_HINTS_H_
+
+// based on components/client_hints/browser/client_hints.h:
+// Copyright 2017 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 "base/memory/raw_ptr.h"
+#include "base/no_destructor.h"
+#include "base/sequence_checker.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/client_hints_controller_delegate.h"
+#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
+
+namespace QtWebEngineCore {
+
+class ClientHints;
+
+class ClientHintsFactory : public BrowserContextKeyedServiceFactory
+{
+public:
+ ClientHintsFactory(const ClientHintsFactory &) = delete;
+ ClientHintsFactory &operator=(const ClientHintsFactory &) = delete;
+
+ static ClientHints *GetForBrowserContext(content::BrowserContext *browser_context);
+ static ClientHintsFactory *GetInstance();
+
+private:
+ friend class base::NoDestructor<ClientHintsFactory>;
+
+ ClientHintsFactory();
+ ~ClientHintsFactory() override;
+
+ // BrowserContextKeyedServiceFactory methods:
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *profile) const override;
+ content::BrowserContext *GetBrowserContextToUse(content::BrowserContext *context) const override;
+};
+
+class ClientHints : public KeyedService, public content::ClientHintsControllerDelegate
+{
+public:
+ ClientHints(content::BrowserContext *context);
+
+ ClientHints(const ClientHints &) = delete;
+ ClientHints &operator=(const ClientHints &) = delete;
+
+ ~ClientHints() override;
+
+ // content::ClientHintsControllerDelegate:
+ network::NetworkQualityTracker *GetNetworkQualityTracker() override;
+
+ void GetAllowedClientHintsFromSource(const url::Origin &origin, blink::EnabledClientHints *client_hints) override;
+
+ bool IsJavaScriptAllowed(const GURL &url, content::RenderFrameHost *parent_rfh) override;
+
+ bool AreThirdPartyCookiesBlocked(const GURL &url, content::RenderFrameHost *rfh) override;
+
+ blink::UserAgentMetadata GetUserAgentMetadata() override;
+
+ void PersistClientHints(const url::Origin &primary_origin,
+ content::RenderFrameHost *parent_rfh,
+ const std::vector<network::mojom::WebClientHintsType> &client_hints) override;
+
+ void SetAdditionalClientHints(const std::vector<network::mojom::WebClientHintsType> &) override;
+
+ void ClearAdditionalClientHints() override;
+
+ void SetMostRecentMainFrameViewportSize(const gfx::Size&) override;
+ gfx::Size GetMostRecentMainFrameViewportSize() override;
+
+private:
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ raw_ptr<content::BrowserContext> context_ = nullptr;
+
+ // Stores enabled Client Hint types for an origin.
+ std::map<url::Origin, blink::EnabledClientHints> accept_ch_cache_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ // Additional Client Hint types for Client Hints Reliability. If additional
+ // hints are set, they would be included by subsequent calls to
+ // GetAllowedClientHintsFromSource.
+ std::vector<network::mojom::WebClientHintsType> additional_hints_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_
+ GUARDED_BY_CONTEXT(sequence_checker_);
+
+ // This stores the viewport size of the most recent visible main frame tree
+ // node. This value is only used when the viewport size cannot be directly
+ // queried such as for prefetch requests and for tab restores.
+ gfx::Size viewport_size_;
+};
+
+} // namespace QtWebEngineCore
+
+#endif
diff --git a/src/core/clipboard_change_observer.h b/src/core/clipboard_change_observer.h
index f9b33fc93..33a382fbe 100644
--- a/src/core/clipboard_change_observer.h
+++ b/src/core/clipboard_change_observer.h
@@ -1,62 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CLIPBOARD_CHANGE_OBSERVER_H
#define CLIPBOARD_CHANGE_OBSERVER_H
#include <QClipboard>
-#include <QMap>
#include <QObject>
+#include "ui/base/clipboard/clipboard_sequence_number_token.h"
+
namespace QtWebEngineCore {
class ClipboardChangeObserver : public QObject {
Q_OBJECT
public:
ClipboardChangeObserver();
- quint64 getSequenceNumber(QClipboard::Mode mode) { return sequenceNumber.value(mode); }
+ const ui::ClipboardSequenceNumberToken &getPrimarySequenceNumber() { return m_primarySequenceNumber; }
+ const ui::ClipboardSequenceNumberToken &getSelectionSequenceNumber() { return m_selectionSequenceNumber; }
private Q_SLOTS:
void trackChange(QClipboard::Mode mode);
private:
- QMap<QClipboard::Mode, quint64> sequenceNumber;
+ ui::ClipboardSequenceNumberToken m_primarySequenceNumber;
+ ui::ClipboardSequenceNumberToken m_selectionSequenceNumber;
};
} // namespace QtWebEngineCore
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index 6549a19da..3f49c6e3c 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -48,17 +12,24 @@
#include "base/logging.h"
#include "base/strings/utf_offset_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/types/variant_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/clipboard_format_type.h"
+#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/base/ui_base_features.h"
+#include <QBuffer>
#include <QGuiApplication>
#include <QImage>
+#include <QImageWriter>
#include <QMimeData>
+#include <memory>
+
namespace QtWebEngineCore {
static void registerMetaTypes()
@@ -77,7 +48,13 @@ ClipboardChangeObserver::ClipboardChangeObserver()
void ClipboardChangeObserver::trackChange(QClipboard::Mode mode)
{
- ++sequenceNumber[mode];
+ if (mode == QClipboard::Clipboard)
+ m_primarySequenceNumber = ui::ClipboardSequenceNumberToken();
+ else if (mode == QClipboard::Selection)
+ m_selectionSequenceNumber = ui::ClipboardSequenceNumberToken();
+ else
+ return;
+ ui::ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
}
} // namespace QtWebEngineCore
@@ -86,12 +63,12 @@ using namespace QtWebEngineCore;
namespace {
-QScopedPointer<QMimeData> uncommittedData;
+std::unique_ptr<QMimeData> uncommittedData;
QMimeData *getUncommittedData()
{
if (!uncommittedData)
uncommittedData.reset(new QMimeData);
- return uncommittedData.data();
+ return uncommittedData.get();
}
} // namespace
@@ -114,50 +91,46 @@ extern void CFHtmlExtractMetadata(const std::string &cf_html, std::string *base_
size_t *html_start, size_t *fragment_start, size_t *fragment_end);
#endif // defined(Q_OS_WIN)
-void ClipboardQt::WritePortableRepresentations(ui::ClipboardBuffer type, const ObjectMap &objects, std::unique_ptr<ui::DataTransferEndpoint> data_src)
+void ClipboardQt::WritePortableAndPlatformRepresentations(ui::ClipboardBuffer type,
+ const ObjectMap &objects,
+ std::vector<ui::Clipboard::PlatformRepresentation> platform_representations,
+ std::unique_ptr<ui::DataTransferEndpoint> data_src)
{
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardBuffer(type));
+ if (!platform_representations.empty())
+ DispatchPlatformRepresentations(std::move(platform_representations));
for (const auto &object : objects)
- DispatchPortableRepresentation(object.first, object.second);
+ DispatchPortableRepresentation(object.second);
// Commit the accumulated data.
if (uncommittedData)
- QGuiApplication::clipboard()->setMimeData(uncommittedData.take(),
+ QGuiApplication::clipboard()->setMimeData(uncommittedData.release(),
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard
: QClipboard::Selection);
if (type == ui::ClipboardBuffer::kCopyPaste && IsSupportedClipboardBuffer(ui::ClipboardBuffer::kSelection)) {
- ObjectMap::const_iterator text_iter = objects.find(PortableFormat::kText);
+ auto text_iter = objects.find(base::VariantIndexOfType<Data, TextData>());
if (text_iter != objects.end()) {
// Copy text and SourceTag to the selection clipboard.
- WritePortableRepresentations(ui::ClipboardBuffer::kSelection,
- ObjectMap(text_iter, text_iter + 1),
- nullptr);
+ WritePortableAndPlatformRepresentations(ui::ClipboardBuffer::kSelection,
+ ObjectMap(text_iter, ++text_iter),
+ {},
+ nullptr);
}
}
m_dataSrc[type] = std::move(data_src);
}
-void ClipboardQt::WritePlatformRepresentations(ui::ClipboardBuffer buffer,
- std::vector<ui::Clipboard::PlatformRepresentation> platform_representations,
- std::unique_ptr<ui::DataTransferEndpoint> data_src)
+void ClipboardQt::WriteText(base::StringPiece text)
{
- DCHECK(CalledOnValidThread());
- DCHECK(IsSupportedClipboardBuffer(buffer));
- DispatchPlatformRepresentations(std::move(platform_representations));
- m_dataSrc[buffer] = std::move(data_src);
+ getUncommittedData()->setText(toQString(text));
}
-void ClipboardQt::WriteText(const char *text_data, size_t text_len)
+void ClipboardQt::WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url)
{
- getUncommittedData()->setText(QString::fromUtf8(text_data, text_len));
-}
-
-void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len)
-{
- QString markup_string = QString::fromUtf8(markup_data, markup_len);
+ QString markup_string = toQString(markup);
#if defined (Q_OS_MACOS)
// We need to prepend the charset on macOS to prevent garbled Unicode characters
// when pasting to certain applications (e.g. Notes, TextEdit)
@@ -168,18 +141,27 @@ void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const ch
#if !defined(Q_OS_WIN)
getUncommittedData()->setHtml(markup_string);
#else
- std::string url;
- if (url_len > 0)
- url.assign(url_data, url_len);
+ QString url;
+ if (source_url)
+ url = toQString(*source_url);
+
+ std::string cf_html = HtmlToCFHtml(markup_string.toStdString(), url.toStdString());
+ size_t html_start = std::string::npos;
+ size_t fragment_start = std::string::npos;
+ size_t fragment_end = std::string::npos;
+ CFHtmlExtractMetadata(cf_html, nullptr, &html_start, &fragment_start, &fragment_end);
+
+ DCHECK(fragment_start != std::string::npos && fragment_end != std::string::npos
+ && html_start != std::string::npos);
+ DCHECK(fragment_start >= html_start && fragment_end >= fragment_start);
- std::string cf_html = HtmlToCFHtml(markup_string.toStdString(), url);
- getUncommittedData()->setHtml(QString::fromStdString(cf_html));
+ getUncommittedData()->setHtml(QString::fromStdString(cf_html.substr(html_start)));
#endif // !defined(Q_OS_WIN)
}
-void ClipboardQt::WriteRTF(const char *rtf_data, size_t data_len)
+void ClipboardQt::WriteRTF(base::StringPiece rtf)
{
- getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeRTF), QByteArray(rtf_data, data_len));
+ getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeRTF), toQByteArray(rtf));
}
void ClipboardQt::WriteWebSmartPaste()
@@ -192,12 +174,12 @@ void ClipboardQt::WriteBitmap(const SkBitmap &bitmap)
getUncommittedData()->setImageData(toQImage(bitmap).copy());
}
-void ClipboardQt::WriteBookmark(const char *title_data, size_t title_len, const char *url_data, size_t url_len)
+void ClipboardQt::WriteBookmark(base::StringPiece title_in, base::StringPiece url_in)
{
// FIXME: Untested, seems to be used only for drag-n-drop.
// Write as a mozilla url (UTF16: URL, newline, title).
- QString url = QString::fromUtf8(url_data, url_len);
- QString title = QString::fromUtf8(title_data, title_len);
+ QString url = toQString(url_in);
+ QString title = toQString(title_in);
QByteArray data;
data.append(reinterpret_cast<const char *>(url.utf16()), url.size() * 2);
@@ -206,9 +188,9 @@ void ClipboardQt::WriteBookmark(const char *title_data, size_t title_len, const
getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeMozillaURL), data);
}
-void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, const char *data_data, size_t data_len)
+void ClipboardQt::WriteData(const ui::ClipboardFormatType &format, base::span<const uint8_t> data)
{
- getUncommittedData()->setData(QString::fromStdString(format.GetName()), QByteArray(data_data, data_len));
+ getUncommittedData()->setData(QString::fromStdString(format.GetName()), QByteArray((const char *)data.data(), data.size()));
}
bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format,
@@ -217,7 +199,12 @@ bool ClipboardQt::IsFormatAvailable(const ui::ClipboardFormatType &format,
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
- return mimeData && mimeData->hasFormat(QString::fromStdString(format.GetName()));
+
+ if (!mimeData)
+ return false;
+ if (format == ui::ClipboardFormatType::PngType())
+ return mimeData->hasImage();
+ return mimeData->hasFormat(QString::fromStdString(format.GetName()));
}
void ClipboardQt::Clear(ui::ClipboardBuffer type)
@@ -229,7 +216,7 @@ void ClipboardQt::Clear(ui::ClipboardBuffer type)
void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type,
const ui::DataTransferEndpoint *data_dst,
- std::vector<base::string16> *types) const
+ std::vector<std::u16string> *types) const
{
if (!types) {
NOTREACHED();
@@ -241,19 +228,19 @@ void ClipboardQt::ReadAvailableTypes(ui::ClipboardBuffer type,
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
return;
- if (mimeData->hasImage() && !mimeData->formats().contains(QStringLiteral("image/png")))
- types->push_back(toString16(QStringLiteral("image/png")));
- const QStringList formats = mimeData->formats();
- for (const QString &mimeType : formats)
- types->push_back(toString16(mimeType));
- const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
- ui::ReadCustomDataTypes(customData.constData(), customData.size(), types);
+ for (const auto& mime_type : GetStandardFormats(type, data_dst))
+ types->push_back(mime_type);
+
+ if (mimeData->hasFormat(QString::fromLatin1(ui::kMimeTypeWebCustomData))) {
+ const QByteArray customData = mimeData->data(QString::fromLatin1(ui::kMimeTypeWebCustomData));
+ ui::ReadCustomDataTypes(customData.constData(), customData.size(), types);
+ }
}
void ClipboardQt::ReadText(ui::ClipboardBuffer type,
const ui::DataTransferEndpoint *data_dst,
- base::string16 *result) const
+ std::u16string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -273,7 +260,7 @@ void ClipboardQt::ReadAsciiText(ui::ClipboardBuffer type,
void ClipboardQt::ReadHTML(ui::ClipboardBuffer type,
const ui::DataTransferEndpoint *data_dst,
- base::string16 *markup, std::string *src_url,
+ std::u16string *markup, std::string *src_url,
uint32_t *fragment_start, uint32_t *fragment_end) const
{
markup->clear();
@@ -329,37 +316,26 @@ void ClipboardQt::ReadRTF(ui::ClipboardBuffer type,
*result = std::string(byteArray.constData(), byteArray.length());
}
-void ClipboardQt::ReadImage(ui::ClipboardBuffer type,
- const ui::DataTransferEndpoint *data_dst,
- ReadImageCallback callback) const
+void ClipboardQt::ReadPng(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *, ui::Clipboard::ReadPngCallback callback) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
if (!mimeData)
- return std::move(callback).Run(SkBitmap());
+ return std::move(callback).Run({});
QImage image = qvariant_cast<QImage>(mimeData->imageData());
- image = image.convertToFormat(QImage::Format_ARGB32);
- SkBitmap bitmap;
-
- bitmap.allocN32Pixels(image.width(), image.height(), true);
- const size_t bytesPerRowDst = bitmap.rowBytes();
- const size_t bytesPerLineSrc = static_cast<size_t>(image.bytesPerLine());
- const size_t dataBytes = std::min(bytesPerRowDst, bytesPerLineSrc);
- uchar *dst = static_cast<uchar *>(bitmap.getPixels());
- const uchar *src = image.constBits();
- for (int y = 0; y < image.height(); ++y) {
- memcpy(dst, src, dataBytes);
- dst += bytesPerRowDst;
- src += bytesPerLineSrc;
- }
-
- return std::move(callback).Run(bitmap);
+ QBuffer buffer;
+ QImageWriter writer(&buffer, "png");
+ writer.write(image);
+ std::vector<uint8_t> pngData;
+ pngData.resize(buffer.size());
+ memcpy(pngData.data(), buffer.data().data(), buffer.size());
+ return std::move(callback).Run(std::move(pngData));
}
-void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type,
+void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const std::u16string &type,
const ui::DataTransferEndpoint *data_dst,
- base::string16 *result) const
+ std::u16string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
clipboard_type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -369,14 +345,14 @@ void ClipboardQt::ReadCustomData(ui::ClipboardBuffer clipboard_type, const base:
ui::ReadCustomDataForType(customData.constData(), customData.size(), type, result);
}
-void ClipboardQt::ReadBookmark(const ui::DataTransferEndpoint *data_dst, base::string16 *title, std::string *url) const
+void ClipboardQt::ReadBookmark(const ui::DataTransferEndpoint *data_dst, std::u16string *title, std::string *url) const
{
NOTIMPLEMENTED();
}
void ClipboardQt::ReadSvg(ui::ClipboardBuffer clipboard_type,
const ui::DataTransferEndpoint *,
- base::string16 *result) const
+ std::u16string *result) const
{
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
clipboard_type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
@@ -387,10 +363,10 @@ void ClipboardQt::ReadSvg(ui::ClipboardBuffer clipboard_type,
*result = toString16(QString::fromUtf8(svgData));
}
-void ClipboardQt::WriteSvg(const char *svg_data, size_t data_len)
+void ClipboardQt::WriteSvg(base::StringPiece markup)
{
getUncommittedData()->setData(QString::fromLatin1(ui::kMimeTypeSvg),
- QByteArray(svg_data, data_len));
+ toQByteArray(markup));
}
void ClipboardQt::ReadData(const ui::ClipboardFormatType &format,
@@ -404,10 +380,11 @@ void ClipboardQt::ReadData(const ui::ClipboardFormatType &format,
*result = std::string(byteArray.constData(), byteArray.length());
}
-uint64_t ClipboardQt::GetSequenceNumber(ui::ClipboardBuffer type) const
+const ui::ClipboardSequenceNumberToken &ClipboardQt::GetSequenceNumber(ui::ClipboardBuffer type) const
{
- return clipboardChangeObserver()->getSequenceNumber(type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard
- : QClipboard::Selection);
+ return type == ui::ClipboardBuffer::kCopyPaste
+ ? clipboardChangeObserver()->getPrimarySequenceNumber()
+ : clipboardChangeObserver()->getSelectionSequenceNumber();
}
const ui::DataTransferEndpoint *ClipboardQt::GetSource(ui::ClipboardBuffer buffer) const
@@ -443,6 +420,11 @@ void ClipboardQt::WriteFilenames(std::vector<ui::FileInfo> filenames)
getUncommittedData()->setUrls(urls);
}
+void ClipboardQt::WriteUnsanitizedHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url)
+{
+ WriteHTML(std::move(markup), std::move(source_url));
+}
+
#if defined(USE_OZONE)
bool ClipboardQt::IsSelectionBufferAvailable() const
{
@@ -450,25 +432,34 @@ bool ClipboardQt::IsSelectionBufferAvailable() const
}
#endif
-std::vector<base::string16> ClipboardQt::ReadAvailablePlatformSpecificFormatNames(ui::ClipboardBuffer buffer, const ui::DataTransferEndpoint *data_dst) const
-{
- // based on ClipboardX11
- std::vector<base::string16> types;
- if (IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextType(), buffer, data_dst))
- types.push_back(base::UTF8ToUTF16(ui::ClipboardFormatType::GetPlainTextType().GetName()));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetHtmlType(), buffer, data_dst))
- types.push_back(base::UTF8ToUTF16(ui::ClipboardFormatType::GetHtmlType().GetName()));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetRtfType(), buffer, data_dst))
- types.push_back(base::UTF8ToUTF16(ui::ClipboardFormatType::GetRtfType().GetName()));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetBitmapType(), buffer, data_dst))
- types.push_back(base::UTF8ToUTF16(ui::kMimeTypePNG));
- if (IsFormatAvailable(ui::ClipboardFormatType::GetSvgType(), buffer, data_dst))
- types.push_back(base::UTF8ToUTF16(ui::kMimeTypeSvg));
+// This is the same as ReadAvailableTypes minus dealing with custom-data
+std::vector<std::u16string> ClipboardQt::GetStandardFormats(ui::ClipboardBuffer buffer, const ui::DataTransferEndpoint *data_dst) const
+{
+ Q_UNUSED(data_dst);
const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(
buffer == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection);
- if (base::FeatureList::IsEnabled(features::kClipboardFilenames) && mimeData->hasUrls())
+ if (!mimeData)
+ return {};
+
+ std::vector<std::u16string> types;
+ if (mimeData->hasImage())
+ types.push_back(base::UTF8ToUTF16(ui::kMimeTypePNG));
+ if (mimeData->hasHtml())
+ types.push_back(base::UTF8ToUTF16(ui::kMimeTypeHTML));
+ if (mimeData->hasText())
+ types.push_back(base::UTF8ToUTF16(ui::kMimeTypeText));
+ if (mimeData->hasUrls())
types.push_back(base::UTF8ToUTF16(ui::kMimeTypeURIList));
- // ### Should we add non-standard mime-types?
+ const QStringList formats = mimeData->formats();
+ for (const QString &mimeType : formats) {
+ auto mime_type = mimeType.toStdString();
+ // Only add white-listed formats here
+ if (mime_type == ui::ClipboardFormatType::SvgType().GetName() ||
+ mime_type == ui::ClipboardFormatType::RtfType().GetName()) {
+ types.push_back(base::UTF8ToUTF16(mime_type));
+ continue;
+ }
+ }
return types;
}
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
index 0b77d2266..22f24cfe5 100644
--- a/src/core/clipboard_qt.h
+++ b/src/core/clipboard_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CLIPBOARD_QT_H
#define CLIPBOARD_QT_H
@@ -47,30 +11,30 @@ namespace QtWebEngineCore {
class ClipboardQt : public ui::Clipboard
{
public:
- uint64_t GetSequenceNumber(ui::ClipboardBuffer type) const override;
+ const ui::ClipboardSequenceNumberToken &GetSequenceNumber(ui::ClipboardBuffer type) const override;
bool IsFormatAvailable(const ui::ClipboardFormatType &format,
ui::ClipboardBuffer buffer,
const ui::DataTransferEndpoint *data_dst) const override;
void Clear(ui::ClipboardBuffer type) override;
void ReadAvailableTypes(ui::ClipboardBuffer type,
const ui::DataTransferEndpoint *data_dst,
- std::vector<base::string16> *types) const override;
- void ReadText(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *data_dst, base::string16 *result) const override;
+ std::vector<std::u16string> *types) const override;
+ void ReadText(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *data_dst, std::u16string *result) const override;
void ReadAsciiText(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *data_dst, std::string *result) const override;
- void ReadHTML(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *data_dst, base::string16 *markup, std::string *src_url, uint32_t *fragment_start,
+ void ReadHTML(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *data_dst, std::u16string *markup, std::string *src_url, uint32_t *fragment_start,
uint32_t *fragment_end) const override;
void ReadRTF(ui::ClipboardBuffer type, const ui::DataTransferEndpoint *data_dst, std::string *result) const override;
- void ReadImage(ui::ClipboardBuffer buffer, const ui::DataTransferEndpoint *data_dst, ReadImageCallback callback) const override;
- void ReadCustomData(ui::ClipboardBuffer clipboard_type, const base::string16 &type, const ui::DataTransferEndpoint *data_dst, base::string16 *result) const override;
- void ReadBookmark(const ui::DataTransferEndpoint *data_dst, base::string16 *title, std::string *url) const override;
+ void ReadCustomData(ui::ClipboardBuffer clipboard_type, const std::u16string &type, const ui::DataTransferEndpoint *data_dst, std::u16string *result) const override;
+ void ReadBookmark(const ui::DataTransferEndpoint *data_dst, std::u16string *title, std::string *url) const override;
void ReadData(const ui::ClipboardFormatType &format, const ui::DataTransferEndpoint *data_dst, std::string *result) const override;
#if defined(USE_OZONE)
bool IsSelectionBufferAvailable() const override;
#endif
void OnPreShutdown() override {}
- void ReadSvg(ui::ClipboardBuffer, const ui::DataTransferEndpoint *, base::string16 *) const override;
- std::vector<base::string16> ReadAvailablePlatformSpecificFormatNames(ui::ClipboardBuffer buffer, const ui::DataTransferEndpoint *data_dst) const override;
+ void ReadSvg(ui::ClipboardBuffer, const ui::DataTransferEndpoint *, std::u16string *) const override;
+ void ReadPng(ui::ClipboardBuffer, const ui::DataTransferEndpoint *, ui::Clipboard::ReadPngCallback) const override;
+ std::vector<std::u16string> GetStandardFormats(ui::ClipboardBuffer buffer, const ui::DataTransferEndpoint *data_dst) const override;
const ui::DataTransferEndpoint *GetSource(ui::ClipboardBuffer buffer) const override;
void ReadFilenames(ui::ClipboardBuffer buffer,
@@ -78,23 +42,21 @@ public:
std::vector<ui::FileInfo> *result) const override;
protected:
- void WritePortableRepresentations(
- ui::ClipboardBuffer buffer,
- const ObjectMap &objects,
- std::unique_ptr<ui::DataTransferEndpoint> data_src) override;
- void WritePlatformRepresentations(
- ui::ClipboardBuffer buffer,
- std::vector<Clipboard::PlatformRepresentation> platform_representations,
- std::unique_ptr<ui::DataTransferEndpoint> data_src) override;
- void WriteText(const char *text_data, size_t text_len) override;
- void WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len) override;
- void WriteRTF(const char *rtf_data, size_t data_len) override;
- void WriteBookmark(const char *title_data, size_t title_len, const char *url_data, size_t url_len) override;
+ void WritePortableAndPlatformRepresentations(ui::ClipboardBuffer buffer,
+ const ObjectMap &objects,
+ std::vector<Clipboard::PlatformRepresentation> platform_representations,
+ std::unique_ptr<ui::DataTransferEndpoint> data_src) override;
+
+ void WriteText(base::StringPiece text) override;
+ void WriteHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url) override;
+ void WriteRTF(base::StringPiece rtf) override;
+ void WriteBookmark(base::StringPiece title, base::StringPiece url) override;
void WriteWebSmartPaste() override;
void WriteBitmap(const SkBitmap &bitmap) override;
- void WriteData(const ui::ClipboardFormatType &format, const char *data_data, size_t data_len) override;
- void WriteSvg(const char *, size_t) override;
+ void WriteData(const ui::ClipboardFormatType &format, base::span<const uint8_t> data) override;
+ void WriteSvg(base::StringPiece markup) override;
void WriteFilenames(std::vector<ui::FileInfo> filenames) override;
+ void WriteUnsanitizedHTML(base::StringPiece markup, absl::optional<base::StringPiece> source_url) override;
base::flat_map<ui::ClipboardBuffer, std::unique_ptr<ui::DataTransferEndpoint>> m_dataSrc;
};
diff --git a/src/core/clipboard_util_win.cpp b/src/core/clipboard_util_win.cpp
index ae615b3b6..601e44180 100644
--- a/src/core/clipboard_util_win.cpp
+++ b/src/core/clipboard_util_win.cpp
@@ -1,31 +1,6 @@
-/*
- * Copyright (C) 2007, 2008 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 COMPUTER, INC. ``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 COMPUTER, INC. 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.
- */
-
+// Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
// 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.Chromium file.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <string>
diff --git a/src/core/color_chooser_controller.cpp b/src/core/color_chooser_controller.cpp
index 361ff93ba..fcaef2eba 100644
--- a/src/core/color_chooser_controller.cpp
+++ b/src/core/color_chooser_controller.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "content/browser/web_contents/web_contents_impl.h"
@@ -101,5 +65,4 @@ void ColorChooserController::reject()
didEndColorDialog();
}
-
-} // namespace
+} // namespace QtWebEngineCore
diff --git a/src/core/color_chooser_controller.h b/src/core/color_chooser_controller.h
index 493847f4e..a97ebfbff 100644
--- a/src/core/color_chooser_controller.h
+++ b/src/core/color_chooser_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -61,7 +25,7 @@ namespace QtWebEngineCore {
class ColorChooserControllerPrivate;
-class Q_WEBENGINECORE_PRIVATE_EXPORT ColorChooserController : public QObject {
+class Q_WEBENGINECORE_EXPORT ColorChooserController : public QObject {
Q_OBJECT
public:
~ColorChooserController();
@@ -83,6 +47,6 @@ private:
friend class ColorChooserQt;
};
-} // namespace
+} // namespace QtWebEngineCore
#endif // COLOR_CHOOSER_CONTROLLER_H
diff --git a/src/core/color_chooser_controller_p.h b/src/core/color_chooser_controller_p.h
index a03167f21..45eeb9471 100644
--- a/src/core/color_chooser_controller_p.h
+++ b/src/core/color_chooser_controller_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef COLOR_CHOOSER_CONTROLLER_P_H
#define COLOR_CHOOSER_CONTROLLER_P_H
@@ -54,7 +18,7 @@
#include <QColor>
namespace content {
- class WebContents;
+class WebContents;
}
namespace QtWebEngineCore {
@@ -67,7 +31,7 @@ public:
QColor m_initialColor;
};
-} // namespace
+} // namespace QtWebEngineCore
#endif // COLOR_CHOOSER_CONTROLLER_P_H
diff --git a/src/core/color_chooser_qt.cpp b/src/core/color_chooser_qt.cpp
index 749d04148..de2e833a0 100644
--- a/src/core/color_chooser_qt.cpp
+++ b/src/core/color_chooser_qt.cpp
@@ -1,49 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "color_chooser_qt.h"
#include "color_chooser_controller.h"
#include "color_chooser_controller_p.h"
-namespace content {
- class WebContents;
-}
+#include <QColor>
namespace QtWebEngineCore {
@@ -57,4 +19,4 @@ QSharedPointer<ColorChooserController> ColorChooserQt::controller()
return m_controller;
}
-} // namespace
+} // namespace QtWebEngineCore
diff --git a/src/core/color_chooser_qt.h b/src/core/color_chooser_qt.h
index 200db3266..dde9a51ce 100644
--- a/src/core/color_chooser_qt.h
+++ b/src/core/color_chooser_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef COLOR_CHOOSER_QT_H
#define COLOR_CHOOSER_QT_H
@@ -43,11 +7,12 @@
#include "content/public/browser/color_chooser.h"
#include "type_conversion.h"
-#include <QColor>
#include <QSharedPointer>
+QT_FORWARD_DECLARE_CLASS(QColor)
+
namespace content {
- class WebContents;
+class WebContents;
}
namespace QtWebEngineCore {
@@ -68,7 +33,6 @@ private:
QSharedPointer<ColorChooserController> m_controller;
};
-
-} // namespace
+} // namespace QtWebEngineCore
#endif // COLOR_CHOOSER_QT_H
diff --git a/src/core/common/extensions/api/qtwebengine_extensions_features.gni b/src/core/common/extensions/api/qtwebengine_extensions_features.gni
deleted file mode 100644
index 3873e235a..000000000
--- a/src/core/common/extensions/api/qtwebengine_extensions_features.gni
+++ /dev/null
@@ -1,27 +0,0 @@
-import("//tools/json_schema_compiler/json_features.gni")
-
-json_features("qt_api_features") {
- feature_type = "APIFeature"
- method_name = "AddQtAPIFeatures"
- sources = [
- "//extensions/common/api/_webengine_api_features.json"
- ]
-}
-
-json_features("qt_permission_features") {
- feature_type = "PermissionFeature"
- method_name = "AddQtPermissionFeatures"
- sources = [
- "//chrome/common/extensions/api/_permission_features.json",
- "//extensions/common/api/_permission_features.json",
- ]
-}
-
-group("qtwebengine_extensions_features") {
- public_deps = [
- ":qt_api_features",
- ":qt_permission_features",
- "//chrome/common/extensions/api:extensions_features",
- "//extensions/common/api:extensions_features",
- ]
-}
diff --git a/src/core/common/extensions/extensions_api_provider_qt.cpp b/src/core/common/extensions/extensions_api_provider_qt.cpp
index 81eb76f3e..1c8e89747 100644
--- a/src/core/common/extensions/extensions_api_provider_qt.cpp
+++ b/src/core/common/extensions/extensions_api_provider_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "extensions_api_provider_qt.h"
diff --git a/src/core/common/extensions/extensions_api_provider_qt.h b/src/core/common/extensions/extensions_api_provider_qt.h
index 7d8c5f98b..34e8bdd9f 100644
--- a/src/core/common/extensions/extensions_api_provider_qt.h
+++ b/src/core/common/extensions/extensions_api_provider_qt.h
@@ -1,48 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef EXTENSIONS_API_PROVIDER_QT_H
#define EXTENSIONS_API_PROVIDER_QT_H
#include "extensions/common/extensions_api_provider.h"
-#include "base/macros.h"
-
namespace extensions {
class ExtensionsAPIProviderQt : public ExtensionsAPIProvider
@@ -64,8 +26,6 @@ public:
// Registers permissions for any associated API features.
void RegisterPermissions(PermissionsInfo* permissions_info) override;
-
-DISALLOW_COPY_AND_ASSIGN(ExtensionsAPIProviderQt);
};
}
diff --git a/src/core/common/extensions/extensions_client_qt.cpp b/src/core/common/extensions/extensions_client_qt.cpp
index c4cc2321a..9240e6528 100644
--- a/src/core/common/extensions/extensions_client_qt.cpp
+++ b/src/core/common/extensions/extensions_client_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -153,11 +117,17 @@ const GURL &ExtensionsClientQt::GetWebstoreUpdateURL() const
// Returns a flag indicating whether or not a given URL is a valid
// extension blacklist URL.
-bool ExtensionsClientQt::IsBlacklistUpdateURL(const GURL &url) const
+bool ExtensionsClientQt::IsBlocklistUpdateURL(const GURL &url) const
{
return true;
}
+const GURL &ExtensionsClientQt::GetNewWebstoreBaseURL() const
+{
+ static GURL dummy;
+ return dummy;
+}
+
// Returns the set of file paths corresponding to any images within an
// extension's contents that may be displayed directly within the browser UI
// or WebUI, such as icons or theme images. This set of paths is used by the
diff --git a/src/core/common/extensions/extensions_client_qt.h b/src/core/common/extensions/extensions_client_qt.h
index 2466e14e3..b2d128bf9 100644
--- a/src/core/common/extensions/extensions_client_qt.h
+++ b/src/core/common/extensions/extensions_client_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -46,9 +10,7 @@
#include "extensions/common/extensions_client.h"
-#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
-#include "base/macros.h"
#include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/features/json_feature_provider_source.h"
@@ -110,7 +72,9 @@ public:
// Returns a flag indicating whether or not a given URL is a valid
// extension blacklist URL.
- bool IsBlacklistUpdateURL(const GURL &url) const override;
+ bool IsBlocklistUpdateURL(const GURL &url) const override;
+
+ const GURL &GetNewWebstoreBaseURL() const override;
// Returns the set of file paths corresponding to any images within an
// extension's contents that may be displayed directly within the browser UI
@@ -131,7 +95,6 @@ private:
const ChromePermissionMessageProvider permission_message_provider_;
mutable GURL update_url_;
mutable GURL base_url_;
- DISALLOW_COPY_AND_ASSIGN(ExtensionsClientQt);
};
} // namespace extensions
diff --git a/src/core/common/qt_messages.cpp b/src/core/common/qt_messages.cpp
index 2f087d21f..bc3a1560d 100644
--- a/src/core/common/qt_messages.cpp
+++ b/src/core/common/qt_messages.cpp
@@ -1,6 +1,5 @@
// Copyright (c) 2010 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.Chromium file.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
// Get basic type definitions.
#define IPC_MESSAGE_IMPL
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index de0257254..17adcbb0d 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -1,11 +1,11 @@
// 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.Chromium file.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
// Multiply-included file, no traditional include guard.
#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_start.h"
#include "url/gurl.h"
#define IPC_MESSAGE_START QtMsgStart
diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp
index 655126f20..4c0bd4c0d 100644
--- a/src/core/compositor/compositor.cpp
+++ b/src/core/compositor/compositor.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "compositor.h"
@@ -43,8 +7,8 @@
#include "components/viz/common/surfaces/frame_sink_id.h"
#include <QHash>
-#include <QImage>
#include <QMutex>
+#include <QQuickWindow>
namespace QtWebEngineCore {
@@ -129,10 +93,8 @@ void Compositor::Observer::unbind()
Compositor::Handle<Compositor> Compositor::Observer::compositor()
{
- if (!m_binding)
- return nullptr;
g_bindings.lock();
- if (m_binding->compositor)
+ if (m_binding && m_binding->compositor)
return m_binding->compositor; // delay unlock
g_bindings.unlock();
return nullptr;
@@ -163,32 +125,35 @@ void Compositor::unbind()
Compositor::Handle<Compositor::Observer> Compositor::observer()
{
- if (!m_binding)
- return nullptr;
g_bindings.lock();
- if (m_binding->observer)
+ if (m_binding && m_binding->observer)
return m_binding->observer; // delay unlock
g_bindings.unlock();
return nullptr;
}
-QImage Compositor::image()
+void Compositor::waitForTexture()
{
- Q_UNREACHABLE();
- return {};
}
-void Compositor::waitForTexture()
+void Compositor::releaseTexture()
+{
+}
+
+QSGTexture *Compositor::texture(QQuickWindow *, uint32_t textureOptions)
{
Q_UNREACHABLE();
+ return nullptr;
}
-int Compositor::textureId()
+bool Compositor::textureIsFlipped()
{
Q_UNREACHABLE();
- return 0;
+ return false;
}
+void Compositor::releaseResources() { }
+
// static
void Compositor::unlockBindings()
{
diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h
index 7968e8201..501559060 100644
--- a/src/core/compositor/compositor.h
+++ b/src/core/compositor/compositor.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef COMPOSITOR_H
#define COMPOSITOR_H
@@ -43,8 +7,9 @@
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
QT_BEGIN_NAMESPACE
-class QImage;
+class QQuickWindow;
class QSize;
+class QSGTexture;
QT_END_NAMESPACE
namespace viz {
@@ -55,10 +20,9 @@ namespace QtWebEngineCore {
// Produces composited frames for display.
//
-// Used by quick/widgets libraries for accessing the frame and
-// controlling frame swapping. Must be cast to a subclass to access
-// the frame as QImage or OpenGL texture, etc.
-class Q_WEBENGINECORE_PRIVATE_EXPORT Compositor
+// Used by quick/widgets libraries for accessing the frames and
+// controlling frame swapping.
+class Q_WEBENGINECORE_EXPORT Compositor
{
struct Binding;
@@ -66,7 +30,8 @@ public:
// Identifies the implementation type.
enum class Type {
Software,
- OpenGL,
+ OpenGL, // TODO: Legacy, remove it with DisplaySkiaOutputDevice!
+ Native
};
// Identifies a compositor.
@@ -110,7 +75,7 @@ public:
// Observes the compositor corresponding to the given id.
//
// Only one observer can exist per compositor.
- class Q_WEBENGINECORE_PRIVATE_EXPORT Observer
+ class Q_WEBENGINECORE_EXPORT Observer
{
public:
// Binding to compositor
@@ -125,7 +90,7 @@ public:
protected:
Observer() = default;
- ~Observer() = default;
+ ~Observer() { if (m_binding) unbind(); }
private:
Binding *m_binding = nullptr;
@@ -153,31 +118,26 @@ public:
virtual QSize size() = 0;
// Whether frame needs an alpha channel.
- //
- // In software mode, the image format can be either
- // QImage::Format_ARGB32_Premultiplied or
- // QImage::Format_RGBA8888_Premultiplied
- //
- // In OpenGL mode, the texture format is either GL_RGBA or GL_RGB.
- virtual bool hasAlphaChannel() = 0;
-
- // (Software) QImage of the frame.
- //
- // This is a big image so we should try not to make copies of it.
- // In particular, the client should drop its QImage reference
- // before calling swapFrame(), otherwise each swap will cause a
- // detach.
- virtual QImage image();
+ virtual bool requiresAlphaChannel() = 0;
- // (OpenGL) Wait on texture fence in Qt's current OpenGL context.
+ // Wait on texture to be ready aka. sync.
virtual void waitForTexture();
- // (OpenGL) Texture of the frame.
- virtual int textureId();
+ // Release any held texture resources
+ virtual void releaseTexture();
+
+ // QSGTexture of the frame.
+ virtual QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions);
+
+ // Is the texture produced upside down?
+ virtual bool textureIsFlipped();
+
+ // Release resources created in texture()
+ virtual void releaseResources();
protected:
Compositor(Type type) : m_type(type) { }
- virtual ~Compositor() = default;
+ virtual ~Compositor() { if (m_binding) unbind(); }
private:
template<typename T>
diff --git a/src/core/compositor/compositor_resource_fence.cpp b/src/core/compositor/compositor_resource_fence.cpp
index d03e260d6..bd1c95cd9 100644
--- a/src/core/compositor/compositor_resource_fence.cpp
+++ b/src/core/compositor/compositor_resource_fence.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "compositor_resource_fence.h"
#include "ozone/gl_surface_qt.h"
diff --git a/src/core/compositor/compositor_resource_fence.h b/src/core/compositor/compositor_resource_fence.h
index 574416b8b..ab92ca5c7 100644
--- a/src/core/compositor/compositor_resource_fence.h
+++ b/src/core/compositor/compositor_resource_fence.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef COMPOSITOR_RESOURCE_FENCE_H
#define COMPOSITOR_RESOURCE_FENCE_H
diff --git a/src/core/compositor/content_gpu_client_qt.cpp b/src/core/compositor/content_gpu_client_qt.cpp
index f934979a0..6ef8048f2 100644
--- a/src/core/compositor/content_gpu_client_qt.cpp
+++ b/src/core/compositor/content_gpu_client_qt.cpp
@@ -1,45 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "content_gpu_client_qt.h"
-
-#include "web_engine_context.h"
+#include "ozone/gl_share_context_qt.h"
namespace QtWebEngineCore {
@@ -51,9 +14,11 @@ ContentGpuClientQt::~ContentGpuClientQt()
{
}
-gpu::SyncPointManager *ContentGpuClientQt::GetSyncPointManager()
+gl::GLShareGroup *ContentGpuClientQt::GetInProcessGpuShareGroup()
{
- return WebEngineContext::syncPointManager();
+ if (!m_shareGroupQt.get())
+ m_shareGroupQt = new ShareGroupQt;
+ return m_shareGroupQt.get();
}
} // namespace
diff --git a/src/core/compositor/content_gpu_client_qt.h b/src/core/compositor/content_gpu_client_qt.h
index d7ad43881..33314e0bb 100644
--- a/src/core/compositor/content_gpu_client_qt.h
+++ b/src/core/compositor/content_gpu_client_qt.h
@@ -1,47 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CONTENT_GPU_CLIENT_QT_H
#define CONTENT_GPU_CLIENT_QT_H
#include "content/public/gpu/content_gpu_client.h"
+namespace gl {
+class GLShareGroup;
+}
+
namespace QtWebEngineCore {
+class ShareGroupQt;
class ContentGpuClientQt : public content::ContentGpuClient {
public:
@@ -49,7 +18,10 @@ public:
~ContentGpuClientQt() override;
// content::ContentGpuClient implementation.
- gpu::SyncPointManager *GetSyncPointManager() override;
+ gl::GLShareGroup *GetInProcessGpuShareGroup() override;
+
+private:
+ scoped_refptr<ShareGroupQt> m_shareGroupQt;
};
}
diff --git a/src/core/compositor/display_gl_output_surface.cpp b/src/core/compositor/display_gl_output_surface.cpp
deleted file mode 100644
index dfc3cb7c6..000000000
--- a/src/core/compositor/display_gl_output_surface.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "display_gl_output_surface.h"
-
-#include "type_conversion.h"
-
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/viz/service/display/display.h"
-#include "components/viz/service/display/output_surface_frame.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/texture_base.h"
-#include "gpu/ipc/in_process_command_buffer.h"
-#include "ui/gfx/buffer_format_util.h"
-
-namespace QtWebEngineCore {
-
-DisplayGLOutputSurface::DisplayGLOutputSurface(
- scoped_refptr<viz::VizProcessContextProvider> contextProvider)
- : OutputSurface(contextProvider)
- , Compositor(Compositor::Type::OpenGL)
- , m_commandBuffer(contextProvider->command_buffer())
- , m_gl(contextProvider->ContextGL())
- , m_vizContextProvider(contextProvider)
-{
- capabilities_.uses_default_gl_framebuffer = false;
- m_gl->GenFramebuffers(1, &m_fboId);
-}
-
-DisplayGLOutputSurface::~DisplayGLOutputSurface()
-{
- unbind();
- m_vizContextProvider->SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback());
- m_gl->DeleteFramebuffers(1, &m_fboId);
-}
-
-// Called from viz::Display::Initialize.
-void DisplayGLOutputSurface::BindToClient(viz::OutputSurfaceClient *client)
-{
- m_client = client;
-}
-
-void DisplayGLOutputSurface::SetFrameSinkId(const viz::FrameSinkId &id)
-{
- bind(id);
-}
-
-// Triggered by ui::Compositor::SetVisible(true).
-void DisplayGLOutputSurface::EnsureBackbuffer()
-{
-}
-
-// Triggered by ui::Compositor::SetVisible(false). Framebuffer must be cleared.
-void DisplayGLOutputSurface::DiscardBackbuffer()
-{
- NOTIMPLEMENTED();
- // m_gl->DiscardBackbufferCHROMIUM();
-}
-
-// Called from viz::DirectRenderer::DrawFrame before rendering starts, but only
-// if the parameters differ from the previous Reshape call.
-//
-// Parameters:
-//
-// - sizeInPixels comes from ui::Compositor::SetScaleAndSize via
-// viz::HostContextFactoryPrivate::ResizeDisplay.
-//
-// - devicePixelRatio comes from viz::CompositorFrame::device_scale_factor()
-// via viz::RootCompositorFrameSinkImpl::SubmitCompositorFrame and
-// viz::Display::SetLocalSurfaceId.
-//
-// - colorSpace and hasAlpha correspond to the color_space and
-// has_transparent_background properties of the root viz::RenderPass.
-//
-// - useStencil should create a stencil buffer, but this is only needed for
-// overdraw feedback (--show-overdraw-feedback), so it's safe to ignore.
-// Accordingly, capabilities_.supports_stencil should be set to false.
-//
-void DisplayGLOutputSurface::Reshape(const gfx::Size &sizeInPixels,
- float devicePixelRatio,
- const gfx::ColorSpace &colorSpace,
- gfx::BufferFormat format,
- bool /*useStencil*/)
-{
- bool hasAlpha = gfx::AlphaBitsForBufferFormat(format) > 0;
- m_currentShape = Shape{sizeInPixels, devicePixelRatio, colorSpace, hasAlpha};
- m_gl->ResizeCHROMIUM(sizeInPixels.width(), sizeInPixels.height(), devicePixelRatio,
- colorSpace.AsGLColorSpace(), hasAlpha);
-}
-
-std::unique_ptr<DisplayGLOutputSurface::Buffer> DisplayGLOutputSurface::makeBuffer(const Shape &shape)
-{
- std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(this);
- buffer->shape = shape;
- m_gl->GenTextures(1, &buffer->clientId);
- m_gl->BindTexture(GL_TEXTURE_2D, buffer->clientId);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- uint32_t width = shape.sizeInPixels.width();
- uint32_t height = shape.sizeInPixels.height();
- uint32_t format = shape.hasAlpha ? GL_RGBA : GL_RGB;
- m_gl->TexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
- return buffer;
-}
-
-void DisplayGLOutputSurface::deleteBufferResources(Buffer *buffer)
-{
- m_gl->DeleteTextures(1, &buffer->clientId);
-}
-
-// Called by viz::GLRenderer during rendering whenever it switches to the root
-// render pass.
-void DisplayGLOutputSurface::BindFramebuffer()
-{
- if (!m_backBuffer || m_backBuffer->shape != m_currentShape)
- m_backBuffer = makeBuffer(m_currentShape);
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer->clientId, 0);
-}
-
-// Called from viz::Display::DrawAndSwap after rendering.
-//
-// Parameters:
-//
-// - frame.size is the same as the size given to Reshape.
-//
-// - frame.sub_buffer_rect and frame.content_bounds are never used since these
-// are only enabled if gl::GLSurface::SupportsPostSubBuffer() or
-// gl::GLSurface::SupportsSwapBuffersWithBounds() are true, respectively,
-// but this not the case for any offscreen gl::GLSurface.
-//
-// - frame.latency_info is viz::CompositorFrame::metadata.latency_info.
-void DisplayGLOutputSurface::SwapBuffers(viz::OutputSurfaceFrame frame)
-{
- DCHECK(frame.size == m_currentShape.sizeInPixels);
- DCHECK(!frame.sub_buffer_rect.has_value());
- DCHECK(frame.content_bounds.empty());
- DCHECK(m_backBuffer);
-
- m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
- m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- gpu::SyncToken syncToken;
- m_gl->GenSyncTokenCHROMIUM(syncToken.GetData());
-
- unsigned int clientId = m_backBuffer->clientId;
-
- // Now some thread-hopping:
- //
- // - We start here on the viz thread (client side of command buffer).
- //
- // - Then we'll jump to the gpu thread (service side of command buffer) to
- // get the real OpenGL texture id.
- //
- // - Then we'll get a call from the Qt Quick Scene Graph thread (could be
- // a separate thread or the main thread).
- //
- // - Finally we'll return to the viz thread to acknowledge the swap.
-
- {
- QMutexLocker locker(&m_mutex);
- m_taskRunner = base::ThreadTaskRunnerHandle::Get();
- m_middleBuffer = std::move(m_backBuffer);
- m_middleBuffer->serviceId = 0;
- }
-
- m_commandBuffer->GetTextureQt(
- clientId,
- base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnGpuThread, base::Unretained(this)),
- std::vector<gpu::SyncToken>{syncToken});
-}
-
-void DisplayGLOutputSurface::swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence)
-{
- {
- QMutexLocker locker(&m_mutex);
- m_middleBuffer->serviceId = id;
- m_middleBuffer->fence = CompositorResourceFence::create(std::move(fence));
- m_readyToUpdate = true;
- }
-
- if (auto obs = observer())
- obs->readyToSwap();
-}
-
-void DisplayGLOutputSurface::swapBuffersOnVizThread()
-{
- {
- QMutexLocker locker(&m_mutex);
- m_backBuffer = std::move(m_middleBuffer);
- }
-
- const auto now = base::TimeTicks::Now();
- m_client->DidReceiveSwapBuffersAck(gfx::SwapTimings{now, now});
- m_client->DidReceivePresentationFeedback(
- gfx::PresentationFeedback(now, base::TimeDelta(),
- gfx::PresentationFeedback::Flags::kVSync));
-}
-
-void DisplayGLOutputSurface::SetDrawRectangle(const gfx::Rect &)
-{
-}
-
-// Returning true here will cause viz::GLRenderer to try to render the output
-// surface as an overlay plane (see viz::DirectRenderer::DrawFrame and
-// viz::GLRenderer::ScheduleOverlays).
-bool DisplayGLOutputSurface::IsDisplayedAsOverlayPlane() const
-{
- return false;
-}
-
-// Only used if IsDisplayedAsOverlayPlane was true (called from
-// viz::GLRenderer::ScheduleOverlays).
-unsigned DisplayGLOutputSurface::GetOverlayTextureId() const
-{
- return 0;
-}
-
-// Called by viz::GLRenderer but always false in all implementations except for
-// android_webview::ParentOutputSurface.
-bool DisplayGLOutputSurface::HasExternalStencilTest() const
-{
- return false;
-}
-
-// Only called if HasExternalStencilTest was true. Dead code?
-void DisplayGLOutputSurface::ApplyExternalStencil()
-{
- NOTREACHED();
-}
-
-// Called from GLRenderer::GetFramebufferCopyTextureFormat when using
-// glCopyTexSubImage2D on our framebuffer.
-uint32_t DisplayGLOutputSurface::GetFramebufferCopyTextureFormat()
-{
- return m_currentShape.hasAlpha ? GL_RGBA : GL_RGB;
-}
-
-// Called from viz::DirectRenderer::DrawFrame, only used for overlays.
-unsigned DisplayGLOutputSurface::UpdateGpuFence()
-{
- NOTREACHED();
- return 0;
-}
-
-void DisplayGLOutputSurface::SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback callback)
-{
- m_vizContextProvider->SetUpdateVSyncParametersCallback(std::move(callback));
-}
-
-void DisplayGLOutputSurface::SetDisplayTransformHint(gfx::OverlayTransform)
-{
-}
-
-gfx::OverlayTransform DisplayGLOutputSurface::GetDisplayTransform()
-{
- return gfx::OVERLAY_TRANSFORM_NONE;
-}
-
-void DisplayGLOutputSurface::swapFrame()
-{
- QMutexLocker locker(&m_mutex);
- if (m_readyToUpdate) {
- std::swap(m_middleBuffer, m_frontBuffer);
- m_taskRunner->PostTask(FROM_HERE,
- base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnVizThread,
- base::Unretained(this)));
- m_taskRunner.reset();
- m_readyToUpdate = false;
- }
-}
-
-void DisplayGLOutputSurface::waitForTexture()
-{
- if (m_frontBuffer && m_frontBuffer->fence) {
- m_frontBuffer->fence->wait();
- m_frontBuffer->fence.reset();
- }
-}
-
-int DisplayGLOutputSurface::textureId()
-{
- return m_frontBuffer ? m_frontBuffer->serviceId : 0;
-}
-
-QSize DisplayGLOutputSurface::size()
-{
- return m_frontBuffer ? toQt(m_frontBuffer->shape.sizeInPixels) : QSize();
-}
-
-bool DisplayGLOutputSurface::hasAlphaChannel()
-{
- return m_frontBuffer ? m_frontBuffer->shape.hasAlpha : false;
-}
-
-float DisplayGLOutputSurface::devicePixelRatio()
-{
- return m_frontBuffer ? m_frontBuffer->shape.devicePixelRatio : 1;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_gl_output_surface.h b/src/core/compositor/display_gl_output_surface.h
deleted file mode 100644
index 30fb0cd0d..000000000
--- a/src/core/compositor/display_gl_output_surface.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef DISPLAY_GL_OUTPUT_SURFACE_H
-#define DISPLAY_GL_OUTPUT_SURFACE_H
-
-#include "compositor_resource_fence.h"
-#include "compositor.h"
-
-#include "components/viz/common/display/update_vsync_parameters_callback.h"
-#include "components/viz/service/display/output_surface.h"
-#include "components/viz/service/display_embedder/viz_process_context_provider.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-
-#include <QMutex>
-
-namespace QtWebEngineCore {
-
-class DisplayGLOutputSurface final : public viz::OutputSurface, public Compositor
-{
-public:
- DisplayGLOutputSurface(scoped_refptr<viz::VizProcessContextProvider> contextProvider);
- ~DisplayGLOutputSurface() override;
-
- // Overridden from viz::OutputSurface.
- void BindToClient(viz::OutputSurfaceClient *client) override;
- void EnsureBackbuffer() override;
- void DiscardBackbuffer() override;
- void BindFramebuffer() override;
- void SetDrawRectangle(const gfx::Rect &drawRect) override;
- bool IsDisplayedAsOverlayPlane() const override;
- unsigned GetOverlayTextureId() const override;
- void Reshape(const gfx::Size &size,
- float devicePixelRatio,
- const gfx::ColorSpace &colorSpace,
- gfx::BufferFormat format,
- bool useStencil) override;
- bool HasExternalStencilTest() const override;
- void ApplyExternalStencil() override;
- uint32_t GetFramebufferCopyTextureFormat() override;
- void SwapBuffers(viz::OutputSurfaceFrame frame) override;
- unsigned UpdateGpuFence() override;
- void SetUpdateVSyncParametersCallback(viz::UpdateVSyncParametersCallback callback) override;
- void SetDisplayTransformHint(gfx::OverlayTransform transform) override;
- gfx::OverlayTransform GetDisplayTransform() override;
- void SetFrameSinkId(const viz::FrameSinkId &id) override;
-
- // Overridden from Compositor.
- void swapFrame() override;
- void waitForTexture() override;
- int textureId() override;
- QSize size() override;
- bool hasAlphaChannel() override;
- float devicePixelRatio() override;
-
-private:
- struct Shape
- {
- gfx::Size sizeInPixels;
- float devicePixelRatio;
- gfx::ColorSpace colorSpace;
- bool hasAlpha;
-
- bool operator==(const Shape &that) const
- {
- return (sizeInPixels == that.sizeInPixels &&
- devicePixelRatio == that.devicePixelRatio &&
- colorSpace == that.colorSpace &&
- hasAlpha == that.hasAlpha);
- }
- bool operator!=(const Shape &that) const { return !(*this == that); }
- };
-
- struct Buffer
- {
- DisplayGLOutputSurface *parent;
- Shape shape;
- uint32_t clientId = 0;
- uint32_t serviceId = 0;
- scoped_refptr<CompositorResourceFence> fence;
-
- Buffer(DisplayGLOutputSurface *parent) : parent(parent) {}
- ~Buffer() { parent->deleteBufferResources(this); }
- };
-
- class Texture;
-
- void swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence);
- void swapBuffersOnVizThread();
-
- std::unique_ptr<Buffer> makeBuffer(const Shape &shape);
- void deleteBufferResources(Buffer *buffer);
- void attachBuffer();
- void detachBuffer();
-
- gpu::InProcessCommandBuffer *const m_commandBuffer;
- gpu::gles2::GLES2Interface *const m_gl;
- mutable QMutex m_mutex;
- uint32_t m_fboId = 0;
- viz::OutputSurfaceClient *m_client = nullptr;
- Shape m_currentShape;
- std::unique_ptr<Buffer> m_backBuffer;
- std::unique_ptr<Buffer> m_middleBuffer;
- std::unique_ptr<Buffer> m_frontBuffer;
- bool m_readyToUpdate = false;
- scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
- scoped_refptr<viz::VizProcessContextProvider> m_vizContextProvider;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // !DISPLAY_GL_OUTPUT_SURFACE_H
diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp
index d41765272..ebaa96dbb 100644
--- a/src/core/compositor/display_overrides.cpp
+++ b/src/core/compositor/display_overrides.cpp
@@ -1,100 +1,100 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "display_gl_output_surface.h"
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#include "display_skia_output_device.h"
#include "display_software_output_surface.h"
+#include "native_skia_output_device.h"
#include "components/viz/service/display_embedder/output_surface_provider_impl.h"
#include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h"
#include "gpu/ipc/in_process_command_buffer.h"
+
#include <qtgui-config.h>
+#include <QtQuick/qquickwindow.h>
-std::unique_ptr<viz::OutputSurface>
-viz::OutputSurfaceProviderImpl::CreateGLOutputSurface(
- scoped_refptr<VizProcessContextProvider> context_provider)
-{
#if QT_CONFIG(opengl)
- return std::make_unique<QtWebEngineCore::DisplayGLOutputSurface>(std::move(context_provider));
-#else
- return nullptr;
-#endif // QT_CONFIG(opengl)
-}
+#include "native_skia_output_device_opengl.h"
+#endif
+
+#if BUILDFLAG(ENABLE_VULKAN)
+#include "native_skia_output_device_vulkan.h"
+#endif
+
+#if defined(Q_OS_WIN)
+#include "native_skia_output_device_direct3d11.h"
+#endif
+
+#if defined(Q_OS_MACOS)
+#include "native_skia_output_device_metal.h"
+#endif
std::unique_ptr<viz::OutputSurface>
-viz::OutputSurfaceProviderImpl::CreateSoftwareOutputSurface()
+viz::OutputSurfaceProviderImpl::CreateSoftwareOutputSurface(const RendererSettings &renderer_settings)
{
- return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>();
+ return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>(renderer_settings.requires_alpha_channel);
}
std::unique_ptr<viz::SkiaOutputDevice>
viz::SkiaOutputSurfaceImplOnGpu::CreateOutputDevice()
{
+ static const auto graphicsApi = QQuickWindow::graphicsApi();
+
#if QT_CONFIG(opengl)
- return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>(
- context_state_,
- shared_gpu_deps_->memory_tracker(),
- GetDidSwapBuffersCompleteCallback());
+ if (graphicsApi == QSGRendererInterface::OpenGL) {
+ if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE) {
+#if !defined(Q_OS_MACOS)
+ return std::make_unique<QtWebEngineCore::DisplaySkiaOutputDevice>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), GetDidSwapBuffersCompleteCallback());
#else
- return nullptr;
+ qFatal("macOS only supports ANGLE.");
+#endif // !defined(Q_OS_MACOS)
+ }
+
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceOpenGL>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+ }
#endif // QT_CONFIG(opengl)
-}
-void gpu::InProcessCommandBuffer::GetTextureQt(
- unsigned int client_id,
- GetTextureCallback callback,
- const std::vector<SyncToken>& sync_token_fences)
-{
- ScheduleGpuTask(base::BindOnce(&InProcessCommandBuffer::GetTextureQtOnGpuThread,
- gpu_thread_weak_ptr_factory_.GetWeakPtr(),
- client_id,
- std::move(callback)),
- sync_token_fences);
-}
+#if BUILDFLAG(ENABLE_VULKAN)
+ if (graphicsApi == QSGRendererInterface::Vulkan) {
+#if !defined(Q_OS_MACOS)
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceVulkan>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+#else
+ qFatal("Vulkan is not supported on macOS.");
+#endif // !defined(Q_OS_MACOS)
+ }
+#endif // BUILDFLAG(ENABLE_VULKAN)
-void gpu::InProcessCommandBuffer::GetTextureQtOnGpuThread(
- unsigned int client_id, GetTextureCallback callback)
-{
- if (!MakeCurrent()) {
- LOG(ERROR) << "MakeCurrent failed for GetTextureQt";
- return;
+#if defined(Q_OS_WIN)
+ if (graphicsApi == QSGRendererInterface::Direct3D11) {
+ if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE)
+ qFatal("Direct3D11 is only supported over ANGLE.");
+
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceDirect3D11>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
+ }
+#endif
+
+#if defined(Q_OS_MACOS)
+ if (graphicsApi == QSGRendererInterface::Metal) {
+ if (gl::GetGLImplementation() != gl::kGLImplementationEGLANGLE)
+ qFatal("Metal is only supported over ANGLE.");
+
+ return std::make_unique<QtWebEngineCore::NativeSkiaOutputDeviceMetal>(
+ context_state_, renderer_settings_.requires_alpha_channel,
+ shared_gpu_deps_->memory_tracker(), dependency_.get(), shared_image_factory_.get(),
+ shared_image_representation_factory_.get(), GetDidSwapBuffersCompleteCallback());
}
- gpu::TextureBase *texture = decoder_->GetTextureBase(client_id);
- std::move(callback).Run(texture ? texture->service_id() : 0, gl::GLFence::Create());
+#endif
+
+ qFatal() << "Unsupported Graphics API:" << graphicsApi;
+ return nullptr;
}
diff --git a/src/core/compositor/display_skia_output_device.cpp b/src/core/compositor/display_skia_output_device.cpp
index 69cb65eeb..0ca466fe8 100644
--- a/src/core/compositor/display_skia_output_device.cpp
+++ b/src/core/compositor/display_skia_output_device.cpp
@@ -1,48 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "display_skia_output_device.h"
+#include "compositor_resource_fence.h"
#include "type_conversion.h"
#include "gpu/command_buffer/service/skia_utils.h"
-#include "skia/ext/legacy_display_globals.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/core/SkSurfaceProps.h"
+#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
+#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
+
+#include <QSGTexture>
namespace QtWebEngineCore {
@@ -53,30 +23,25 @@ public:
: m_parent(parent)
, m_shape(m_parent->m_shape)
{
- auto formatIndex = static_cast<int>(m_shape.format);
- const auto &colorType = m_parent->capabilities_.sk_color_types[formatIndex];
- DCHECK(colorType != kUnknown_SkColorType)
- << "SkColorType is invalid for format: " << formatIndex;
+ }
+ void initialize()
+ {
+ const auto &colorType = m_shape.imageInfo.colorType();
+ DCHECK(colorType != kUnknown_SkColorType);
m_texture = m_parent->m_contextState->gr_context()->createBackendTexture(
- m_shape.sizeInPixels.width(), m_shape.sizeInPixels.height(), colorType,
+ m_shape.imageInfo.width(), m_shape.imageInfo.height(), colorType,
GrMipMapped::kNo, GrRenderable::kYes);
DCHECK(m_texture.isValid());
- if (m_texture.backend() == GrBackendApi::kVulkan) {
- GrVkImageInfo info;
- bool result = m_texture.getVkImageInfo(&info);
- DCHECK(result);
- m_estimatedSize = info.fAlloc.fSize;
- } else {
- auto info = SkImageInfo::Make(m_shape.sizeInPixels.width(), m_shape.sizeInPixels.height(),
- colorType, kUnpremul_SkAlphaType);
- m_estimatedSize = info.computeMinByteSize();
- }
+ DCHECK(m_texture.backend() == GrBackendApi::kOpenGL);
+ auto info = SkImageInfo::Make(m_shape.imageInfo.width(), m_shape.imageInfo.height(),
+ colorType, kUnpremul_SkAlphaType);
+ m_estimatedSize = info.computeMinByteSize();
m_parent->memory_type_tracker_->TrackMemAlloc(m_estimatedSize);
- SkSurfaceProps surfaceProps = skia::LegacyDisplayGlobals::GetSkSurfaceProps();
- m_surface = SkSurface::MakeFromBackendTexture(
+ SkSurfaceProps surfaceProps = SkSurfaceProps{0, kUnknown_SkPixelGeometry};
+ m_surface = SkSurfaces::WrapBackendTexture(
m_parent->m_contextState->gr_context(), m_texture,
m_parent->capabilities_.output_surface_origin == gfx::SurfaceOrigin::kTopLeft
? kTopLeft_GrSurfaceOrigin
@@ -87,8 +52,10 @@ public:
~Buffer()
{
- DeleteGrBackendTexture(m_parent->m_contextState.get(), &m_texture);
- m_parent->memory_type_tracker_->TrackMemFree(m_estimatedSize);
+ if (m_texture.isValid()) {
+ DeleteGrBackendTexture(m_parent->m_contextState.get(), &m_texture);
+ m_parent->memory_type_tracker_->TrackMemFree(m_estimatedSize);
+ }
}
void createFence()
@@ -119,16 +86,20 @@ private:
DisplaySkiaOutputDevice::DisplaySkiaOutputDevice(
scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
gpu::MemoryTracker *memoryTracker,
DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
- : SkiaOutputDevice(
- contextState->gr_context(),
- memoryTracker,
- didSwapBufferCompleteCallback)
+ : SkiaOutputDevice(contextState->gr_context(), contextState->graphite_context(),
+ memoryTracker, didSwapBufferCompleteCallback)
, Compositor(Compositor::Type::OpenGL)
, m_contextState(contextState)
+ , m_requiresAlpha(requiresAlpha)
{
capabilities_.uses_default_gl_framebuffer = false;
+ capabilities_.supports_surfaceless = true;
+ capabilities_.preserve_buffer_content = true;
+ capabilities_.only_invalidates_damage_rect = false;
+ capabilities_.number_of_buffers = 3;
capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] =
kRGBA_8888_SkColorType;
@@ -148,20 +119,20 @@ void DisplaySkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id)
{
bind(id);
}
-
-bool DisplaySkiaOutputDevice::Reshape(const gfx::Size& sizeInPixels,
- float devicePixelRatio,
- const gfx::ColorSpace& colorSpace,
- gfx::BufferFormat format,
+bool DisplaySkiaOutputDevice::Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &colorSpace,
+ int sample_count,
+ float device_scale_factor,
gfx::OverlayTransform transform)
{
- m_shape = Shape{sizeInPixels, devicePixelRatio, colorSpace, format};
+ m_shape = Shape{image_info, device_scale_factor, colorSpace};
DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
return true;
}
-void DisplaySkiaOutputDevice::SwapBuffers(BufferPresentedCallback feedback,
- viz::OutputSurfaceFrame frame)
+void DisplaySkiaOutputDevice::Present(const absl::optional<gfx::Rect> &update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame)
{
DCHECK(m_backBuffer);
@@ -171,8 +142,8 @@ void DisplaySkiaOutputDevice::SwapBuffers(BufferPresentedCallback feedback,
{
QMutexLocker locker(&m_mutex);
- m_taskRunner = base::ThreadTaskRunnerHandle::Get();
- m_middleBuffer = std::move(m_backBuffer);
+ m_taskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ std::swap(m_middleBuffer, m_backBuffer);
m_readyToUpdate = true;
}
@@ -188,10 +159,12 @@ void DisplaySkiaOutputDevice::DiscardBackbuffer()
{
}
-SkSurface *DisplaySkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *)
+SkSurface *DisplaySkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *end_semaphores)
{
- if (!m_backBuffer || m_backBuffer->shape() != m_shape)
+ if (!m_backBuffer || m_backBuffer->shape() != m_shape) {
m_backBuffer = std::make_unique<Buffer>(this);
+ m_backBuffer->initialize();
+ }
return m_backBuffer->surface();
}
@@ -218,26 +191,33 @@ void DisplaySkiaOutputDevice::waitForTexture()
m_frontBuffer->consumeFence();
}
-int DisplaySkiaOutputDevice::textureId()
+QSGTexture *DisplaySkiaOutputDevice::texture(QQuickWindow *win, uint32_t textureOptions)
{
if (!m_frontBuffer)
- return 0;
+ return nullptr;
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture = nullptr;
GrGLTextureInfo info;
- if (!m_frontBuffer->texture().getGLTextureInfo(&info))
- return 0;
+ if (GrBackendTextures::GetGLTextureInfo(m_frontBuffer->texture(), &info))
+ texture = QNativeInterface::QSGOpenGLTexture::fromNative(info.fID, win, size(), texOpts);
+ return texture;
+}
- return info.fID;
+bool DisplaySkiaOutputDevice::textureIsFlipped()
+{
+ return true;
}
QSize DisplaySkiaOutputDevice::size()
{
- return m_frontBuffer ? toQt(m_frontBuffer->shape().sizeInPixels) : QSize();
+ return m_frontBuffer ? toQt(m_frontBuffer->shape().imageInfo.dimensions()) : QSize();
}
-bool DisplaySkiaOutputDevice::hasAlphaChannel()
+bool DisplaySkiaOutputDevice::requiresAlphaChannel()
{
- return true;
+ return m_requiresAlpha;
}
float DisplaySkiaOutputDevice::devicePixelRatio()
@@ -249,11 +229,11 @@ void DisplaySkiaOutputDevice::SwapBuffersFinished()
{
{
QMutexLocker locker(&m_mutex);
- m_backBuffer = std::move(m_middleBuffer);
+ std::swap(m_backBuffer, m_middleBuffer);
}
FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK),
- gfx::Size(m_shape.sizeInPixels.width(), m_shape.sizeInPixels.height()),
+ gfx::Size(m_shape.imageInfo.width(), m_shape.imageInfo.height()),
std::move(m_frame));
}
diff --git a/src/core/compositor/display_skia_output_device.h b/src/core/compositor/display_skia_output_device.h
index 2993e9147..e6a97b810 100644
--- a/src/core/compositor/display_skia_output_device.h
+++ b/src/core/compositor/display_skia_output_device.h
@@ -1,53 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DISPLAY_SKIA_OUTPUT_DEVICE_H
#define DISPLAY_SKIA_OUTPUT_DEVICE_H
-#include "compositor_resource_fence.h"
+#include <QtCore/QMutex>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+
#include "compositor.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/task/single_thread_task_runner.h"
#include "components/viz/service/display_embedder/skia_output_device.h"
#include "gpu/command_buffer/service/shared_context_state.h"
-#include <QMutex>
+QT_BEGIN_NAMESPACE
+class QQuickWindow;
+QT_END_NAMESPACE
namespace QtWebEngineCore {
@@ -55,19 +23,21 @@ class DisplaySkiaOutputDevice final : public viz::SkiaOutputDevice, public Compo
{
public:
DisplaySkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
gpu::MemoryTracker *memoryTracker,
DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
~DisplaySkiaOutputDevice() override;
// Overridden from SkiaOutputDevice.
void SetFrameSinkId(const viz::FrameSinkId &frame_sink_id) override;
- bool Reshape(const gfx::Size& size,
- float devicePixelRatio,
- const gfx::ColorSpace& colorSpace,
- gfx::BufferFormat format,
+ bool Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &color_space,
+ int sample_count,
+ float device_scale_factor,
gfx::OverlayTransform transform) override;
- void SwapBuffers(BufferPresentedCallback feedback,
- viz::OutputSurfaceFrame frame) override;
+ void Present(const absl::optional<gfx::Rect>& update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame) override;
void EnsureBackbuffer() override;
void DiscardBackbuffer() override;
SkSurface *BeginPaint(std::vector<GrBackendSemaphore> *semaphores) override;
@@ -76,25 +46,24 @@ public:
// Overridden from Compositor.
void swapFrame() override;
void waitForTexture() override;
- int textureId() override;
+ QSGTexture *texture(QQuickWindow *win, uint32_t texOpts) override;
+ bool textureIsFlipped() override;
QSize size() override;
- bool hasAlphaChannel() override;
+ bool requiresAlphaChannel() override;
float devicePixelRatio() override;
private:
struct Shape
{
- gfx::Size sizeInPixels;
+ SkImageInfo imageInfo;
float devicePixelRatio;
gfx::ColorSpace colorSpace;
- gfx::BufferFormat format;
bool operator==(const Shape &that) const
{
- return (sizeInPixels == that.sizeInPixels &&
+ return (imageInfo == that.imageInfo &&
devicePixelRatio == that.devicePixelRatio &&
- colorSpace == that.colorSpace &&
- format == that.format);
+ colorSpace == that.colorSpace);
}
bool operator!=(const Shape &that) const { return !(*this == that); }
};
@@ -111,6 +80,7 @@ private:
std::unique_ptr<Buffer> m_backBuffer;
viz::OutputSurfaceFrame m_frame;
bool m_readyToUpdate = false;
+ bool m_requiresAlpha;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
};
diff --git a/src/core/compositor/display_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp
index b811449c9..2c208ca57 100644
--- a/src/core/compositor/display_software_output_surface.cpp
+++ b/src/core/compositor/display_software_output_surface.cpp
@@ -1,54 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "display_software_output_surface.h"
#include "compositor.h"
-#include "render_widget_host_view_qt_delegate.h"
#include "type_conversion.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/task/single_thread_task_runner.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/output_surface_frame.h"
#include <QMutex>
#include <QPainter>
+#include <QQuickWindow>
namespace QtWebEngineCore {
@@ -56,36 +20,34 @@ class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDev
public Compositor
{
public:
- Device();
- ~Device();
+ Device(bool requiresAlpha);
// Overridden from viz::SoftwareOutputDevice.
void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override;
- void OnSwapBuffers(SwapBuffersCallback swap_ack_callback) override;
+ void OnSwapBuffers(SwapBuffersCallback swap_ack_callback, gfx::FrameData data) override;
// Overridden from Compositor.
void swapFrame() override;
- QImage image() override;
+ QSGTexture *texture(QQuickWindow *win, uint32_t) override;
+ bool textureIsFlipped() override;
float devicePixelRatio() override;
QSize size() override;
- bool hasAlphaChannel() override;
+ bool requiresAlphaChannel() override;
private:
mutable QMutex m_mutex;
float m_devicePixelRatio = 1.0;
+ bool m_requiresAlpha;
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
SwapBuffersCallback m_swapCompletionCallback;
QImage m_image;
float m_imageDevicePixelRatio = 1.0;
};
-DisplaySoftwareOutputSurface::Device::Device()
+DisplaySoftwareOutputSurface::Device::Device(bool requiresAlpha)
: Compositor(Type::Software)
-{}
-
-DisplaySoftwareOutputSurface::Device::~Device()
+ , m_requiresAlpha(requiresAlpha)
{
- unbind();
}
void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio)
@@ -94,14 +56,14 @@ void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels,
return;
m_devicePixelRatio = devicePixelRatio;
viewport_pixel_size_ = sizeInPixels;
- surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(sizeInPixels.width(), sizeInPixels.height()));
+ surface_ = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(sizeInPixels.width(), sizeInPixels.height()));
}
-void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(SwapBuffersCallback swap_ack_callback)
+void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(SwapBuffersCallback swap_ack_callback, gfx::FrameData data)
{
{ // MEMO don't hold a lock together with an 'observer', as the call from Qt's scene graph may come at the same time
QMutexLocker locker(&m_mutex);
- m_taskRunner = base::ThreadTaskRunnerHandle::Get();
+ m_taskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
m_swapCompletionCallback = std::move(swap_ack_callback);
}
@@ -149,9 +111,14 @@ void DisplaySoftwareOutputSurface::Device::swapFrame()
m_taskRunner.reset();
}
-QImage DisplaySoftwareOutputSurface::Device::image()
+QSGTexture *DisplaySoftwareOutputSurface::Device::texture(QQuickWindow *win, uint32_t)
+{
+ return win->createTextureFromImage(m_image);
+}
+
+bool DisplaySoftwareOutputSurface::Device::textureIsFlipped()
{
- return m_image;
+ return false;
}
float DisplaySoftwareOutputSurface::Device::devicePixelRatio()
@@ -164,13 +131,13 @@ QSize DisplaySoftwareOutputSurface::Device::size()
return m_image.size();
}
-bool DisplaySoftwareOutputSurface::Device::hasAlphaChannel()
+bool DisplaySoftwareOutputSurface::Device::requiresAlphaChannel()
{
- return m_image.format() == QImage::Format_ARGB32_Premultiplied;
+ return m_requiresAlpha;
}
-DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface()
- : SoftwareOutputSurface(std::make_unique<Device>())
+DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface(bool requiresAlpha)
+ : SoftwareOutputSurface(std::make_unique<Device>(requiresAlpha))
{}
DisplaySoftwareOutputSurface::~DisplaySoftwareOutputSurface() {}
diff --git a/src/core/compositor/display_software_output_surface.h b/src/core/compositor/display_software_output_surface.h
index 27687c7c0..d23664d56 100644
--- a/src/core/compositor/display_software_output_surface.h
+++ b/src/core/compositor/display_software_output_surface.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
#define DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
@@ -47,7 +11,7 @@ namespace QtWebEngineCore {
class DisplaySoftwareOutputSurface final : public viz::SoftwareOutputSurface
{
public:
- DisplaySoftwareOutputSurface();
+ DisplaySoftwareOutputSurface(bool requiresAlpha);
~DisplaySoftwareOutputSurface() override;
// Overridden from viz::OutputSurface.
diff --git a/src/core/compositor/native_skia_output_device.cpp b/src/core/compositor/native_skia_output_device.cpp
new file mode 100644
index 000000000..8f11e5162
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device.cpp
@@ -0,0 +1,418 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "native_skia_output_device.h"
+
+#include "type_conversion.h"
+
+#include "components/viz/common/resources/shared_image_format.h"
+#include "components/viz/common/resources/shared_image_format_utils.h"
+#include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/command_buffer/service/skia_utils.h"
+#include "third_party/skia/include/gpu/GrDirectContext.h"
+#include "third_party/skia/include/core/SkSurfaceProps.h"
+#include "ui/gfx/native_pixmap.h"
+#include "ui/gfx/gpu_fence.h"
+#include "ui/gl/gl_fence.h"
+
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#endif
+
+namespace QtWebEngineCore {
+
+namespace {
+
+// Helper function for moving a GpuFence from a fence handle to a unique_ptr.
+std::unique_ptr<gfx::GpuFence> TakeGpuFence(gfx::GpuFenceHandle fence)
+{
+ return fence.is_null() ? nullptr : std::make_unique<gfx::GpuFence>(std::move(fence));
+}
+
+} // namespace
+
+NativeSkiaOutputDevice::NativeSkiaOutputDevice(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : SkiaOutputDevice(contextState->gr_context(), contextState->graphite_context(), memoryTracker,
+ didSwapBufferCompleteCallback)
+ , Compositor(Type::Native)
+ , m_contextState(contextState)
+ , m_requiresAlpha(requiresAlpha)
+ , m_factory(shared_image_factory)
+ , m_representationFactory(shared_image_representation_factory)
+ , m_deps(dependency)
+{
+ capabilities_.uses_default_gl_framebuffer = false;
+ capabilities_.supports_surfaceless = true;
+ capabilities_.output_surface_origin = gfx::SurfaceOrigin::kTopLeft;
+ capabilities_.preserve_buffer_content = true;
+ capabilities_.only_invalidates_damage_rect = false;
+
+#if defined(USE_OZONE)
+ m_isNativeBufferSupported = ui::OzonePlatform::GetInstance()
+ ->GetPlatformRuntimeProperties()
+ .supports_native_pixmaps;
+#endif
+}
+
+NativeSkiaOutputDevice::~NativeSkiaOutputDevice()
+{
+}
+
+void NativeSkiaOutputDevice::SetFrameSinkId(const viz::FrameSinkId &id)
+{
+ bind(id);
+}
+
+bool NativeSkiaOutputDevice::Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &colorSpace,
+ int sample_count,
+ float device_scale_factor,
+ gfx::OverlayTransform transform)
+{
+ m_shape = Shape{image_info, device_scale_factor, colorSpace, sample_count};
+ DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
+ return true;
+}
+
+void NativeSkiaOutputDevice::Present(const absl::optional<gfx::Rect> &update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame)
+{
+ DCHECK(m_backBuffer);
+
+ StartSwapBuffers(std::move(feedback));
+ m_frame = std::move(frame);
+ {
+ QMutexLocker locker(&m_mutex);
+ m_backBuffer->createFence();
+ m_gpuTaskRunner = base::SingleThreadTaskRunner::GetCurrentDefault();
+ std::swap(m_middleBuffer, m_backBuffer);
+ m_readyToUpdate = true;
+ }
+
+ if (auto obs = observer())
+ obs->readyToSwap();
+}
+
+void NativeSkiaOutputDevice::EnsureBackbuffer()
+{
+}
+
+void NativeSkiaOutputDevice::DiscardBackbuffer()
+{
+}
+
+SkSurface *NativeSkiaOutputDevice::BeginPaint(std::vector<GrBackendSemaphore> *end_semaphores)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ if (!m_backBuffer || m_backBuffer->shape() != m_shape) {
+ m_backBuffer = std::make_unique<Buffer>(this);
+ if (!m_backBuffer->initialize())
+ return nullptr;
+ }
+ }
+ auto surface = m_backBuffer->beginWriteSkia();
+ *end_semaphores = m_backBuffer->takeEndWriteSkiaSemaphores();
+ return surface;
+}
+
+void NativeSkiaOutputDevice::EndPaint()
+{
+ m_backBuffer->endWriteSkia(true);
+}
+
+void NativeSkiaOutputDevice::swapFrame()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_readyToUpdate) {
+ std::swap(m_frontBuffer, m_middleBuffer);
+ m_gpuTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::SwapBuffersFinished,
+ base::Unretained(this)));
+ m_readyToUpdate = false;
+ if (m_frontBuffer) {
+ m_readyWithTexture = true;
+ m_frontBuffer->beginPresent();
+ }
+ if (m_middleBuffer)
+ m_middleBuffer->freeTexture();
+ m_gpuTaskRunner.reset();
+ }
+}
+
+void NativeSkiaOutputDevice::waitForTexture()
+{
+ if (m_readyWithTexture)
+ m_frontBuffer->consumeFence();
+}
+
+void NativeSkiaOutputDevice::releaseTexture()
+{
+ if (m_readyWithTexture) {
+ m_frontBuffer->endPresent();
+ m_readyWithTexture = false;
+ }
+}
+
+void NativeSkiaOutputDevice::releaseResources()
+{
+ if (m_frontBuffer)
+ m_frontBuffer->freeTexture();
+}
+
+bool NativeSkiaOutputDevice::textureIsFlipped()
+{
+ return false;
+}
+
+QSize NativeSkiaOutputDevice::size()
+{
+ return m_frontBuffer ? toQt(m_frontBuffer->shape().imageInfo.dimensions()) : QSize();
+}
+
+bool NativeSkiaOutputDevice::requiresAlphaChannel()
+{
+ return m_requiresAlpha;
+}
+
+float NativeSkiaOutputDevice::devicePixelRatio()
+{
+ return m_frontBuffer ? m_frontBuffer->shape().devicePixelRatio : 1;
+}
+
+void NativeSkiaOutputDevice::SwapBuffersFinished()
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ std::swap(m_backBuffer, m_middleBuffer);
+ }
+
+ FinishSwapBuffers(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK),
+ gfx::Size(m_shape.imageInfo.width(), m_shape.imageInfo.height()),
+ std::move(m_frame));
+}
+
+NativeSkiaOutputDevice::Buffer::Buffer(NativeSkiaOutputDevice *parent)
+ : m_parent(parent), m_shape(m_parent->m_shape)
+{
+}
+
+NativeSkiaOutputDevice::Buffer::~Buffer()
+{
+ if (m_scopedSkiaWriteAccess)
+ endWriteSkia(false);
+
+ if (!m_mailbox.IsZero())
+ m_parent->m_factory->DestroySharedImage(m_mailbox);
+}
+
+// The following Buffer methods are based on
+// components/viz/service/display_embedder/output_presenter.cc: Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+bool NativeSkiaOutputDevice::Buffer::initialize()
+{
+ static const uint32_t kDefaultSharedImageUsage = gpu::SHARED_IMAGE_USAGE_SCANOUT
+ | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE
+ | gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+ auto mailbox = gpu::Mailbox::GenerateForSharedImage();
+
+ SkColorType skColorType = m_shape.imageInfo.colorType();
+ if (!m_parent->m_factory->CreateSharedImage(
+ mailbox, viz::SkColorTypeToSinglePlaneSharedImageFormat(skColorType),
+ { m_shape.imageInfo.width(), m_shape.imageInfo.height() }, m_shape.colorSpace,
+ kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, m_parent->m_deps->GetSurfaceHandle(),
+ kDefaultSharedImageUsage, "QWE_SharedImageBuffer")) {
+ LOG(ERROR) << "CreateSharedImage failed.";
+ return false;
+ }
+ m_mailbox = mailbox;
+
+ m_skiaRepresentation =
+ m_parent->m_representationFactory->ProduceSkia(m_mailbox, m_parent->m_contextState);
+ if (!m_skiaRepresentation) {
+ LOG(ERROR) << "ProduceSkia() failed.";
+ return false;
+ }
+
+ if (m_parent->m_isNativeBufferSupported) {
+ m_overlayRepresentation = m_parent->m_representationFactory->ProduceOverlay(m_mailbox);
+ if (!m_overlayRepresentation) {
+ LOG(ERROR) << "ProduceOverlay() failed";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+SkSurface *NativeSkiaOutputDevice::Buffer::beginWriteSkia()
+{
+ DCHECK(!m_scopedSkiaWriteAccess);
+ DCHECK(!m_presentCount);
+ DCHECK(m_endSemaphores.empty());
+
+ std::vector<GrBackendSemaphore> beginSemaphores;
+ SkSurfaceProps surface_props{ 0, kUnknown_SkPixelGeometry };
+
+ // Buffer queue is internal to GPU proc and handles texture initialization,
+ // so allow uncleared access.
+ m_scopedSkiaWriteAccess = m_skiaRepresentation->BeginScopedWriteAccess(
+ m_shape.sampleCount, surface_props, &beginSemaphores, &m_endSemaphores,
+ gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
+ DCHECK(m_scopedSkiaWriteAccess);
+ if (!beginSemaphores.empty()) {
+ m_scopedSkiaWriteAccess->surface()->wait(beginSemaphores.size(), beginSemaphores.data(),
+ /*deleteSemaphoresAfterWait=*/false);
+ }
+ return m_scopedSkiaWriteAccess->surface();
+}
+
+void NativeSkiaOutputDevice::Buffer::endWriteSkia(bool force_flush)
+{
+ // The Flush now takes place in finishPaintCurrentBuffer on the CPU side.
+ // check if end_semaphores is not empty then flush here
+ DCHECK(m_scopedSkiaWriteAccess);
+ if (!m_endSemaphores.empty() || force_flush) {
+ GrFlushInfo flush_info = {};
+ flush_info.fNumSemaphores = m_endSemaphores.size();
+ flush_info.fSignalSemaphores = m_endSemaphores.data();
+ auto *direct_context =
+ m_scopedSkiaWriteAccess->surface()->recordingContext()->asDirectContext();
+ DCHECK(direct_context);
+ direct_context->flush(m_scopedSkiaWriteAccess->surface(), {});
+ m_scopedSkiaWriteAccess->ApplyBackendSurfaceEndState();
+ direct_context->flush(m_scopedSkiaWriteAccess->surface(), flush_info, nullptr);
+ direct_context->submit();
+ }
+ m_scopedSkiaWriteAccess.reset();
+ m_endSemaphores.clear();
+
+ // SkiaRenderer always draws the full frame.
+ m_skiaRepresentation->SetCleared();
+}
+
+std::vector<GrBackendSemaphore> NativeSkiaOutputDevice::Buffer::takeEndWriteSkiaSemaphores()
+{
+ return std::exchange(m_endSemaphores, {});
+}
+
+void NativeSkiaOutputDevice::Buffer::createSkImageOnGPUThread()
+{
+ if (!m_scopedSkiaReadAccess)
+ return;
+
+ QMutexLocker locker(&m_skImageMutex);
+ m_cachedSkImage = m_scopedSkiaReadAccess->CreateSkImage(m_parent->m_contextState.get());
+ if (!m_cachedSkImage)
+ qWarning("SKIA: Failed to create SkImage.");
+}
+
+void NativeSkiaOutputDevice::Buffer::beginPresent()
+{
+ if (++m_presentCount != 1) {
+ DCHECK(m_scopedOverlayReadAccess || m_scopedSkiaReadAccess);
+ return;
+ }
+
+ DCHECK(!m_scopedSkiaWriteAccess);
+ DCHECK(!m_scopedOverlayReadAccess && !m_scopedSkiaReadAccess);
+
+ if (m_overlayRepresentation) {
+ m_scopedOverlayReadAccess = m_overlayRepresentation->BeginScopedReadAccess();
+ DCHECK(m_scopedOverlayReadAccess);
+ m_acquireFence = TakeGpuFence(m_scopedOverlayReadAccess->TakeAcquireFence());
+ } else {
+ DCHECK(m_skiaRepresentation);
+ std::vector<GrBackendSemaphore> beginSemaphores;
+ m_scopedSkiaReadAccess =
+ m_skiaRepresentation->BeginScopedReadAccess(&beginSemaphores, nullptr);
+ DCHECK(m_scopedSkiaReadAccess);
+ if (!beginSemaphores.empty())
+ qWarning("SKIA: Unexpected semaphores while reading texture, wait is not implemented.");
+
+ m_parent->m_gpuTaskRunner->PostTask(FROM_HERE,
+ base::BindOnce(&NativeSkiaOutputDevice::Buffer::createSkImageOnGPUThread,
+ base::Unretained(this)));
+ }
+}
+
+void NativeSkiaOutputDevice::Buffer::endPresent()
+{
+ if (!m_presentCount)
+ return;
+ DCHECK(m_scopedOverlayReadAccess || m_scopedSkiaReadAccess);
+ if (--m_presentCount)
+ return;
+
+ if (m_scopedOverlayReadAccess) {
+ DCHECK(!m_scopedSkiaReadAccess);
+ m_scopedOverlayReadAccess.reset();
+ } else if (m_scopedSkiaReadAccess) {
+ DCHECK(!m_scopedOverlayReadAccess);
+ QMutexLocker locker(&m_skImageMutex);
+ m_scopedSkiaReadAccess.reset();
+ }
+}
+
+void NativeSkiaOutputDevice::Buffer::freeTexture()
+{
+ if (textureCleanupCallback) {
+ textureCleanupCallback();
+ textureCleanupCallback = nullptr;
+ }
+}
+
+void NativeSkiaOutputDevice::Buffer::createFence()
+{
+ // For some reason we still need to create this, but we do not need to wait on it.
+ if (m_parent->m_contextState->gr_context_type() == gpu::GrContextType::kGL)
+ m_fence = gl::GLFence::Create();
+}
+
+void NativeSkiaOutputDevice::Buffer::consumeFence()
+{
+ if (m_acquireFence) {
+ m_acquireFence->Wait();
+ m_acquireFence.reset();
+ }
+}
+
+sk_sp<SkImage> NativeSkiaOutputDevice::Buffer::skImage()
+{
+ return m_cachedSkImage;
+}
+#if defined(USE_OZONE)
+scoped_refptr<gfx::NativePixmap> NativeSkiaOutputDevice::Buffer::nativePixmap()
+{
+ DCHECK(m_presentCount);
+ if (!m_scopedOverlayReadAccess)
+ return nullptr;
+
+ return m_scopedOverlayReadAccess->GetNativePixmap();
+}
+#elif defined(Q_OS_WIN)
+absl::optional<gl::DCLayerOverlayImage> NativeSkiaOutputDevice::Buffer::overlayImage() const
+{
+ DCHECK(m_presentCount);
+ return m_scopedOverlayReadAccess->GetDCLayerOverlayImage();
+}
+#elif defined(Q_OS_MACOS)
+gfx::ScopedIOSurface NativeSkiaOutputDevice::Buffer::ioSurface() const
+{
+ DCHECK(m_presentCount);
+ return m_scopedOverlayReadAccess->GetIOSurface();
+}
+#endif
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device.h b/src/core/compositor/native_skia_output_device.h
new file mode 100644
index 000000000..2c35cef77
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device.h
@@ -0,0 +1,183 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_H
+
+#include "compositor.h"
+
+#include "base/task/single_thread_task_runner.h"
+#include "components/viz/service/display_embedder/skia_output_device.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/config/gpu_preferences.h"
+
+#include <QMutex>
+
+#if defined(Q_OS_WIN)
+#include "ui/gl/dc_layer_overlay_image.h"
+#endif
+
+#if defined(Q_OS_MACOS)
+#include "ui/gfx/mac/io_surface.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+class QQuickWindow;
+QT_END_NAMESPACE
+
+namespace gl {
+class GLFence;
+}
+
+namespace gfx {
+class GpuFence;
+class NativePixmap;
+}
+
+namespace gpu {
+class SharedImageFactory;
+class SharedImageRepresentationFactory;
+}
+
+namespace viz {
+class SkiaOutputSurfaceDependency;
+}
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDevice : public viz::SkiaOutputDevice, public Compositor
+{
+public:
+ NativeSkiaOutputDevice(scoped_refptr<gpu::SharedContextState> contextState,
+ bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker,
+ viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDevice() override;
+
+ // Overridden from SkiaOutputDevice.
+ void SetFrameSinkId(const viz::FrameSinkId &frame_sink_id) override;
+ bool Reshape(const SkImageInfo &image_info,
+ const gfx::ColorSpace &color_space,
+ int sample_count,
+ float device_scale_factor,
+ gfx::OverlayTransform transform) override;
+ void Present(const absl::optional<gfx::Rect>& update_rect,
+ BufferPresentedCallback feedback,
+ viz::OutputSurfaceFrame frame) override;
+ void EnsureBackbuffer() override;
+ void DiscardBackbuffer() override;
+ SkSurface *BeginPaint(std::vector<GrBackendSemaphore> *semaphores) override;
+ void EndPaint() override;
+
+ // Overridden from Compositor.
+ void swapFrame() override;
+ void waitForTexture() override;
+ void releaseTexture() override;
+ void releaseResources() override;
+ bool textureIsFlipped() override;
+ QSize size() override;
+ bool requiresAlphaChannel() override;
+ float devicePixelRatio() override;
+
+protected:
+ struct Shape
+ {
+ SkImageInfo imageInfo;
+ float devicePixelRatio;
+ gfx::ColorSpace colorSpace;
+ int sampleCount;
+
+ bool operator==(const Shape &that) const
+ {
+ return (imageInfo == that.imageInfo &&
+ devicePixelRatio == that.devicePixelRatio &&
+ colorSpace == that.colorSpace &&
+ sampleCount == that.sampleCount);
+ }
+ bool operator!=(const Shape &that) const { return !(*this == that); }
+ };
+
+ class Buffer
+ {
+ public:
+ Buffer(NativeSkiaOutputDevice *parent);
+ ~Buffer();
+
+ bool initialize();
+ SkSurface *beginWriteSkia();
+ void endWriteSkia(bool force_flush);
+ std::vector<GrBackendSemaphore> takeEndWriteSkiaSemaphores();
+ void beginPresent();
+ void endPresent();
+ void freeTexture();
+ void createFence();
+ void consumeFence();
+
+ sk_sp<SkImage> skImage();
+#if defined(USE_OZONE)
+ scoped_refptr<gfx::NativePixmap> nativePixmap();
+#elif defined(Q_OS_WIN)
+ absl::optional<gl::DCLayerOverlayImage> overlayImage() const;
+#elif defined(Q_OS_MACOS)
+ gfx::ScopedIOSurface ioSurface() const;
+#endif
+
+ const Shape &shape() const { return m_shape; }
+ viz::SharedImageFormat sharedImageFormat() const { return m_skiaRepresentation->format(); }
+
+ std::function<void()> textureCleanupCallback;
+
+ private:
+ void createSkImageOnGPUThread();
+
+ NativeSkiaOutputDevice *m_parent;
+ Shape m_shape;
+ uint64_t m_estimatedSize = 0; // FIXME: estimate size
+ std::unique_ptr<gfx::GpuFence> m_acquireFence;
+ std::unique_ptr<gl::GLFence> m_fence;
+ gpu::Mailbox m_mailbox;
+ std::unique_ptr<gpu::SkiaImageRepresentation> m_skiaRepresentation;
+ std::unique_ptr<gpu::SkiaImageRepresentation::ScopedWriteAccess> m_scopedSkiaWriteAccess;
+ std::unique_ptr<gpu::SkiaImageRepresentation::ScopedReadAccess> m_scopedSkiaReadAccess;
+ std::unique_ptr<gpu::OverlayImageRepresentation> m_overlayRepresentation;
+ std::unique_ptr<gpu::OverlayImageRepresentation::ScopedReadAccess>
+ m_scopedOverlayReadAccess;
+ std::vector<GrBackendSemaphore> m_endSemaphores;
+ int m_presentCount = 0;
+
+ mutable QMutex m_skImageMutex;
+ sk_sp<SkImage> m_cachedSkImage;
+ };
+
+protected:
+ scoped_refptr<gpu::SharedContextState> m_contextState;
+ std::unique_ptr<Buffer> m_frontBuffer;
+ bool m_readyWithTexture = false;
+ bool m_isNativeBufferSupported = true;
+
+private:
+ friend class NativeSkiaOutputDevice::Buffer;
+
+ void SwapBuffersFinished();
+
+ mutable QMutex m_mutex;
+ Shape m_shape;
+ std::unique_ptr<Buffer> m_middleBuffer;
+ std::unique_ptr<Buffer> m_backBuffer;
+ viz::OutputSurfaceFrame m_frame;
+ bool m_readyToUpdate = false;
+ bool m_requiresAlpha;
+ scoped_refptr<base::SingleThreadTaskRunner> m_gpuTaskRunner;
+
+ const raw_ptr<gpu::SharedImageFactory> m_factory;
+ const raw_ptr<gpu::SharedImageRepresentationFactory> m_representationFactory;
+ const raw_ptr<viz::SkiaOutputSurfaceDependency> m_deps;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !NATIVE_SKIA_OUTPUT_DEVICE_H
diff --git a/src/core/compositor/native_skia_output_device_direct3d11.cpp b/src/core/compositor/native_skia_output_device_direct3d11.cpp
new file mode 100644
index 000000000..352fa9f92
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_direct3d11.cpp
@@ -0,0 +1,88 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "native_skia_output_device_direct3d11.h"
+
+#include <QtCore/private/qsystemerror_p.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+#include <d3d11_1.h>
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceDirect3D11::NativeSkiaOutputDeviceDirect3D11(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceDirect3D11::~NativeSkiaOutputDeviceDirect3D11() { }
+
+QSGTexture *NativeSkiaOutputDeviceDirect3D11::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+ absl::optional<gl::DCLayerOverlayImage> overlayImage = m_frontBuffer->overlayImage();
+ if (!overlayImage) {
+ qWarning("No overlay image.");
+ return nullptr;
+ }
+
+ QSGRendererInterface *ri = win->rendererInterface();
+
+ HRESULT status = S_OK;
+ HANDLE sharedHandle = nullptr;
+ IDXGIResource1 *resource = nullptr;
+ if (!overlayImage->nv12_texture()) {
+ qWarning("No D3D texture.");
+ return nullptr;
+ }
+ status = overlayImage->nv12_texture()->QueryInterface(__uuidof(IDXGIResource1),
+ (void **)&resource);
+ Q_ASSERT(status == S_OK);
+ status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
+ Q_ASSERT(status == S_OK);
+ Q_ASSERT(sharedHandle);
+
+ // Pass texture between two D3D devices:
+ ID3D11Device1 *device = static_cast<ID3D11Device1 *>(
+ ri->getResource(win, QSGRendererInterface::DeviceResource));
+
+ ID3D11Texture2D *qtTexture;
+ status = device->OpenSharedResource1(sharedHandle, __uuidof(ID3D11Texture2D),
+ (void **)&qtTexture);
+ if (status != S_OK) {
+ qWarning("Failed to share D3D11 texture (%s). This will result in failed rendering. Report "
+ "the bug, and try restarting with QTWEBENGINE_CHROMIUM_FLAGS=--disble-gpu",
+ qPrintable(QSystemError::windowsComString(status)));
+ ::CloseHandle(sharedHandle);
+ return nullptr;
+ }
+
+ Q_ASSERT(qtTexture);
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture =
+ QNativeInterface::QSGD3D11Texture::fromNative(qtTexture, win, size(), texOpts);
+
+ m_frontBuffer->textureCleanupCallback = [qtTexture, sharedHandle]() {
+ qtTexture->Release();
+ ::CloseHandle(sharedHandle);
+ };
+
+ return texture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_direct3d11.h b/src/core/compositor/native_skia_output_device_direct3d11.h
new file mode 100644
index 000000000..33cf1bcd6
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_direct3d11.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_DIRECT3D11_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_DIRECT3D11_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceDirect3D11 final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceDirect3D11(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceDirect3D11() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_DIRECT3D11_H
diff --git a/src/core/compositor/native_skia_output_device_mac.mm b/src/core/compositor/native_skia_output_device_mac.mm
new file mode 100644
index 000000000..fd3930a9f
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_mac.mm
@@ -0,0 +1,90 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// This is a workaround to be able to include Qt headers without
+// "redefinition of 'NSString' as different kind of symbol" errors.
+// TODO: Remove this when namespace ambiguity issues are fixed properly,
+// see get_forward_declaration_macro() in cmake/Functions.cmake
+#undef Q_FORWARD_DECLARE_OBJC_CLASS
+
+#import <AppKit/AppKit.h>
+#import <IOSurface/IOSurface.h>
+#import <Metal/Metal.h>
+
+#include <QtGui/qtguiglobal.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgrendererinterface.h>
+#include <QtQuick/qsgtexture.h>
+
+#if QT_CONFIG(opengl)
+#include <OpenGL/OpenGL.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglextrafunctions.h>
+#include <QtOpenGL/qopengltextureblitter.h>
+#include <QtOpenGL/qopenglframebufferobject.h>
+#endif
+
+namespace QtWebEngineCore {
+
+QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef ioSurface, uint ioSurfacePlane,
+ const QSize &size, QQuickWindow::CreateTextureOptions texOpts)
+{
+ auto desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
+ width:size.width()
+ height:size.height()
+ mipmapped:false];
+
+ QSGRendererInterface *ri = win->rendererInterface();
+ auto device = (__bridge id<MTLDevice>)(ri->getResource(win, QSGRendererInterface::DeviceResource));
+ auto texture = [device newTextureWithDescriptor:desc iosurface:ioSurface plane:ioSurfacePlane];
+ return QNativeInterface::QSGMetalTexture::fromNative(texture, win, size, texOpts);
+}
+
+#if QT_CONFIG(opengl)
+uint32_t makeCGLTexture(QQuickWindow *win, IOSurfaceRef ioSurface, const QSize &size)
+{
+ const int width = size.width();
+ const int height = size.height();
+
+ auto glContext = QOpenGLContext::currentContext();
+ auto glFun = glContext->extraFunctions();
+ auto nscontext = glContext->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
+ CGLContextObj cglContext = [nscontext CGLContextObj];
+
+ win->beginExternalCommands();
+ // Bind the IO surface to a texture
+ GLuint glTexture;
+ glFun->glGenTextures(1, &glTexture);
+ glFun->glBindTexture(GL_TEXTURE_RECTANGLE_ARB, glTexture);
+ CGLTexImageIOSurface2D(cglContext, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, width, height, GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV, ioSurface, 0);
+ glFun->glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+ glFun->glViewport(0, 0, width, height);
+
+ // The bound IO surface is a weird dynamic bind, so take a snapshot of it to a normal texture
+ {
+ QOpenGLFramebufferObject fbo(width, height, GL_TEXTURE_2D);
+ auto success = fbo.bind();
+ Q_ASSERT(success);
+
+ QOpenGLTextureBlitter blitter;
+ success = blitter.create();
+ Q_ASSERT(success);
+ glFun->glDisable(GL_BLEND);
+ glFun->glDisable(GL_SCISSOR_TEST);
+ blitter.bind(GL_TEXTURE_RECTANGLE_ARB);
+ blitter.blit(glTexture, {}, QOpenGLTextureBlitter::OriginBottomLeft);
+ blitter.release();
+ blitter.destroy();
+
+ glFun->glDeleteTextures(1, &glTexture);
+ glTexture = fbo.takeTexture();
+ fbo.release();
+ }
+ win->endExternalCommands();
+
+ return glTexture;
+}
+#endif // QT_CONFIG(opengl)
+
+} // namespace
diff --git a/src/core/compositor/native_skia_output_device_metal.cpp b/src/core/compositor/native_skia_output_device_metal.cpp
new file mode 100644
index 000000000..95ed02779
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_metal.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "native_skia_output_device_metal.h"
+
+#include <QtQuick/qquickwindow.h>
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceMetal::NativeSkiaOutputDeviceMetal(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceMetal::~NativeSkiaOutputDeviceMetal() { }
+
+QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef ioSurface, uint ioSurfacePlane,
+ const QSize &size, QQuickWindow::CreateTextureOptions texOpts);
+
+QSGTexture *NativeSkiaOutputDeviceMetal::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+ gfx::ScopedIOSurface ioSurface = m_frontBuffer->ioSurface();
+ if (!ioSurface) {
+ qWarning("No IOSurface.");
+ return nullptr;
+ }
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ return makeMetalTexture(win, ioSurface.release(), /* plane */ 0, size(), texOpts);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_metal.h b/src/core/compositor/native_skia_output_device_metal.h
new file mode 100644
index 000000000..e61665fb5
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_metal.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_METAL_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_METAL_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceMetal final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceMetal(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceMetal() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_METAL_H
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
new file mode 100644
index 000000000..ea4c0c500
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -0,0 +1,86 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "native_skia_output_device_opengl.h"
+
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglextrafunctions.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceOpenGL::NativeSkiaOutputDeviceOpenGL(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceOpenGL::~NativeSkiaOutputDeviceOpenGL() { }
+
+#if defined(Q_OS_MACOS)
+uint32_t makeCGLTexture(QQuickWindow *win, IOSurfaceRef ioSurface, const QSize &size);
+#endif
+
+QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+#if defined(USE_OZONE)
+ scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
+ if (!nativePixmap) {
+ qWarning("No native pixmap.");
+ return nullptr;
+ }
+#elif defined(Q_OS_WIN)
+ auto overlayImage = m_frontBuffer->overlayImage();
+ if (!overlayImage) {
+ qWarning("No overlay image.");
+ return nullptr;
+ }
+#elif defined(Q_OS_MACOS)
+ gfx::ScopedIOSurface ioSurface = m_frontBuffer->ioSurface();
+ if (!ioSurface) {
+ qWarning("No IOSurface.");
+ return nullptr;
+ }
+#endif
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture = nullptr;
+
+#if defined(USE_OZONE)
+ // TODO(QTBUG-112281): Add ANGLE support to Linux.
+ QT_NOT_YET_IMPLEMENTED
+#elif defined(Q_OS_WIN)
+ // TODO: Add WGL support over ANGLE.
+ QT_NOT_YET_IMPLEMENTED
+#elif defined(Q_OS_MACOS)
+ uint32_t glTexture = makeCGLTexture(win, ioSurface.release(), size());
+ texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
+
+ m_frontBuffer->textureCleanupCallback = [glTexture]() {
+ auto *glContext = QOpenGLContext::currentContext();
+ if (!glContext)
+ return;
+ auto glFun = glContext->functions();
+ glFun->glDeleteTextures(1, &glTexture);
+ };
+#endif
+
+ return texture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_opengl.h b/src/core/compositor/native_skia_output_device_opengl.h
new file mode 100644
index 000000000..233f51df9
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_opengl.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_OPENGL_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_OPENGL_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceOpenGL final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceOpenGL(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceOpenGL() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_OPENGL_H
diff --git a/src/core/compositor/native_skia_output_device_vulkan.cpp b/src/core/compositor/native_skia_output_device_vulkan.cpp
new file mode 100644
index 000000000..c2ad7a382
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_vulkan.cpp
@@ -0,0 +1,306 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "native_skia_output_device_vulkan.h"
+
+#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
+
+#include <QtGui/qvulkaninstance.h>
+#include <QtGui/qvulkanfunctions.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
+
+#if defined(USE_OZONE)
+#include "ui/ozone/buildflags.h"
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+// We need to define USE_VULKAN_XCB for proper vulkan function pointers.
+// Avoiding it may lead to call wrong vulkan functions.
+// This is originally defined in chromium/gpu/vulkan/BUILD.gn.
+#define USE_VULKAN_XCB
+#endif // BUILDFLAG(OZONE_PLATFORM_X11)
+#include "gpu/vulkan/vulkan_function_pointers.h"
+
+#include "components/viz/common/gpu/vulkan_context_provider.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#endif // defined(USE_OZONE)
+
+namespace QtWebEngineCore {
+
+NativeSkiaOutputDeviceVulkan::NativeSkiaOutputDeviceVulkan(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
+ : NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
+ shared_image_factory, shared_image_representation_factory,
+ didSwapBufferCompleteCallback)
+{
+ SkColorType skColorType = kRGBA_8888_SkColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
+ capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
+}
+
+NativeSkiaOutputDeviceVulkan::~NativeSkiaOutputDeviceVulkan() { }
+
+QSGTexture *NativeSkiaOutputDeviceVulkan::texture(QQuickWindow *win, uint32_t textureOptions)
+{
+ if (!m_frontBuffer || !m_readyWithTexture)
+ return nullptr;
+
+#if defined(USE_OZONE)
+ Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kVulkan);
+
+ GrVkImageInfo vkImageInfo;
+ scoped_refptr<gfx::NativePixmap> nativePixmap = m_frontBuffer->nativePixmap();
+ if (!nativePixmap) {
+ if (m_isNativeBufferSupported) {
+ qWarning("VULKAN: No NativePixmap.");
+ return nullptr;
+ }
+
+ sk_sp<SkImage> skImage = m_frontBuffer->skImage();
+ if (!skImage) {
+ qWarning("VULKAN: No SkImage.");
+ return nullptr;
+ }
+
+ if (!skImage->isTextureBacked()) {
+ qWarning("VULKAN: SkImage is not backed by GPU texture.");
+ return nullptr;
+ }
+
+ GrBackendTexture backendTexture;
+ bool success = SkImages::GetBackendTextureFromImage(skImage, &backendTexture, false);
+ if (!success || !backendTexture.isValid()) {
+ qWarning("VULKAN: Failed to retrieve backend texture from SkImage.");
+ return nullptr;
+ }
+
+ if (backendTexture.backend() != GrBackendApi::kVulkan) {
+ qWarning("VULKAN: Backend texture is not a Vulkan texture.");
+ return nullptr;
+ }
+
+ backendTexture.getVkImageInfo(&vkImageInfo);
+ if (vkImageInfo.fAlloc.fMemory == VK_NULL_HANDLE) {
+ qWarning("VULKAN: Unable to access Vulkan memory.");
+ return nullptr;
+ }
+ }
+#elif defined(Q_OS_WIN)
+ Q_ASSERT(m_contextState->gr_context_type() == gpu::GrContextType::kGL);
+
+ absl::optional<gl::DCLayerOverlayImage> overlayImage = m_frontBuffer->overlayImage();
+ if (!overlayImage) {
+ qWarning("No overlay image.");
+ return nullptr;
+ }
+#endif
+
+ QSGRendererInterface *ri = win->rendererInterface();
+ VkDevice qtVulkanDevice =
+ *static_cast<VkDevice *>(ri->getResource(win, QSGRendererInterface::DeviceResource));
+ VkPhysicalDevice qtPhysicalDevice = *static_cast<VkPhysicalDevice *>(
+ ri->getResource(win, QSGRendererInterface::PhysicalDeviceResource));
+ QVulkanFunctions *f = win->vulkanInstance()->functions();
+ QVulkanDeviceFunctions *df = win->vulkanInstance()->deviceFunctions(qtVulkanDevice);
+
+ VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ VkPhysicalDeviceProperties deviceProperties;
+ f->vkGetPhysicalDeviceProperties(qtPhysicalDevice, &deviceProperties);
+ if (deviceProperties.vendorID == 0x10DE) {
+ // FIXME: This is a workaround for Nvidia driver.
+ // The imported image is empty if the initialLayout is not
+ // VK_IMAGE_LAYOUT_PREINITIALIZED.
+ imageLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ }
+
+ VkExternalMemoryImageCreateInfoKHR externalMemoryImageCreateInfo = {
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR
+ };
+#if defined(USE_OZONE)
+ VkSubresourceLayout planeLayout = {};
+ VkImageDrmFormatModifierExplicitCreateInfoEXT modifierInfo = {
+ VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT
+ };
+ base::ScopedFD scopedFd;
+
+ if (nativePixmap) {
+ gfx::NativePixmapHandle nativePixmapHandle = nativePixmap->ExportHandle();
+ if (nativePixmapHandle.planes.size() != 1)
+ qFatal("VULKAN: Multiple planes are not supported.");
+
+ planeLayout.offset = nativePixmapHandle.planes[0].offset;
+ planeLayout.size = 0;
+ planeLayout.rowPitch = nativePixmapHandle.planes[0].stride;
+ planeLayout.arrayPitch = 0;
+ planeLayout.depthPitch = 0;
+
+ modifierInfo.drmFormatModifier = nativePixmapHandle.modifier;
+ modifierInfo.drmFormatModifierPlaneCount = 1;
+ modifierInfo.pPlaneLayouts = &planeLayout;
+
+ externalMemoryImageCreateInfo.pNext = &modifierInfo;
+ externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+
+ scopedFd = std::move(nativePixmapHandle.planes[0].fd);
+ } else {
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ VkMemoryGetFdInfoKHR exportInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR };
+ exportInfo.pNext = nullptr;
+ exportInfo.memory = vkImageInfo.fAlloc.fMemory;
+ exportInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+ gpu::VulkanFunctionPointers *vfp = gpu::GetVulkanFunctionPointers();
+ gpu::VulkanDeviceQueue *vulkanDeviceQueue =
+ m_contextState->vk_context_provider()->GetDeviceQueue();
+ VkDevice vulkanDevice = vulkanDeviceQueue->GetVulkanDevice();
+
+ int fd = -1;
+ if (vfp->vkGetMemoryFdKHR(vulkanDevice, &exportInfo, &fd) != VK_SUCCESS)
+ qFatal("VULKAN: Unable to extract file descriptor out of external VkImage.");
+
+ scopedFd.reset(fd);
+ }
+
+ if (!scopedFd.is_valid())
+ qFatal("VULKAN: Unable to extract file descriptor.");
+#elif defined(Q_OS_WIN)
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+
+ HRESULT status = S_OK;
+ HANDLE sharedHandle = nullptr;
+ IDXGIResource1 *resource = nullptr;
+ if (!overlayImage->nv12_texture()) {
+ qWarning("VULKAN: No D3D texture.");
+ return nullptr;
+ }
+ status = overlayImage->nv12_texture()->QueryInterface(__uuidof(IDXGIResource1),
+ (void **)&resource);
+ Q_ASSERT(status == S_OK);
+ status = resource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &sharedHandle);
+ Q_ASSERT(status == S_OK);
+
+ if (!sharedHandle)
+ qFatal("VULKAN: Unable to extract shared handle.");
+#endif
+
+ constexpr VkImageUsageFlags kUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
+ | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+
+ VkImageCreateInfo importedImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
+ importedImageCreateInfo.pNext = &externalMemoryImageCreateInfo;
+ importedImageCreateInfo.flags = 0;
+ importedImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+ importedImageCreateInfo.format = gpu::ToVkFormat(m_frontBuffer->sharedImageFormat());
+ importedImageCreateInfo.extent.width = static_cast<uint32_t>(size().width());
+ importedImageCreateInfo.extent.height = static_cast<uint32_t>(size().height());
+ importedImageCreateInfo.extent.depth = 1;
+ importedImageCreateInfo.mipLevels = 1;
+ importedImageCreateInfo.arrayLayers = 1;
+ importedImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ importedImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ importedImageCreateInfo.usage = kUsage;
+ importedImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ importedImageCreateInfo.queueFamilyIndexCount = 0;
+ importedImageCreateInfo.pQueueFamilyIndices = nullptr;
+ importedImageCreateInfo.initialLayout = imageLayout;
+
+#if defined(USE_OZONE)
+ if (nativePixmap)
+ importedImageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+ else
+ importedImageCreateInfo.tiling = vkImageInfo.fImageTiling;
+#endif
+
+ VkResult result;
+ VkImage importedImage = VK_NULL_HANDLE;
+ result = df->vkCreateImage(qtVulkanDevice, &importedImageCreateInfo, nullptr /* pAllocator */,
+ &importedImage);
+ if (result != VK_SUCCESS)
+ qFatal() << "VULKAN: vkCreateImage failed result:" << result;
+
+#if defined(USE_OZONE)
+ VkImportMemoryFdInfoKHR importMemoryHandleInfo = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR
+ };
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+ importMemoryHandleInfo.fd = scopedFd.release();
+
+ if (nativePixmap)
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+#elif defined(Q_OS_WIN)
+ VkImportMemoryWin32HandleInfoKHR importMemoryHandleInfo = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR
+ };
+ importMemoryHandleInfo.pNext = nullptr;
+ importMemoryHandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
+ importMemoryHandleInfo.handle = sharedHandle;
+#endif
+
+ VkMemoryDedicatedAllocateInfoKHR dedicatedMemoryInfo = {
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR
+ };
+ dedicatedMemoryInfo.pNext = &importMemoryHandleInfo;
+ dedicatedMemoryInfo.image = importedImage;
+
+ VkMemoryAllocateInfo memoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
+ memoryAllocateInfo.pNext = &dedicatedMemoryInfo;
+
+ VkMemoryRequirements requirements;
+ df->vkGetImageMemoryRequirements(qtVulkanDevice, importedImage, &requirements);
+ if (!requirements.memoryTypeBits)
+ qFatal("VULKAN: vkGetImageMemoryRequirements failed.");
+
+ VkPhysicalDeviceMemoryProperties memoryProperties;
+ f->vkGetPhysicalDeviceMemoryProperties(qtPhysicalDevice, &memoryProperties);
+ constexpr VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ constexpr uint32_t kMaxIndex = 31;
+ uint32_t memoryTypeIndex = kMaxIndex + 1;
+ for (uint32_t i = 0; i <= kMaxIndex; i++) {
+ if (((1u << i) & requirements.memoryTypeBits) == 0)
+ continue;
+ if ((memoryProperties.memoryTypes[i].propertyFlags & flags) != flags)
+ continue;
+ memoryTypeIndex = i;
+ break;
+ }
+
+ if (memoryTypeIndex > kMaxIndex)
+ qFatal("VULKAN: Cannot find valid memory type index.");
+
+ memoryAllocateInfo.allocationSize = requirements.size;
+ memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
+
+ VkDeviceMemory importedImageMemory = VK_NULL_HANDLE;
+ result = df->vkAllocateMemory(qtVulkanDevice, &memoryAllocateInfo, nullptr /* pAllocator */,
+ &importedImageMemory);
+ if (result != VK_SUCCESS)
+ qFatal() << "VULKAN: vkAllocateMemory failed result:" << result;
+
+ df->vkBindImageMemory(qtVulkanDevice, importedImage, importedImageMemory, 0);
+
+ QQuickWindow::CreateTextureOptions texOpts(textureOptions);
+ QSGTexture *texture = QNativeInterface::QSGVulkanTexture::fromNative(importedImage, imageLayout,
+ win, size(), texOpts);
+
+ m_frontBuffer->textureCleanupCallback = [=]() {
+ df->vkDestroyImage(qtVulkanDevice, importedImage, nullptr);
+ df->vkFreeMemory(qtVulkanDevice, importedImageMemory, nullptr);
+#if defined(Q_OS_WIN)
+ ::CloseHandle(sharedHandle);
+#endif
+ };
+
+ return texture;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_vulkan.h b/src/core/compositor/native_skia_output_device_vulkan.h
new file mode 100644
index 000000000..bead0cc11
--- /dev/null
+++ b/src/core/compositor/native_skia_output_device_vulkan.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_SKIA_OUTPUT_DEVICE_VULKAN_H
+#define NATIVE_SKIA_OUTPUT_DEVICE_VULKAN_H
+
+#include "native_skia_output_device.h"
+
+namespace QtWebEngineCore {
+
+class NativeSkiaOutputDeviceVulkan final : public NativeSkiaOutputDevice
+{
+public:
+ NativeSkiaOutputDeviceVulkan(
+ scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
+ gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
+ gpu::SharedImageFactory *shared_image_factory,
+ gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
+ DidSwapBufferCompleteCallback didSwapBufferCompleteCallback);
+ ~NativeSkiaOutputDeviceVulkan() override;
+
+ // Overridden from Compositor:
+ QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_SKIA_OUTPUT_DEVICE_VULKAN_H
diff --git a/src/core/compositor/vulkan_implementation_qt.cpp b/src/core/compositor/vulkan_implementation_qt.cpp
new file mode 100644
index 000000000..2f2259666
--- /dev/null
+++ b/src/core/compositor/vulkan_implementation_qt.cpp
@@ -0,0 +1,162 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "vulkan_implementation_qt.h"
+
+#include "base/environment.h"
+#include "base/logging.h"
+#include "gpu/vulkan/vulkan_image.h"
+#include "gpu/vulkan/vulkan_surface.h"
+#include "gpu/vulkan/vulkan_util.h"
+#include "ui/gfx/gpu_fence.h"
+
+#include <vulkan/vulkan.h>
+
+namespace gpu {
+
+VulkanImplementationQt::VulkanImplementationQt() : VulkanImplementation(false) { }
+
+VulkanImplementationQt::~VulkanImplementationQt() = default;
+
+bool VulkanImplementationQt::InitializeVulkanInstance(bool /*using_surface*/)
+{
+ std::vector<const char *> required_extensions = {
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
+ };
+
+ auto env = base::Environment::Create();
+ std::string vulkan_path;
+ if (!env->GetVar("QT_VULKAN_LIB", &vulkan_path)) {
+#if BUILDFLAG(IS_WIN)
+ vulkan_path = "vulkan-1.dll";
+#else
+ vulkan_path = "libvulkan.so.1";
+#endif
+ }
+
+ if (!vulkan_instance_.Initialize(base::FilePath::FromUTF8Unsafe(vulkan_path),
+ required_extensions, {})) {
+ LOG(ERROR) << "Failed to initialize vulkan instance";
+ return false;
+ }
+
+ return true;
+}
+
+VulkanInstance *VulkanImplementationQt::GetVulkanInstance()
+{
+ return &vulkan_instance_;
+}
+
+std::unique_ptr<VulkanSurface>
+VulkanImplementationQt::CreateViewSurface(gfx::AcceleratedWidget /*window*/)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+bool VulkanImplementationQt::GetPhysicalDevicePresentationSupport(
+ VkPhysicalDevice /*device*/,
+ const std::vector<VkQueueFamilyProperties> & /*queue_family_properties*/,
+ uint32_t /*queue_family_index*/)
+{
+ NOTREACHED();
+ return true;
+}
+
+std::vector<const char *> VulkanImplementationQt::GetRequiredDeviceExtensions()
+{
+ return {
+ VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+#if BUILDFLAG(IS_WIN)
+ VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
+#else
+ VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
+#endif
+ };
+}
+
+std::vector<const char *> VulkanImplementationQt::GetOptionalDeviceExtensions()
+{
+ return {
+ VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
+#if BUILDFLAG(IS_WIN)
+ VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
+#else
+ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
+ VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME,
+ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
+ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
+#endif
+ };
+}
+
+VkFence VulkanImplementationQt::CreateVkFenceForGpuFence(VkDevice /*vk_device*/)
+{
+ NOTREACHED();
+ return VK_NULL_HANDLE;
+}
+
+std::unique_ptr<gfx::GpuFence>
+VulkanImplementationQt::ExportVkFenceToGpuFence(VkDevice /*vk_device*/, VkFence /*vk_fence*/)
+{
+ NOTREACHED();
+ return nullptr;
+}
+
+VkSemaphore VulkanImplementationQt::ImportSemaphoreHandle(VkDevice vk_device,
+ SemaphoreHandle sync_handle)
+{
+ return ImportVkSemaphoreHandle(vk_device, std::move(sync_handle));
+}
+
+VkExternalSemaphoreHandleTypeFlagBits VulkanImplementationQt::GetExternalSemaphoreHandleType()
+{
+#if BUILDFLAG(IS_WIN)
+ return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+#else
+ return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
+#endif
+}
+
+bool VulkanImplementationQt::CanImportGpuMemoryBuffer(
+ VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferType memory_buffer_type)
+{
+#if BUILDFLAG(IS_LINUX)
+ const auto &enabled_extensions = device_queue->enabled_extensions();
+ return gfx::HasExtension(enabled_extensions,
+ VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME) &&
+ gfx::HasExtension(enabled_extensions,
+ VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME) &&
+ memory_buffer_type == gfx::GpuMemoryBufferType::NATIVE_PIXMAP;
+#else
+ return false;
+#endif
+}
+
+std::unique_ptr<VulkanImage> VulkanImplementationQt::CreateImageFromGpuMemoryHandle(VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferHandle gmb_handle,
+ gfx::Size size,
+ VkFormat vk_format,
+ const gfx::ColorSpace &)
+{
+#if BUILDFLAG(IS_LINUX)
+ constexpr auto kUsage =
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ auto tiling = gmb_handle.native_pixmap_handle.modifier ==
+ gfx::NativePixmapHandle::kNoModifier
+ ? VK_IMAGE_TILING_OPTIMAL
+ : VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+ return gpu::VulkanImage::CreateFromGpuMemoryBufferHandle(
+ device_queue, std::move(gmb_handle), size, vk_format, kUsage, /*flags=*/0,
+ tiling, VK_QUEUE_FAMILY_EXTERNAL);
+#else
+ NOTIMPLEMENTED();
+ return nullptr;
+#endif
+}
+
+} // namespace gpu
diff --git a/src/core/compositor/vulkan_implementation_qt.h b/src/core/compositor/vulkan_implementation_qt.h
new file mode 100644
index 000000000..88983331f
--- /dev/null
+++ b/src/core/compositor/vulkan_implementation_qt.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef VULKAN_IMPLEMENTATION_QT_H
+#define VULKAN_IMPLEMENTATION_QT_H
+
+#include "gpu/vulkan/vulkan_implementation.h"
+#include "gpu/vulkan/vulkan_instance.h"
+
+namespace gpu {
+
+class VulkanImplementationQt : public VulkanImplementation
+{
+public:
+ VulkanImplementationQt();
+ ~VulkanImplementationQt() override;
+
+ // Overridden from VulkanImplementation.
+ bool InitializeVulkanInstance(bool using_surface) override;
+ VulkanInstance *GetVulkanInstance() override;
+ std::unique_ptr<VulkanSurface> CreateViewSurface(gfx::AcceleratedWidget window) override;
+ bool GetPhysicalDevicePresentationSupport(
+ VkPhysicalDevice device,
+ const std::vector<VkQueueFamilyProperties> &queue_family_properties,
+ uint32_t queue_family_index) override;
+ std::vector<const char *> GetRequiredDeviceExtensions() override;
+ std::vector<const char *> GetOptionalDeviceExtensions() override;
+ VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
+ std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(VkDevice vk_device,
+ VkFence vk_fence) override;
+ VkSemaphore ImportSemaphoreHandle(VkDevice vk_device, SemaphoreHandle handle) override;
+ VkExternalSemaphoreHandleTypeFlagBits GetExternalSemaphoreHandleType() override;
+ bool CanImportGpuMemoryBuffer(VulkanDeviceQueue* device_queue,
+ gfx::GpuMemoryBufferType memory_buffer_type) override;
+ std::unique_ptr<VulkanImage> CreateImageFromGpuMemoryHandle(VulkanDeviceQueue *device_queue,
+ gfx::GpuMemoryBufferHandle gmb_handle,
+ gfx::Size size, VkFormat vk_format,
+ const gfx::ColorSpace &color_space) override;
+
+private:
+ VulkanInstance vulkan_instance_;
+};
+
+} // namespace gpu
+
+#endif // VULKAN_IMPLEMENTATION_QT_H
diff --git a/src/core/configure.json b/src/core/configure.json
deleted file mode 100644
index 9e39ae59a..000000000
--- a/src/core/configure.json
+++ /dev/null
@@ -1,303 +0,0 @@
-{
- "module": "webenginecore",
- "depends": [
- "buildtools-private",
- "core-private",
- "gui-private",
- "printsupport"
- ],
- "condition": "module.gui && features.build-qtwebengine-core && features.webengine-core-support",
- "testDir": "../../config.tests",
- "commandline": {
- "options": {
- "webengine-alsa": "boolean",
- "webengine-embedded-build": "boolean",
- "webengine-full-debug-info": "boolean",
- "webengine-icu": { "type": "enum", "name": "webengine-system-icu", "values": { "system": "yes", "qt": "no" } },
- "webengine-ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
- "webengine-opus": { "type": "enum", "name": "webengine-system-opus", "values": { "system": "yes", "qt": "no" } },
- "webengine-webp": { "type": "enum", "name": "webengine-system-libwebp", "values": { "system": "yes", "qt": "no" } },
- "webengine-pepper-plugins": "boolean",
- "webengine-printing-and-pdf": "boolean",
- "webengine-proprietary-codecs": "boolean",
- "webengine-pulseaudio": "boolean",
- "webengine-spellchecker": "boolean",
- "webengine-native-spellchecker": "boolean",
- "webengine-extensions": "boolean",
- "webengine-webrtc": "boolean",
- "webengine-webrtc-pipewire": "boolean",
- "webengine-geolocation": "boolean",
- "webengine-webchannel": "boolean",
- "webengine-kerberos": "boolean",
- "alsa": { "type": "boolean", "name": "webengine-alsa" },
- "pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" },
- "ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
- "opus": { "type": "enum", "name": "webengine-system-opus", "values": { "system": "yes", "qt": "no" } },
- "webp": { "type": "enum", "name": "webengine-system-libwebp", "values": { "system": "yes", "qt": "no" } },
- "pepper-plugins": { "type": "boolean", "name": "webengine-pepper-plugins" },
- "printing-and-pdf": { "type": "boolean", "name": "webengine-printing-and-pdf" },
- "proprietary-codecs": { "type": "boolean", "name": "webengine-proprietary-codecs" },
- "spellchecker": { "type": "boolean", "name": "webengine-spellchecker" },
- "extensions": { "type": "boolean", "name": "webengine-extensions" },
- "webrtc": { "type": "boolean", "name": "webengine-webrtc" }
- }
- },
-
- "libraries": {
- "webengine-alsa": {
- "label": "alsa",
- "test": {
- "tail": [
- "#if SND_LIB_VERSION < 0x1000a // 1.0.10",
- "#error Alsa version found too old, require >= 1.0.10",
- "#endif"
- ]
- },
- "headers" : ["alsa/asoundlib.h"],
- "sources" : [{ "type": "pkgConfig", "args": "alsa" }
- ]
- },
- "webengine-poppler-cpp": {
- "label": "poppler-cpp",
- "sources": [
- { "type": "pkgConfig", "args": "poppler-cpp" }
- ]
- },
- "webengine-pulseaudio": {
- "label": "pulseaudio >= 0.9.10",
- "sources": [
- { "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" }
- ]
- },
- "webengine-gio": {
- "label": "gio",
- "sources": [
- { "type": "pkgConfig", "args": "gio-2.0" }
- ]
- }
- },
- "tests" : {
- "webengine-host-compiler": {
- "label": "host compiler",
- "test": "hostcompiler",
- "host": "true",
- "type": "compile"
- },
- "webengine-host-pkg-config": {
- "label": "host pkg-config",
- "type": "detectHostPkgConfig",
- "log": "path"
- },
- "webengine-embedded-build": {
- "label": "embedded build",
- "type": "detectEmbedded"
- }
- },
- "features": {
- "webengine-embedded-build": {
- "label": "Embedded build",
- "purpose": "Enables the embedded build configuration.",
- "condition": "config.unix",
- "autoDetect": "tests.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-alsa": {
- "label": "Use ALSA",
- "condition": "config.unix && libs.webengine-alsa",
- "output": [ "privateFeature" ]
- },
- "webengine-v8-snapshot-support": {
- "label" : "Building v8 snapshot supported",
- "condition": "!config.unix || !features.cross_compile || arch.arm64 || tests.webengine-host-compiler",
- "output": [ "privateFeature" ]
- },
- "webengine-geolocation": {
- "label": "Geolocation",
- "condition": "module.positioning",
- "output": [ "publicFeature" ]
- },
- "webengine-pulseaudio": {
- "label": "Use PulseAudio",
- "autoDetect": "config.unix",
- "condition": "libs.webengine-pulseaudio",
- "output": [ "privateFeature" ]
- },
- "webengine-pepper-plugins": {
- "label": "Pepper Plugins",
- "purpose": "Enables use of Pepper Flash plugins.",
- "autoDetect": "!features.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-printing-and-pdf": {
- "label": "Printing and PDF",
- "purpose": "Provides printing and output to PDF.",
- "condition": "module.printsupport && features.printer",
- "autoDetect": "!features.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-webchannel": {
- "label": "WebChannel support",
- "purpose": "Provides QtWebChannel integration.",
- "section": "WebEngine",
- "condition": "module.webchannel",
- "output": [ "publicFeature" ]
- },
- "webengine-proprietary-codecs": {
- "label": "Proprietary Codecs",
- "purpose": "Enables the use of proprietary codecs such as h.264/h.265 and MP3.",
- "autoDetect": false,
- "output": [ "privateFeature" ]
- },
- "webengine-kerberos": {
- "label": "Kerberos Authentication",
- "purpose": "Enables Kerberos Authentication Support",
- "autoDetect": "config.win32",
- "section": "WebEngine",
- "output": [ "privateFeature" ]
- },
- "webengine-spellchecker": {
- "label": "Spellchecker",
- "purpose": "Provides a spellchecker.",
- "output": [ "publicFeature" ]
- },
- "webengine-native-spellchecker": {
- "label": "Native Spellchecker",
- "purpose": "Use the system's native spellchecking engine.",
- "autoDetect": false,
- "condition": "config.macos && features.webengine-spellchecker",
- "output": [ "publicFeature" ]
- },
- "webengine-extensions": {
- "label": "Extensions",
- "purpose": "Enables Chromium extensions within certain limits. Currently used for enabling the pdf viewer.",
- "section": "WebEngine",
- "condition": "features.webengine-printing-and-pdf",
- "autoDetect": "features.webengine-printing-and-pdf",
- "output": [ "publicFeature" ]
- },
- "webengine-webrtc": {
- "label": "WebRTC",
- "purpose": "Provides WebRTC support.",
- "autoDetect": "!features.webengine-embedded-build",
- "output": [ "privateFeature" ]
- },
- "webengine-webrtc-pipewire": {
- "label": "PipeWire over GIO",
- "purpose": "Provides PipeWire support in WebRTC using GIO.",
- "condition": "features.webengine-webrtc && libs.webengine-gio",
- "autoDetect": "false",
- "output": [ "privateFeature" ]
- },
- "webengine-ozone" : {
- "label": "Support qpa-xcb",
- "condition": "features.webengine-ozone-x11",
- "output": [ "privateFeature" ]
- },
- "webengine-poppler-cpp": {
- "label": "poppler-cpp",
- "autoDetect": "config.unix",
- "condition": "libs.webengine-poppler-cpp",
- "output": [ "privateFeature" ]
- },
- "webengine-full-debug-info": {
- "label": "Full debug information",
- "purpose": "Enables debug information for Blink and V8.",
- "autoDetect": false,
- "condition": "config.debug || features.debug_and_release || features.force_debug_info",
- "output": [
- { "type": "privateConfig", "name": "v8base_debug" },
- { "type": "privateConfig", "name": "webcore_debug" }
- ]
- }
- },
-
- "report": [
- {
- "type": "warning",
- "condition": "config.unix && !features.webengine-host-pkg-config",
- "message": "host pkg-config not found"
- },
- {
- "type": "warning",
- "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb",
- "message": "Thumb instruction set is required to build ffmpeg for QtWebEngine."
- },
- {
- "type": "warning",
- "condition": "config.unix && config.cross_compile && !features.webengine-v8-snapshot-support",
- "message": "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed."
- }
- ],
-
- "summary": [
- {
- "section": "Qt WebEngineCore",
- "condition": "features.build-qtwebengine-core",
- "entries": [
- "webengine-embedded-build",
- "webengine-full-debug-info",
- "webengine-pepper-plugins",
- "webengine-printing-and-pdf",
- "webengine-proprietary-codecs",
- "webengine-spellchecker",
- "webengine-native-spellchecker",
- "webengine-webrtc",
- "webengine-webrtc-pipewire",
- "webengine-geolocation",
- "webengine-webchannel",
- "webengine-kerberos",
- "webengine-extensions",
- {
- "type": "feature",
- "args": "webengine-ozone",
- "condition": "config.unix"
- },
- {
- "type": "feature",
- "args": "webengine-v8-snapshot-support",
- "condition": "config.unix && config.cross_compile"
- },
- {
- "type": "feature",
- "args": "webengine-alsa",
- "condition": "config.unix"
- },
- {
- "type": "feature",
- "args": "webengine-pulseaudio",
- "condition": "config.unix"
- },
- {
- "message": "macOS version",
- "type": "macosToolchainVersion",
- "args": "macosVersion",
- "condition": "config.macos"
- },
- {
- "message": "Xcode version",
- "type": "macosToolchainVersion",
- "args": "xcodeVersion",
- "condition": "config.macos"
- },
- {
- "message": "Clang version",
- "type": "macosToolchainVersion",
- "args": "clangVersion",
- "condition": "config.macos"
- },
- {
- "message": "macOS SDK version",
- "type": "macosToolchainVersion",
- "args": "sdkVersion",
- "condition": "config.macos"
- },
- {
- "message": "macOS minimum deployment target",
- "type": "macosToolchainVersion",
- "args": "deploymentTarget",
- "condition": "config.macos"
- }
- ]
- }
- ]
-}
diff --git a/src/core/configure/BUILD.root.gn.in b/src/core/configure/BUILD.root.gn.in
index 2ba599e45..986db5026 100644
--- a/src/core/configure/BUILD.root.gn.in
+++ b/src/core/configure/BUILD.root.gn.in
@@ -11,6 +11,7 @@ import("//build/config/locales.gni")
import("//chrome/chrome_repack_locales.gni")
import("//extensions/buildflags/buildflags.gni")
import("//ui/ozone/ozone.gni")
+import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
# Workaround for cmake configure_file command. Words wrapped with @ characters are
# handled as variables in this file.
@@ -33,7 +34,7 @@ if (moc_source_h_files != []) {
script = "@WEBENGINE_ROOT_SOURCE_DIR@/tools/scripts/gn_run_binary.py"
sources = moc_source_h_files
outputs = [ "${target_gen_dir}/.moc/moc_{{source_name_part}}.cpp" ]
- inputs = [ "@WEBENGINE_ROOT_SOURCE_DIR@/CMakeLists.txt" ]
+ inputs = [ "@WEBENGINE_ROOT_SOURCE_DIR@/src/core/CMakeLists.txt" ]
args = [
@GN_ARGS_MOC_BIN@,
@GN_ARGS_DEFINES@,
@@ -78,20 +79,28 @@ config("QtWebEngineCore_config") {
]
}
-config("cpp17_config") {
- # static initialized constexpr expressions must be compiled always as c++14 or always as c++17
- # and our qtwebengine core sources use them as c++17
+declare_args() {
+ use_embedded_config = false
+ enable_webenginedriver = true
+}
+
+config("embedded_config") {
+ defines = [ "QTWEBENGINE_EMBEDDED_SWITCHES=1" ]
+}
+
+config("cpp20_config") {
+ # Chromium is built with C++20
if (is_win) {
- cflags_cc = [ "/std:c++17" ]
+ cflags_cc = [ "/std:c++20" ]
} else {
- cflags_cc = [ "-std=c++17" ]
+ cflags_cc = [ "-std=c++20" ]
}
}
shared_library("QtWebEngineCore") {
- rsp_types = [ "objects", "archives", "libs" ]
+ rsp_types = [ "objects", "archives", "libs", "ldir"]
configs += [
- ":cpp17_config",
+ ":cpp20_config",
":QtWebEngineCore_config",
"//build/config:precompiled_headers"
]
@@ -101,27 +110,40 @@ shared_library("QtWebEngineCore") {
"//third_party/boringssl/src/include",
"//third_party/skia/include/core"
]
- defines = [ "CHROMIUM_VERSION=\"" + chromium_version[0] + "\"" ]
+ data_deps = []
+ defines = [ "CHROMIUM_VERSION=" + chromium_version[0] ]
deps = [
"//base",
+ "//components/autofill/content/browser",
+ "//components/autofill/content/renderer",
+ "//components/autofill/core/browser",
+ "//components/autofill/core/browser:buildflags",
"//components/cdm/renderer",
+ "//components/embedder_support/origin_trials",
"//components/error_page/common",
"//components/favicon/content",
+ "//components/gcm_driver",
"//components/history/content/browser",
"//components/keyed_service/content",
+ "//components/lens:buildflags",
"//components/navigation_interception",
"//components/network_hints/browser",
"//components/network_hints/common:mojo_bindings",
"//components/network_hints/renderer",
+ "//components/signin/public/base",
"//components/visitedlink/browser",
"//components/visitedlink/renderer",
"//components/web_cache/browser",
"//components/web_cache/renderer",
"//components/spellcheck:buildflags",
+ "//components/supervised_user/core/common:buildflags",
+ "//components/profile_metrics",
"//components/proxy_config",
"//components/user_prefs",
"//content/public/app",
+ "//content/public/browser",
"//content",
+ "//gpu/ipc:gl_in_process_context",
"//media:media_buildflags",
"//net",
"//services/proxy_resolver:lib",
@@ -131,7 +153,6 @@ shared_library("QtWebEngineCore") {
"//ui/gl",
"//qtwebengine/browser:interfaces",
"//qtwebengine/userscript",
- "//qtwebengine/browser:service_manifests",
"//qtwebengine/common:mojo_bindings",
":qtwebengine_sources",
":qtwebengine_resources",
@@ -146,12 +167,16 @@ shared_library("QtWebEngineCore") {
deps += [ "//third_party/webrtc_overrides:webrtc_component" ]
}
- if (use_xscrnsaver) {
- deps += [ "//ui/base/x" ]
+ if (is_win) {
+ configs += [ "//build/config/compiler:rtti" ]
+ data_deps += [ ":QtWebEngineCoreSandbox" ]
+ }
+ if (use_embedded_config) {
+ configs += [ ":embedded_config" ]
}
- if (is_win) {
- data_deps = [ ":QtWebEngineCoreSandbox" ]
+ if (is_apple) {
+ configs -= [ "//build/config/compiler:enable_arc" ]
}
sources = [
@@ -169,6 +194,11 @@ shared_library("QtWebEngineCore") {
":generate_cpp_mocs",
]
}
+ if (use_v8_context_snapshot) {
+ data_deps += [
+ "//tools/v8_context_snapshot:v8_context_snapshot"
+ ]
+ }
}
source_set("qtwebengine_spellcheck_sources") {
@@ -185,10 +215,9 @@ source_set("qtwebengine_spellcheck_sources") {
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
"//chrome/browser/spellchecker/spellcheck_service.cc",
"//chrome/browser/spellchecker/spellcheck_service.h",
- "//components/language/core/browser/pref_names.cc",
- "//components/language/core/browser/pref_names.h",
]
deps = [
+ "//components/language/core/browser",
"//components/spellcheck/browser",
"//components/spellcheck/renderer",
"//third_party/blink/public:blink",
@@ -196,27 +225,63 @@ source_set("qtwebengine_spellcheck_sources") {
]
if (is_mac && use_browser_spellchecker) {
sources += [
- "//chrome/browser/spellchecker/spell_check_host_chrome_impl_mac.cc",
+ "//chrome/browser/spellchecker/spelling_request.cc",
]
}
}
+source_set("devtools_sources") {
+ configs += [ ":cpp20_config" ]
+ deps = [
+ "//components/zoom",
+ "//third_party/blink/public/mojom:mojom_platform",
+ ]
+ sources = [
+ "//chrome/browser/devtools/devtools_eye_dropper.cc",
+ "//chrome/browser/devtools/devtools_eye_dropper.h",
+ "//chrome/browser/devtools/devtools_file_helper.cc",
+ "//chrome/browser/devtools/devtools_file_helper.h",
+ "//chrome/browser/devtools/devtools_file_system_indexer.cc",
+ "//chrome/browser/devtools/devtools_file_system_indexer.h",
+ "//chrome/browser/devtools/devtools_file_watcher.cc",
+ "//chrome/browser/devtools/devtools_file_watcher.h",
+ "//chrome/browser/devtools/url_constants.cc",
+ "//chrome/browser/devtools/url_constants.h",
+ "//chrome/browser/devtools/devtools_ui_bindings.cc",
+ "//chrome/browser/devtools/devtools_ui_bindings.h",
+ "//chrome/browser/devtools/devtools_settings.cc",
+ "//chrome/browser/devtools/devtools_settings.h",
+ "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc",
+ "//chrome/browser/devtools/devtools_embedder_message_dispatcher.h",
+ ]
+}
+
source_set("qtwebengine_sources") {
configs += [
- ":cpp17_config",
+ ":cpp20_config",
"//skia:skia_config",
"//third_party/boringssl:external_config",
]
deps = [
+ ":devtools_sources",
"//build:branding_buildflags",
+ "//build/config/chromebox_for_meetings:buildflags",
"//chrome/browser:dev_ui_browser_resources_grit",
+ "//chrome/browser/resources/accessibility:resources",
"//chrome/browser/resources/net_internals:resources",
- "//chrome/browser/resources/quota_internals:resources",
+ "//chrome/browser/signin:identity_manager_provider",
"//chrome/common:buildflags",
+ "//chrome/common:version_header",
+ "//components/custom_handlers",
+ "//components/embedder_support:embedder_support",
"//components/nacl/common:buildflags",
"//components/performance_manager",
+ "//components/permissions:permissions_common",
"//components/plugins/renderer/",
+ "//content/browser/resources/quota:resources",
"//extensions/buildflags:buildflags",
+ "//pdf:buildflags",
+ "//printing/buildflags:buildflags",
"//qtwebengine/common:mojo_bindings",
"//rlz/buildflags:buildflags",
"//third_party/blink/public/mojom:mojom_platform",
@@ -224,19 +289,60 @@ source_set("qtwebengine_sources") {
sources = [
"//chrome/browser/accessibility/accessibility_ui.cc",
"//chrome/browser/accessibility/accessibility_ui.h",
- "//chrome/browser/custom_handlers/protocol_handler_registry.cc",
- "//chrome/browser/custom_handlers/protocol_handler_registry.h",
- "//chrome/browser/custom_handlers/protocol_handler_registry_factory.cc",
- "//chrome/browser/custom_handlers/protocol_handler_registry_factory.h",
- "//chrome/browser/devtools/devtools_eye_dropper.cc",
- "//chrome/browser/devtools/devtools_eye_dropper.h",
+ "//chrome/browser/gcm/gcm_product_util.cc",
+ "//chrome/browser/gcm/gcm_product_util.h",
+ "//chrome/browser/gcm/gcm_profile_service_factory.cc",
+ "//chrome/browser/gcm/gcm_profile_service_factory.h",
+ "//chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc",
+ "//chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h",
+ "//chrome/browser/media/webrtc/desktop_capturer_wrapper.cc",
+ "//chrome/browser/media/webrtc/desktop_capturer_wrapper.h",
+ "//chrome/browser/media/webrtc/desktop_media_list.cc",
"//chrome/browser/media/webrtc/desktop_media_list.h",
+ "//chrome/browser/media/webrtc/desktop_media_list_base.cc",
+ "//chrome/browser/media/webrtc/desktop_media_list_base.h",
+ "//chrome/browser/media/webrtc/native_desktop_media_list.cc",
+ "//chrome/browser/media/webrtc/native_desktop_media_list.h",
+ "//chrome/browser/media/webrtc/thumbnail_capturer.cc",
+ "//chrome/browser/media/webrtc/thumbnail_capturer.h",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
"//chrome/browser/prefs/chrome_command_line_pref_store.cc",
"//chrome/browser/prefs/chrome_command_line_pref_store.h",
+ "//chrome/browser/profiles/incognito_helpers.cc",
+ "//chrome/browser/profiles/incognito_helpers.h",
+ "//chrome/browser/profiles/profile_keyed_service_factory.cc",
+ "//chrome/browser/profiles/profile_keyed_service_factory.h",
+ "//chrome/browser/profiles/profile_selections.cc",
+ "//chrome/browser/profiles/profile_selections.h",
"//chrome/browser/profiles/profile.cc",
"//chrome/browser/profiles/profile.h",
+ "//chrome/browser/push_messaging/push_messaging_app_identifier.cc",
+ "//chrome/browser/push_messaging/push_messaging_app_identifier.h",
+ "//chrome/browser/push_messaging/push_messaging_constants.cc",
+ "//chrome/browser/push_messaging/push_messaging_constants.h",
+ "//chrome/browser/push_messaging/push_messaging_features.cc",
+ "//chrome/browser/push_messaging/push_messaging_features.h",
+ "//chrome/browser/push_messaging/push_messaging_notification_manager.cc",
+ "//chrome/browser/push_messaging/push_messaging_notification_manager.h",
+ "//chrome/browser/push_messaging/push_messaging_refresher.cc",
+ "//chrome/browser/push_messaging/push_messaging_refresher.h",
+ "//chrome/browser/push_messaging/push_messaging_service_factory.cc",
+ "//chrome/browser/push_messaging/push_messaging_service_factory.h",
+ "//chrome/browser/push_messaging/push_messaging_service_impl.cc",
+ "//chrome/browser/push_messaging/push_messaging_service_impl.h",
+ "//chrome/browser/push_messaging/push_messaging_utils.cc",
+ "//chrome/browser/push_messaging/push_messaging_utils.h",
+ "//chrome/browser/signin/chrome_signin_client.cc",
+ "//chrome/browser/signin/chrome_signin_client.h",
+ "//chrome/browser/signin/chrome_signin_client_factory.cc",
+ "//chrome/browser/signin/chrome_signin_client_factory.h",
+ "//chrome/browser/signin/force_signin_verifier.cc",
+ "//chrome/browser/signin/force_signin_verifier.h",
+ "//chrome/browser/signin/identity_manager_factory.cc",
+ "//chrome/browser/signin/identity_manager_factory.h",
+ "//chrome/browser/signin/signin_util.cc",
+ "//chrome/browser/signin/signin_util.h",
"//chrome/browser/tab_contents/form_interaction_tab_helper.cc",
"//chrome/browser/tab_contents/form_interaction_tab_helper.h",
"//chrome/browser/tab_contents/web_contents_collection.cc",
@@ -249,38 +355,50 @@ source_set("qtwebengine_sources") {
"//chrome/browser/ui/webui/devtools_ui_data_source.h",
"//chrome/browser/ui/webui/net_internals/net_internals_ui.cc",
"//chrome/browser/ui/webui/net_internals/net_internals_ui.h",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_handler.h",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_types.cc",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_types.h",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_ui.cc",
- "//chrome/browser/ui/webui/quota_internals/quota_internals_ui.h",
"//chrome/browser/ui/webui/user_actions/user_actions_ui.cc",
"//chrome/browser/ui/webui/user_actions/user_actions_ui.h",
"//chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc",
"//chrome/browser/ui/webui/user_actions/user_actions_ui_handler.h",
- "//chrome/common/custom_handlers/protocol_handler.cc",
- "//chrome/common/custom_handlers/protocol_handler.h",
"//chrome/browser/ui/webui/webui_util.cc",
"//chrome/browser/ui/webui/webui_util.h",
"//chrome/common/chrome_switches.cc",
"//chrome/common/chrome_switches.h",
- "//chrome/common/pref_names.cc",
"//chrome/common/pref_names.h",
"//chrome/common/url_constants.cc",
"//chrome/common/url_constants.h",
"//chrome/common/webui_url_constants.cc",
"//chrome/common/webui_url_constants.h",
+ "//components/embedder_support/user_agent_utils.cc",
+ "//components/embedder_support/user_agent_utils.h",
]
+ if (use_ozone) {
+ deps += [
+ "//ui/gfx/linux:drm",
+ ]
+
+ sources += [
+ "//ui/ozone/platform/wayland/gpu/wayland_gl_egl_utility.cc",
+ "//ui/ozone/platform/wayland/gpu/wayland_gl_egl_utility.h",
+ ]
+
+ if (ozone_platform_x11) {
+ deps += [
+ "//ui/base/x:gl",
+ "//ui/gfx/linux:gpu_memory_buffer_support_x11",
+ ]
+
+ sources += [
+ "//ui/ozone/platform/x11/gl_egl_utility_x11.cc",
+ "//ui/ozone/platform/x11/gl_egl_utility_x11.h",
+ ]
+ }
+ }
if (enable_extensions) {
deps += [
":qtwebengine_extensions_features",
"//chrome/app:generated_resources",
"//chrome/browser/extensions/api:api_registration",
"//chrome/browser/resources:component_extension_resources_grit",
- "//chrome/common/extensions/api",
"//chrome/common/extensions/api:api",
"//chrome/common/extensions/api:extensions_features",
"//components/crx_file",
@@ -292,7 +410,6 @@ source_set("qtwebengine_sources") {
"//extensions/common:core_api_provider",
"//extensions/browser",
"//extensions/browser/api",
- "//extensions/browser:core_api_provider",
"//extensions/renderer",
"//extensions:extensions_resources",
"//extensions/strings",
@@ -312,19 +429,30 @@ source_set("qtwebengine_sources") {
"//chrome/common/extensions/permissions/chrome_permission_message_rules.h",
]
} else {
- deps += [
- "//extensions/common:common_constants",
- ]
sources += [
"//extensions/common/url_pattern.cc",
"//extensions/common/url_pattern.h",
]
}
- if (is_linux) {
+ if (is_linux || is_win) {
sources += [
"//chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc",
"//chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h",
]
+ deps += [
+ "//chrome/browser/resources/sandbox_internals:resources",
+ ]
+ }
+ if (is_win) {
+ sources += [
+ "//chrome/browser/net/chrome_mojo_proxy_resolver_win.cc",
+ "//chrome/browser/net/chrome_mojo_proxy_resolver_win.h",
+ "//chrome/browser/ui/webui/sandbox/sandbox_handler.cc",
+ "//chrome/browser/ui/webui/sandbox/sandbox_handler.h",
+ ]
+ deps += [ "//services/proxy_resolver_win",
+ "//services/proxy_resolver_win/public/mojom",
+ ]
}
if (enable_spellcheck) {
deps += [
@@ -334,12 +462,10 @@ source_set("qtwebengine_sources") {
]
}
if (enable_plugins) {
- sources += [
- "//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
- "//chrome/renderer/pepper/pepper_flash_font_file_host.h",
- "//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
- "//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
- ]
+ sources += [
+ "//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
+ "//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
+ ]
}
if (enable_basic_printing || enable_print_preview) {
sources += [
@@ -352,26 +478,23 @@ source_set("qtwebengine_sources") {
"//chrome/browser/printing/print_job_worker.cc",
"//chrome/browser/printing/print_job_worker.h",
]
- deps += [
- "//printing/buildflags:buildflags",
- ]
}
if (enable_pdf) {
- deps += [
- "//pdf",
- "//pdf:buildflags",
- "//pdf:pdf_ppapi",
- "//chrome/browser/resources/pdf:resources",
- "//components/pdf/browser:browser",
- "//components/pdf/renderer:renderer",
- "//components/printing/browser",
- "//components/printing/renderer",
- ]
+ deps += [
+ "//pdf",
+ "//chrome/browser/resources/pdf:resources",
+ "//components/pdf/browser",
+ "//components/pdf/browser:interceptors",
+ "//components/pdf/common",
+ "//components/pdf/renderer",
+ "//components/printing/browser",
+ "//components/printing/renderer",
+ ]
}
if (enable_webrtc && enable_extensions) {
deps += [
- "//chrome/browser/resources/media:webrtc_logs_resources",
+ "//chrome/browser/resources/media:resources",
"//components/upload_list",
"//components/webrtc_logging/browser",
"//components/webrtc_logging/common",
@@ -417,7 +540,7 @@ source_set("qtwebengine_sources") {
if (is_win) {
static_library("QtWebEngineCoreSandbox") {
complete_static_lib = true
- configs += [ ":cpp17_config",
+ configs += [ ":cpp20_config",
":QtWebEngineCore_config",
"//build/config:precompiled_headers"
]
@@ -447,40 +570,52 @@ group("qtwebengine_resources") {
repack("qtwebengine_repack_resources") {
sources = [
"$root_gen_dir/qtwebengine/qt_webengine_resources.pak",
+ "$root_gen_dir/chrome/accessibility_resources.pak",
"$root_gen_dir/chrome/common_resources.pak",
"$root_gen_dir/chrome/dev_ui_browser_resources.pak",
"$root_gen_dir/chrome/net_internals_resources.pak",
- "$root_gen_dir/chrome/quota_internals_resources.pak",
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/components/dev_ui_components_resources.pak",
+ "$root_gen_dir/content/attribution_internals_resources.pak",
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/content_resources.pak",
- "$root_gen_dir/content/dev_ui_content_resources.pak",
+ "$root_gen_dir/content/gpu_resources.pak",
+ "$root_gen_dir/content/histograms_resources.pak",
+ "$root_gen_dir/content/indexed_db_resources.pak",
+ "$root_gen_dir/content/network_errors_resources.pak",
+ "$root_gen_dir/content/process_resources.pak",
+ "$root_gen_dir/content/quota_internals_resources.pak",
+ "$root_gen_dir/content/service_worker_resources.pak",
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/net/net_resources.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
"$root_gen_dir/ui/resources/webui_resources.pak",
- "$root_gen_dir/ui/resources/webui_generated_resources.pak",
]
output = "$root_out_dir/qtwebengine_resources.pak"
deps = [
"//qtwebengine/browser:qt_webengine_resources",
"//chrome/browser:dev_ui_browser_resources_grit",
+ "//chrome/browser/resources/accessibility:resources",
"//chrome/browser/resources/net_internals:resources",
- "//chrome/browser/resources/quota_internals:resources",
"//chrome/common:resources_grit",
"//components/resources:components_resources_grit",
"//components/resources:dev_ui_components_resources_grit",
+ "//content/browser/resources/attribution_reporting:resources",
+ "//content/browser/resources/gpu:resources",
+ "//content/browser/resources/histograms:resources_grit",
+ "//content/browser/resources/indexed_db:resources",
"//content/browser/resources/media:resources",
+ "//content/browser/resources/net:resources",
+ "//content/browser/resources/process:resources",
+ "//content/browser/resources/quota:resources",
+ "//content/browser/resources/service_worker:resources",
"//content/browser/tracing:resources",
- "//content:content_resources_grit",
- "//content:dev_ui_content_resources_grit",
+ "//content:content_resources",
"//mojo/public/js:resources",
"//net:net_resources_grit",
"//third_party/blink/public:resources_grit",
- "//ui/resources:webui_resources_grd_grit",
- "//ui/resources:webui_generated_resources_grd",
+ "//ui/resources:webui_resources_grd",
]
if (enable_extensions) {
sources += [
@@ -504,10 +639,10 @@ repack("qtwebengine_repack_resources") {
}
if (enable_webrtc && enable_extensions) {
sources += [
- "$root_gen_dir/chrome/webrtc_logs_resources.pak",
+ "$root_gen_dir/chrome/media_resources.pak",
]
deps += [
- "//chrome/browser/resources/media:webrtc_logs_resources",
+ "//chrome/browser/resources/media:resources",
]
}
if (enable_pdf) {
@@ -518,13 +653,20 @@ repack("qtwebengine_repack_resources") {
"//chrome/browser/resources/pdf:resources",
]
}
+ if (is_linux || is_win) {
+ sources += [
+ "$root_gen_dir/chrome/sandbox_internals_resources.pak",
+ ]
+ deps += [
+ "//chrome/browser/resources/sandbox_internals:resources_grit",
+ ]
+ }
}
repack("qtwebengine_repack_resources_100") {
sources = [
"$root_gen_dir/chrome/renderer_resources_100_percent.pak",
"$root_gen_dir/components/components_resources_100_percent.pak",
- "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
"$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
]
@@ -532,7 +674,6 @@ repack("qtwebengine_repack_resources_100") {
deps = [
"//chrome/renderer:resources_grit",
"//components/resources:components_scaled_resources_grit",
- "//content/app/resources:resources_grit",
"//third_party/blink/public:scaled_resources_100_percent",
"//ui/resources:ui_resources_grd_grit"
]
@@ -550,7 +691,6 @@ repack("qtwebengine_repack_resources_200") {
sources = [
"$root_gen_dir/chrome/renderer_resources_200_percent.pak",
"$root_gen_dir/components/components_resources_200_percent.pak",
- "$root_gen_dir/content/app/resources/content_resources_200_percent.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_200_percent.pak",
"$root_gen_dir/ui/resources/ui_resources_200_percent.pak",
]
@@ -558,7 +698,6 @@ repack("qtwebengine_repack_resources_200") {
deps = [
"//chrome/renderer:resources_grit",
"//components/resources:components_scaled_resources_grit",
- "//content/app/resources:resources_grit",
"//third_party/blink/public:scaled_resources_200_percent",
"//ui/resources:ui_resources_grd_grit"
]
@@ -575,17 +714,19 @@ repack("qtwebengine_repack_resources_200") {
repack("qtwebengine_repack_resources_devtools") {
sources = [
"$root_gen_dir/content/browser/devtools/devtools_resources.pak",
+ "$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
]
output = "$root_out_dir/qtwebengine_devtools_resources.pak"
deps = [
"//content/browser/devtools:devtools_resources_grit",
+ "//third_party/blink/public:devtools_inspector_resources_grit",
]
}
chrome_repack_locales("qtwebengine_repack_locales_pack") {
- input_locales = locales
+ input_locales = platform_pak_locales
output_dir = "$root_out_dir/qtwebengine_locales"
- output_locales = locales
+ output_locales = platform_pak_locales
}
if (enable_extensions) {
@@ -617,7 +758,7 @@ if (enable_extensions) {
if (enable_spellcheck) {
shared_library("convert_dict") {
- rsp_types = [ "objects", "archives", "libs" ]
+ rsp_types = [ "objects", "archives", "libs", "ldir" ]
configs += [ "//build/config/compiler:wexit_time_destructors" ]
deps = [
"//chrome/tools/convert_dict:lib",
@@ -627,3 +768,12 @@ if (enable_spellcheck) {
]
}
}
+
+if (enable_webenginedriver) {
+ group("webenginedriver_group") {
+ testonly = true
+ deps = [
+ "//chrome/test/chromedriver:chromedriver_server",
+ ]
+ }
+}
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index f8d1afe10..53c2caa2d 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -1,55 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "content_browser_client_qt.h"
#include "base/files/file_util.h"
-#include "base/optional.h"
-#include "base/task/post_task.h"
-#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
-#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
+#include "components/autofill/content/browser/content_autofill_driver_factory.h"
+#include "components/custom_handlers/protocol_handler_registry.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h"
#include "components/navigation_interception/intercept_navigation_throttle.h"
-#include "components/navigation_interception/navigation_params.h"
#include "components/network_hints/browser/simple_network_hints_handler_impl.h"
+#include "components/performance_manager/embedder/performance_manager_lifetime.h"
#include "components/performance_manager/embedder/performance_manager_registry.h"
#include "components/performance_manager/public/performance_manager.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -59,37 +22,47 @@
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/file_url_loader.h"
#include "content/public/browser/media_observer.h"
+#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
+#include "content/public/browser/url_loader_request_interceptor.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
+#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
+#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
+#include "pdf/buildflags.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_store.h"
+#include "net/ssl/ssl_private_key.h"
+#include "printing/buildflags/buildflags.h"
+#include "services/device/public/cpp/geolocation/geolocation_manager.h"
#include "services/network/network_service.h"
+#include "services/network/public/cpp/web_sandbox_flags.h"
+#include "services/network/public/mojom/websocket.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
-#include "third_party/blink/public/mojom/insecure_input/insecure_input_service.mojom.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
#include "url/url_util_qt.h"
#include "qtwebengine/common/renderer_configuration.mojom.h"
-#include "qtwebengine/grit/qt_webengine_resources.h"
#include "profile_adapter.h"
#include "browser_main_parts_qt.h"
#include "browser_message_filter_qt.h"
#include "certificate_error_controller.h"
#include "client_cert_select_controller.h"
+#include "custom_handlers/protocol_handler_registry_factory.h"
#include "devtools_manager_delegate_qt.h"
+#include "file_system_access/file_system_access_permission_request_manager_qt.h"
#include "login_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
#include "net/cookie_monster_delegate_qt.h"
@@ -97,11 +70,9 @@
#include "net/proxying_restricted_cookie_manager_qt.h"
#include "net/proxying_url_loader_factory_qt.h"
#include "net/system_network_context_manager.h"
-#include "ozone/gl_share_context_qt.h"
#include "platform_notification_service_qt.h"
#include "profile_qt.h"
#include "profile_io_data_qt.h"
-#include "quota_permission_context_qt.h"
#include "renderer_host/user_resource_controller_host.h"
#include "select_file_dialog_factory_qt.h"
#include "type_conversion.h"
@@ -112,28 +83,23 @@
#include "web_engine_context.h"
#include "web_engine_library_info.h"
#include "web_engine_settings.h"
+#include "authenticator_request_client_delegate_qt.h"
#include "api/qwebenginecookiestore.h"
#include "api/qwebenginecookiestore_p.h"
-
-#if QT_CONFIG(opengl)
-#include <QOpenGLContext>
-#include <QOpenGLExtraFunctions>
-#endif
+#include "api/qwebengineurlrequestinfo_p.h"
#if QT_CONFIG(webengine_geolocation)
#include "base/memory/ptr_util.h"
#include "location_provider_qt.h"
#endif
-#if QT_CONFIG(webengine_pepper_plugins)
-#include "content/public/browser/browser_ppapi_host.h"
-#include "ppapi/host/ppapi_host.h"
-#include "renderer_host/pepper/pepper_host_factory_qt.h"
-#endif
-
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
+#include "chrome/browser/spellchecker/spellcheck_factory.h"
+#include "chrome/browser/spellchecker/spellcheck_service.h"
+#include "components/spellcheck/browser/pref_names.h"
#include "components/spellcheck/common/spellcheck.mojom.h"
+#include "components/spellcheck/common/spellcheck_features.h"
#endif
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
@@ -147,31 +113,50 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
#include "components/guest_view/browser/guest_view_base.h"
+#include "extensions/browser/api/messaging/messaging_api_message_filter.h"
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
+#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_message_filter.h"
#include "extensions/browser/extension_protocols.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
-#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
+#include "extensions/browser/guest_view/extensions_guest_view.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/browser/process_map.h"
#include "extensions/browser/url_loader_factory_manager.h"
+#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h"
#include "extensions/common/manifest_handlers/mime_types_handler.h"
#include "extensions/extension_web_contents_observer_qt.h"
#include "extensions/extensions_browser_client_qt.h"
-#include "extensions/pdf_iframe_navigation_throttle_qt.h"
#include "net/plugin_response_interceptor_url_loader_throttle.h"
#endif
+#if QT_CONFIG(webengine_webchannel)
+#include "qtwebengine/browser/qtwebchannel.mojom.h"
+#include "renderer_host/web_channel_ipc_transport_host.h"
+#endif
+
+#if BUILDFLAG(ENABLE_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW)
+#include "printing/pdf_stream_delegate_qt.h"
+#include "printing/print_view_manager_qt.h"
+#endif
+
+#if BUILDFLAG(ENABLE_PDF)
+#include "components/pdf/browser/pdf_navigation_throttle.h"
+#include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
+#include "components/pdf/browser/pdf_document_helper.h"
+
+#include "printing/pdf_document_helper_client_qt.h"
+#endif
+
+#if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/pdf_iframe_navigation_throttle_qt.h"
+#endif
+
#include <QGuiApplication>
#include <QStandardPaths>
-#include <qpa/qplatformnativeinterface.h>
-
-QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
-QT_END_NAMESPACE
// Implement IsHandledProtocol as declared in //url/url_util_qt.h.
namespace url {
@@ -192,9 +177,6 @@ bool IsHandledProtocol(base::StringPiece scheme)
content::kChromeUIScheme,
url::kDataScheme,
url::kAboutScheme,
-#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
- url::kFtpScheme,
-#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
url::kBlobScheme,
url::kFileSystemScheme,
url::kQrcScheme,
@@ -227,9 +209,12 @@ ContentBrowserClientQt::~ContentBrowserClientQt()
{
}
-std::unique_ptr<content::BrowserMainParts> ContentBrowserClientQt::CreateBrowserMainParts(const content::MainFunctionParams&)
+std::unique_ptr<content::BrowserMainParts> ContentBrowserClientQt::CreateBrowserMainParts(bool)
{
- return std::make_unique<BrowserMainPartsQt>();
+ Q_ASSERT(!m_browserMainParts);
+ auto browserMainParts = std::make_unique<BrowserMainPartsQt>();
+ m_browserMainParts = browserMainParts.get();
+ return browserMainParts;
}
void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost *host)
@@ -237,6 +222,11 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
const int id = host->GetID();
Profile *profile = Profile::FromBrowserContext(host->GetBrowserContext());
+#if QT_CONFIG(webengine_spellchecker)
+ if (spellcheck::UseBrowserSpellChecker() && !profile->GetPrefs()->GetBoolean(spellcheck::prefs::kSpellCheckEnable))
+ SpellcheckServiceFactory::GetForContext(profile)->InitForRenderer(host);
+#endif
+
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
WebRtcLoggingController::AttachToRenderProcessHost(host, WebEngineContext::current()->webRtcLogUploader());
#endif
@@ -253,7 +243,7 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
host->AddFilter(new BrowserMessageFilterQt(id, profile));
#if BUILDFLAG(ENABLE_EXTENSIONS)
host->AddFilter(new extensions::ExtensionMessageFilter(id, profile));
- host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(id, profile));
+ host->AddFilter(new extensions::MessagingAPIMessageFilter(id, profile));
#endif //ENABLE_EXTENSIONS
bool is_incognito_process = profile->IsOffTheRecord();
@@ -262,13 +252,6 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost
renderer_configuration->SetInitialConfiguration(is_incognito_process);
}
-gl::GLShareGroup *ContentBrowserClientQt::GetInProcessGpuShareGroup()
-{
- if (!m_shareGroupQt.get())
- m_shareGroupQt = new ShareGroupQt;
- return m_shareGroupQt.get();
-}
-
content::MediaObserver *ContentBrowserClientQt::GetMediaObserver()
{
return MediaCaptureDevicesDispatcher::GetInstance();
@@ -289,11 +272,6 @@ void ContentBrowserClientQt::OverrideWebkitPrefs(content::WebContents *webConten
delegate->overrideWebPreferences(webContents, web_prefs);
}
-scoped_refptr<content::QuotaPermissionContext> ContentBrowserClientQt::CreateQuotaPermissionContext()
-{
- return new QuotaPermissionContextQt;
-}
-
void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webContents,
int cert_error,
const net::SSLInfo &ssl_info,
@@ -310,13 +288,15 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont
}
-base::OnceClosure ContentBrowserClientQt::SelectClientCertificate(content::WebContents *webContents,
+base::OnceClosure ContentBrowserClientQt::SelectClientCertificate(content::BrowserContext *browser_context,
+ content::WebContents *webContents,
net::SSLCertRequestInfo *certRequestInfo,
net::ClientCertIdentityList clientCerts,
std::unique_ptr<content::ClientCertificateDelegate> delegate)
{
+ Q_UNUSED(browser_context);
if (!clientCerts.empty()) {
- WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
QSharedPointer<ClientCertSelectController> certSelectController(
new ClientCertSelectController(certRequestInfo, std::move(clientCerts), std::move(delegate)));
@@ -401,73 +381,11 @@ void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base:
}
#endif
-#if QT_CONFIG(webengine_pepper_plugins)
-void ContentBrowserClientQt::DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host)
-{
- browser_host->GetPpapiHost()->AddHostFactoryFilter(
- std::make_unique<QtWebEngineCore::PepperHostFactoryQt>(browser_host));
-}
-#endif
-
-content::DevToolsManagerDelegate* ContentBrowserClientQt::GetDevToolsManagerDelegate()
+std::unique_ptr<content::DevToolsManagerDelegate> ContentBrowserClientQt::CreateDevToolsManagerDelegate()
{
- return new DevToolsManagerDelegateQt;
+ return std::make_unique<DevToolsManagerDelegateQt>();
}
-content::PlatformNotificationService *ContentBrowserClientQt::GetPlatformNotificationService(content::BrowserContext *browser_context)
-{
- ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
- if (!profile)
- return nullptr;
- return profile->platformNotificationService();
-}
-
-// This is a really complicated way of doing absolutely nothing, but Mojo demands it:
-class ServiceDriver
- : public blink::mojom::InsecureInputService
- , public content::WebContentsUserData<ServiceDriver>
-{
-public:
- static void CreateForRenderFrameHost(content::RenderFrameHost *renderFrameHost)
- {
- content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(renderFrameHost);
- if (!web_contents)
- return;
- CreateForWebContents(web_contents);
- }
- static ServiceDriver* FromRenderFrameHost(content::RenderFrameHost *renderFrameHost)
- {
- content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(renderFrameHost);
- if (!web_contents)
- return nullptr;
- return FromWebContents(web_contents);
- }
- static void BindInsecureInputService(content::RenderFrameHost *render_frame_host, mojo::PendingReceiver<blink::mojom::InsecureInputService> receiver)
- {
- CreateForRenderFrameHost(render_frame_host);
- ServiceDriver *driver = FromRenderFrameHost(render_frame_host);
-
- if (driver)
- driver->BindInsecureInputServiceReceiver(std::move(receiver));
- }
- void BindInsecureInputServiceReceiver(mojo::PendingReceiver<blink::mojom::InsecureInputService> receiver)
- {
- m_receivers.Add(this, std::move(receiver));
- }
-
- // blink::mojom::InsecureInputService:
- void DidEditFieldInInsecureContext() override
- { }
-
-private:
- WEB_CONTENTS_USER_DATA_KEY_DECL();
- explicit ServiceDriver(content::WebContents* /*web_contents*/) { }
- friend class content::WebContentsUserData<ServiceDriver>;
- mojo::ReceiverSet<blink::mojom::InsecureInputService> m_receivers;
-};
-
-WEB_CONTENTS_USER_DATA_KEY_IMPL(ServiceDriver)
-
void ContentBrowserClientQt::BindHostReceiverForRenderer(content::RenderProcessHost *render_process_host,
mojo::GenericPendingReceiver receiver)
{
@@ -515,8 +433,6 @@ void ContentBrowserClientQt::RegisterBrowserInterfaceBindersForFrame(
content::RenderFrameHost *render_frame_host,
mojo::BinderMapWithContext<content::RenderFrameHost *> *map)
{
- Q_UNUSED(render_frame_host);
- map->Add<blink::mojom::InsecureInputService>(base::BindRepeating(&ServiceDriver::BindInsecureInputService));
map->Add<network_hints::mojom::NetworkHintsHandler>(base::BindRepeating(&BindNetworkHintsHandler));
#if BUILDFLAG(ENABLE_EXTENSIONS)
map->Add<extensions::mime_handler::MimeHandlerService>(base::BindRepeating(&BindMimeHandlerService));
@@ -533,6 +449,8 @@ void ContentBrowserClientQt::RegisterBrowserInterfaceBindersForFrame(
extensions::ExtensionsBrowserClient::Get()->RegisterBrowserInterfaceBindersForFrame(map,
render_frame_host,
extension);
+#else
+ Q_UNUSED(render_frame_host);
#endif
}
@@ -540,9 +458,65 @@ void ContentBrowserClientQt::ExposeInterfacesToRenderer(service_manager::BinderR
blink::AssociatedInterfaceRegistry *associated_registry,
content::RenderProcessHost *render_process_host)
{
- Q_UNUSED(associated_registry);
if (auto *manager = performance_manager::PerformanceManagerRegistry::GetInstance())
manager->CreateProcessNodeAndExposeInterfacesToRendererProcess(registry, render_process_host);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ associated_registry->AddInterface<extensions::mojom::EventRouter>(
+ base::BindRepeating(&extensions::EventRouter::BindForRenderer, render_process_host->GetID()));
+ associated_registry->AddInterface<guest_view::mojom::GuestViewHost>(
+ base::BindRepeating(&extensions::ExtensionsGuestView::CreateForComponents, render_process_host->GetID()));
+ associated_registry->AddInterface<extensions::mojom::GuestView>(
+ base::BindRepeating(&extensions::ExtensionsGuestView::CreateForExtensions, render_process_host->GetID()));
+#else
+ Q_UNUSED(associated_registry);
+#endif
+}
+
+void ContentBrowserClientQt::RegisterAssociatedInterfaceBindersForRenderFrameHost(
+ content::RenderFrameHost &rfh,
+ blink::AssociatedInterfaceRegistry &associated_registry)
+{
+#if QT_CONFIG(webengine_webchannel)
+ associated_registry.AddInterface<qtwebchannel::mojom::WebChannelTransportHost>(
+ base::BindRepeating(
+ [](content::RenderFrameHost *render_frame_host,
+ mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportHost> receiver) {
+ auto *web_contents = content::WebContents::FromRenderFrameHost(render_frame_host);
+ auto *adapter = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())->webContentsAdapter();
+ adapter->webChannelTransport()->BindReceiver(std::move(receiver), render_frame_host);
+ }, &rfh));
+#endif
+#if BUILDFLAG(ENABLE_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW)
+ associated_registry.AddInterface<printing::mojom::PrintManagerHost>(
+ base::BindRepeating(
+ [](content::RenderFrameHost* render_frame_host,
+ mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost> receiver) {
+ PrintViewManagerQt::BindPrintManagerHost(std::move(receiver), render_frame_host);
+ }, &rfh));
+#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ associated_registry.AddInterface<extensions::mojom::LocalFrameHost>(
+ base::BindRepeating(
+ [](content::RenderFrameHost *render_frame_host,
+ mojo::PendingAssociatedReceiver<extensions::mojom::LocalFrameHost> receiver) {
+ extensions::ExtensionWebContentsObserverQt::BindLocalFrameHost(std::move(receiver), render_frame_host);
+ }, &rfh));
+#endif
+ associated_registry.AddInterface<autofill::mojom::AutofillDriver>(
+ base::BindRepeating(
+ [](content::RenderFrameHost *render_frame_host,
+ mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver> receiver) {
+ autofill::ContentAutofillDriverFactory::BindAutofillDriver(std::move(receiver), render_frame_host);
+ }, &rfh));
+#if BUILDFLAG(ENABLE_PDF)
+ associated_registry.AddInterface<pdf::mojom::PdfService>(
+ base::BindRepeating(
+ [](content::RenderFrameHost *render_frame_host,
+ mojo::PendingAssociatedReceiver<pdf::mojom::PdfService> receiver) {
+ pdf::PDFDocumentHelper::BindPdfService(std::move(receiver), render_frame_host, std::make_unique<PDFDocumentHelperClientQt>());
+ }, &rfh));
+#endif // BUILDFLAG(ENABLE_PDF)
+ ContentBrowserClient::RegisterAssociatedInterfaceBindersForRenderFrameHost(rfh, associated_registry);
}
bool ContentBrowserClientQt::CanCreateWindow(
@@ -594,6 +568,15 @@ std::unique_ptr<device::LocationProvider> ContentBrowserClientQt::OverrideSystem
}
#endif
+device::GeolocationManager *ContentBrowserClientQt::GetGeolocationManager()
+{
+#if BUILDFLAG(IS_MAC)
+ return m_browserMainParts->GetGeolocationManager();
+#else
+ return nullptr;
+#endif
+}
+
bool ContentBrowserClientQt::ShouldEnableStrictSiteIsolation()
{
// mirroring AwContentBrowserClient, CastContentBrowserClient and
@@ -605,9 +588,9 @@ bool ContentBrowserClientQt::WillCreateRestrictedCookieManager(network::mojom::R
content::BrowserContext *browser_context,
const url::Origin & /*origin*/,
const net::IsolationInfo & /*isolation_info*/,
- bool is_service_worker,
- int process_id,
- int routing_id,
+ bool /*is_service_worker*/,
+ int /*process_id*/,
+ int /*routing_id*/,
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> *receiver)
{
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> orig_receiver = std::move(*receiver);
@@ -618,27 +601,15 @@ bool ContentBrowserClientQt::WillCreateRestrictedCookieManager(network::mojom::R
ProxyingRestrictedCookieManagerQt::CreateAndBind(
ProfileIODataQt::FromBrowserContext(browser_context),
std::move(target_rcm_remote),
- is_service_worker, process_id, routing_id,
std::move(orig_receiver));
return false; // only made a proxy, still need the actual impl to be made.
}
-bool ContentBrowserClientQt::AllowAppCache(const GURL &manifest_url,
- const GURL &first_party,
- const base::Optional<url::Origin> &top_frame_origin,
- content::BrowserContext *context)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (!context || context->ShutdownStarted())
- return false;
- return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(first_party), toQt(manifest_url));
-}
-
content::AllowServiceWorkerResult
ContentBrowserClientQt::AllowServiceWorker(const GURL &scope,
- const GURL &site_for_cookies,
- const base::Optional<url::Origin> & /*top_frame_origin*/,
+ const net::SiteForCookies &site_for_cookies,
+ const absl::optional<url::Origin> & /*top_frame_origin*/,
const GURL & /*script_url*/,
content::BrowserContext *context)
{
@@ -647,7 +618,7 @@ ContentBrowserClientQt::AllowServiceWorker(const GURL &scope,
return content::AllowServiceWorkerResult::No();
// FIXME: Chrome also checks if javascript is enabled here to check if has been disabled since the service worker
// was started.
- return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(site_for_cookies), toQt(scope))
+ return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(site_for_cookies.first_party_url()), toQt(scope))
? content::AllowServiceWorkerResult::Yes()
: content::AllowServiceWorkerResult::No();
}
@@ -655,7 +626,7 @@ ContentBrowserClientQt::AllowServiceWorker(const GURL &scope,
// We control worker access to FS and indexed-db using cookie permissions, this is mirroring Chromium's logic.
void ContentBrowserClientQt::AllowWorkerFileSystem(const GURL &url,
content::BrowserContext *context,
- const std::vector<content::GlobalFrameRoutingId> &/*render_frames*/,
+ const std::vector<content::GlobalRenderFrameHostId> &/*render_frames*/,
base::OnceCallback<void(bool)> callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -668,7 +639,7 @@ void ContentBrowserClientQt::AllowWorkerFileSystem(const GURL &url,
bool ContentBrowserClientQt::AllowWorkerIndexedDB(const GURL &url,
content::BrowserContext *context,
- const std::vector<content::GlobalFrameRoutingId> &/*render_frames*/)
+ const std::vector<content::GlobalRenderFrameHostId> &/*render_frames*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!context || context->ShutdownStarted())
@@ -677,47 +648,74 @@ bool ContentBrowserClientQt::AllowWorkerIndexedDB(const GURL &url,
}
static void LaunchURL(const GURL& url,
- base::OnceCallback<content::WebContents*()> web_contents_getter,
- ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture)
+ base::RepeatingCallback<content::WebContents*()> web_contents_getter,
+ ui::PageTransition page_transition,
+ network::mojom::WebSandboxFlags sandbox_flags,
+ bool is_main_frame, bool has_user_gesture)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
content::WebContents* webContents = std::move(web_contents_getter).Run();
if (!webContents)
return;
- ProtocolHandlerRegistry* protocolHandlerRegistry =
- ProtocolHandlerRegistryFactory::GetForBrowserContext(
- webContents->GetBrowserContext());
- if (protocolHandlerRegistry &&
- protocolHandlerRegistry->IsHandledProtocol(url.scheme()))
+ custom_handlers::ProtocolHandlerRegistry *protocolHandlerRegistry =
+ ProtocolHandlerRegistryFactory::GetForBrowserContext(webContents->GetBrowserContext());
+ if (protocolHandlerRegistry && protocolHandlerRegistry->IsHandledProtocol(url.scheme()))
return;
+ // Sandbox flag logic from chrome/browser/chrome_content_browser_client.cc:
+ if (!is_main_frame) {
+ using SandboxFlags = network::mojom::WebSandboxFlags;
+ auto allow = [&](SandboxFlags flag) {
+ return (sandbox_flags & flag) == SandboxFlags::kNone;
+ };
+ bool allowed = (allow(SandboxFlags::kPopups)) ||
+ (allow(SandboxFlags::kTopNavigation)) ||
+ (allow(SandboxFlags::kTopNavigationByUserActivation) &&
+ has_user_gesture);
+
+ if (!allowed) {
+ content::RenderFrameHost *rfh = webContents->GetPrimaryMainFrame();
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch("disable-sandbox-external-protocols")) {
+ rfh->AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kError,
+ "Navigation to external protocol blocked by sandbox.");
+ return;
+ }
+ }
+ }
+
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame, has_user_gesture);
}
bool ContentBrowserClientQt::HandleExternalProtocol(const GURL &url,
- base::OnceCallback<content::WebContents*()> web_contents_getter,
- int child_id,
+ base::RepeatingCallback<content::WebContents*()> web_contents_getter,
+ int frame_tree_node_id,
content::NavigationUIData *navigation_data,
- bool is_main_frame,
+ bool is_primary_main_frame,
+ bool is_in_fenced_frame_tree,
+ network::mojom::WebSandboxFlags sandbox_flags,
ui::PageTransition page_transition,
bool has_user_gesture,
- const base::Optional<url::Origin> &initiating_origin,
+ const absl::optional<url::Origin> &initiating_origin,
+ content::RenderFrameHost *initiator_document,
mojo::PendingRemote<network::mojom::URLLoaderFactory> *out_factory)
{
- Q_UNUSED(child_id);
+ Q_UNUSED(frame_tree_node_id);
+ Q_UNUSED(is_in_fenced_frame_tree);
Q_UNUSED(navigation_data);
Q_UNUSED(initiating_origin);
+ Q_UNUSED(initiator_document);
Q_UNUSED(out_factory);
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&LaunchURL,
url,
std::move(web_contents_getter),
page_transition,
- is_main_frame,
+ sandbox_flags,
+ is_primary_main_frame,
has_user_gesture));
return true;
}
@@ -727,7 +725,7 @@ namespace {
class ProtocolHandlerThrottle : public blink::URLLoaderThrottle
{
public:
- explicit ProtocolHandlerThrottle(ProtocolHandlerRegistry *protocol_handler_registry)
+ explicit ProtocolHandlerThrottle(custom_handlers::ProtocolHandlerRegistry *protocol_handler_registry)
: protocol_handler_registry_(protocol_handler_registry)
{
}
@@ -758,7 +756,7 @@ private:
*url = translated_url;
}
- ProtocolHandlerRegistry *protocol_handler_registry_;
+ custom_handlers::ProtocolHandlerRegistry *protocol_handler_registry_;
};
} // namespace
@@ -773,7 +771,7 @@ ContentBrowserClientQt::CreateURLLoaderThrottles(
ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context)));
#if BUILDFLAG(ENABLE_EXTENSIONS)
result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
- browser_context, request.destination, frame_tree_node_id));
+ request.destination, frame_tree_node_id));
#endif
return result;
}
@@ -804,18 +802,14 @@ WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::Page
}
}
-static bool navigationThrottleCallback(content::WebContents *source,
- const navigation_interception::NavigationParams &params)
+static bool navigationThrottleCallback(content::NavigationHandle *handle)
{
// We call navigationRequested later in launchExternalUrl for external protocols.
// The is_external_protocol parameter here is not fully accurate though,
// and doesn't know about profile specific custom URL schemes.
+ content::WebContents *source = handle->GetWebContents();
ProfileQt *profile = static_cast<ProfileQt *>(source->GetBrowserContext());
- if (params.is_external_protocol() && !profile->profileAdapter()->urlSchemeHandler(toQByteArray(params.url().scheme())))
- return false;
-
- WebContentsViewQt *view = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(source)->GetView());
- if (!view->client())
+ if (handle->IsExternalProtocol() && !profile->profileAdapter()->urlSchemeHandler(toQByteArray(handle->GetURL().scheme())))
return false;
bool navigationAccepted = true;
@@ -826,14 +820,14 @@ static bool navigationThrottleCallback(content::WebContents *source,
return false;
// Redirects might not be reflected in transition_type at this point (see also chrome/.../web_navigation_api_helpers.cc)
- auto transition_type = params.transition_type();
- if (params.is_redirect())
+ auto transition_type = handle->GetPageTransition();
+ if (handle->WasServerRedirect())
transition_type = ui::PageTransitionFromInt(transition_type | ui::PAGE_TRANSITION_SERVER_REDIRECT);
client->navigationRequested(pageTransitionToNavigationType(transition_type),
- toQt(params.url()),
+ toQt(handle->GetURL()),
navigationAccepted,
- params.is_main_frame());
+ handle->IsInPrimaryMainFrame());
return !navigationAccepted;
}
@@ -846,9 +840,12 @@ std::vector<std::unique_ptr<content::NavigationThrottle>> ContentBrowserClientQt
base::BindRepeating(&navigationThrottleCallback),
navigation_interception::SynchronyMode::kSync));
-#if BUILDFLAG(ENABLE_EXTENSIONS)
- MaybeAddThrottle(extensions::PDFIFrameNavigationThrottleQt::MaybeCreateThrottleFor(navigation_handle), &throttles);
-#endif
+#if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS)
+ MaybeAddThrottle(
+ extensions::PDFIFrameNavigationThrottleQt::MaybeCreateThrottleFor(navigation_handle),
+ &throttles);
+ MaybeAddThrottle(pdf::PdfNavigationThrottle::MaybeCreateThrottleFor(navigation_handle, std::make_unique<PdfStreamDelegateQt>()), &throttles);
+#endif // BUILDFLAG(ENABLE_PDF) && BUIDLFLAG(ENABLE_EXTENSIONS)
return throttles;
}
@@ -861,7 +858,7 @@ bool ContentBrowserClientQt::IsHandledURL(const GURL &url)
bool ContentBrowserClientQt::HasCustomSchemeHandler(content::BrowserContext *browser_context,
const std::string &scheme)
{
- if (ProtocolHandlerRegistry *protocol_handler_registry =
+ if (custom_handlers::ProtocolHandlerRegistry *protocol_handler_registry =
ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context)) {
return protocol_handler_registry->IsHandledProtocol(scheme);
}
@@ -968,7 +965,16 @@ void ContentBrowserClientQt::OverrideURLLoaderFactoryParams(content::BrowserCont
std::string ContentBrowserClientQt::getUserAgent()
{
// Mention the Chromium version we're based on to get passed stupid UA-string-based feature detection (several WebRTC demos need this)
- return content::BuildUserAgentFromProduct("QtWebEngine/" QTWEBENGINECORE_VERSION_STR " Chrome/" CHROMIUM_VERSION);
+ return content::BuildUserAgentFromProduct("QtWebEngine/" + std::string(qWebEngineVersion())
+ + " Chrome/"
+ + std::string(qWebEngineChromiumVersion()));
+}
+
+blink::UserAgentMetadata ContentBrowserClientQt::GetUserAgentMetadata()
+{
+ // Implemented only for safe-keeping. It will be overridden on WebContents level.
+ static blink::UserAgentMetadata userAgentMetadata(embedder_support::GetUserAgentMetadata());
+ return userAgentMetadata;
}
std::string ContentBrowserClientQt::GetProduct()
@@ -1060,8 +1066,16 @@ void ContentBrowserClientQt::RegisterNonNetworkWorkerMainResourceURLLoaderFactor
void ContentBrowserClientQt::RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(content::BrowserContext* browser_context,
NonNetworkURLLoaderFactoryMap* factories)
{
- DCHECK(browser_context);
- DCHECK(factories);
+ Profile *profile = Profile::FromBrowserContext(browser_context);
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
+
+ for (const QByteArray &scheme : profileAdapter->customUrlSchemes()) {
+ if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(scheme.toStdString())) {
+ if (cs->flags & url::CustomScheme::ServiceWorkersAllowed)
+ factories->emplace(scheme.toStdString(), CreateCustomURLLoaderFactory(profileAdapter));
+ }
+ }
+
#if BUILDFLAG(ENABLE_EXTENSIONS)
factories->emplace(
extensions::kExtensionScheme,
@@ -1070,8 +1084,10 @@ void ContentBrowserClientQt::RegisterNonNetworkServiceWorkerUpdateURLLoaderFacto
}
void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id, int render_frame_id,
+ const absl::optional<url::Origin> &request_initiator_origin,
NonNetworkURLLoaderFactoryMap *factories)
{
+ Q_UNUSED(request_initiator_origin);
content::RenderProcessHost *process_host = content::RenderProcessHost::FromID(render_process_id);
Profile *profile = Profile::FromBrowserContext(process_host->GetBrowserContext());
ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(profile)->profileAdapter();
@@ -1085,18 +1101,18 @@ void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int
if (web_contents)
url = web_contents->GetVisibleURL();
+ bool is_background_page = false;
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ is_background_page = extensions::GetViewType(web_contents) == extensions::mojom::ViewType::kExtensionBackgroundPage;
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
// Install file scheme if necessary:
bool install_file_scheme = false;
- if (web_contents) {
- const auto *settings = static_cast<WebContentsDelegateQt *>(web_contents->GetResponsibleWebContents()->GetDelegate())->webEngineSettings();
- if (settings->testAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls)) {
- for (const auto &local_scheme : url::GetLocalSchemes()) {
- if (url.SchemeIs(local_scheme)) {
- install_file_scheme = true;
- break;
- }
- }
- }
+ if (web_contents && !is_background_page) {
+ const std::string scheme = url.scheme();
+ install_file_scheme = base::Contains(url::GetLocalSchemes(), scheme);
+ if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(scheme))
+ install_file_scheme = cs->flags & (url::CustomScheme::LocalAccessAllowed | url::CustomScheme::Local);
}
if (install_file_scheme && factories->find(url::kFileScheme) == factories->end()) {
@@ -1163,6 +1179,9 @@ base::flat_set<std::string> ContentBrowserClientQt::GetPluginMimeTypesWithExtern
}
}
#endif
+#if BUILDFLAG(ENABLE_PDF)
+ mime_types.insert("application/x-google-chrome-pdf");
+#endif
return mime_types;
}
@@ -1172,59 +1191,148 @@ bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
int render_process_id,
URLLoaderFactoryType type,
const url::Origin &request_initiator,
- base::Optional<int64_t> navigation_id,
+ absl::optional<int64_t> navigation_id,
ukm::SourceIdObj ukm_source_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> *factory_receiver,
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient> *header_client,
bool *bypass_redirect_checks,
bool *disable_secure_dns,
- network::mojom::URLLoaderFactoryOverridePtr *factory_override)
-{
+ network::mojom::URLLoaderFactoryOverridePtr *factory_override,
+ scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner)
+{
+ Q_UNUSED(render_process_id);
+ Q_UNUSED(type);
+ Q_UNUSED(request_initiator);
+ Q_UNUSED(navigation_id);
+ Q_UNUSED(ukm_source_id);
+ Q_UNUSED(header_client);
+ Q_UNUSED(bypass_redirect_checks);
+ Q_UNUSED(disable_secure_dns);
+ Q_UNUSED(factory_override);
auto adapter = static_cast<ProfileQt *>(browser_context)->profileAdapter();
- int process_id = type == URLLoaderFactoryType::kNavigation ? 0 : render_process_id;
auto proxied_receiver = std::move(*factory_receiver);
mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_url_loader_factory;
*factory_receiver = pending_url_loader_factory.InitWithNewPipeAndPassReceiver();
// Will manage its own lifetime
- new ProxyingURLLoaderFactoryQt(adapter, process_id, std::move(proxied_receiver), std::move(pending_url_loader_factory));
+ // FIXME: use navigation_response_task_runner?
+ new ProxyingURLLoaderFactoryQt(adapter,
+ frame ? frame->GetFrameTreeNodeId() : content::RenderFrameHost::kNoFrameTreeNodeId,
+ std::move(proxied_receiver), std::move(pending_url_loader_factory));
return true;
}
-void ContentBrowserClientQt::SiteInstanceGotProcess(content::SiteInstance *site_instance)
+std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
+ContentBrowserClientQt::WillCreateURLLoaderRequestInterceptors(content::NavigationUIData* navigation_ui_data,
+ int frame_tree_node_id, int64_t navigation_id,
+ scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner)
{
-#if BUILDFLAG(ENABLE_EXTENSIONS)
- content::BrowserContext *context = site_instance->GetBrowserContext();
- extensions::ExtensionRegistry *registry = extensions::ExtensionRegistry::Get(context);
- const extensions::Extension *extension = registry->enabled_extensions().GetExtensionOrAppByURL(site_instance->GetSiteURL());
- if (!extension)
- return;
+ std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>> interceptors;
+#if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS)
+ {
+ std::unique_ptr<content::URLLoaderRequestInterceptor> pdf_interceptor =
+ pdf::PdfURLLoaderRequestInterceptor::MaybeCreateInterceptor(
+ frame_tree_node_id, std::make_unique<PdfStreamDelegateQt>());
+ if (pdf_interceptor)
+ interceptors.push_back(std::move(pdf_interceptor));
+ }
+#endif // BUILDFLAG(ENABLE_PDF) && BUIDLFLAG(ENABLE_EXTENSIONS)
- extensions::ProcessMap *processMap = extensions::ProcessMap::Get(context);
- processMap->Insert(extension->id(), site_instance->GetProcess()->GetID(), site_instance->GetId());
-#endif
+ return interceptors;
}
-void ContentBrowserClientQt::SiteInstanceDeleting(content::SiteInstance *site_instance)
+bool ContentBrowserClientQt::WillInterceptWebSocket(content::RenderFrameHost *frame)
{
-#if BUILDFLAG(ENABLE_EXTENSIONS)
- // Don't do anything if we're shutting down.
- if (content::BrowserMainRunner::ExitedMainMessageLoop() || !site_instance->HasProcess())
- return;
+ return frame != nullptr;
+}
+
+QWebEngineUrlRequestInterceptor *getProfileInterceptorFromFrame(content::RenderFrameHost *frame)
+{
+ ProfileQt *profile = static_cast<ProfileQt *>(frame->GetBrowserContext());
+ if (profile)
+ return profile->profileAdapter()->requestInterceptor();
+ return nullptr;
+}
+
+QWebEngineUrlRequestInterceptor *getPageInterceptor(content::WebContents *web_contents)
+{
+ if (web_contents) {
+ auto view = static_cast<content::WebContentsImpl *>(web_contents)->GetView();
+ if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client())
+ return client->webContentsAdapter()->requestInterceptor();
+ }
+ return nullptr;
+}
+
+void ContentBrowserClientQt::CreateWebSocket(
+ content::RenderFrameHost *frame,
+ WebSocketFactory factory,
+ const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const absl::optional<std::string> &user_agent,
+ mojo::PendingRemote<network::mojom::WebSocketHandshakeClient> handshake_client)
+{
+ QWebEngineUrlRequestInterceptor *profileInterceptor = getProfileInterceptorFromFrame(frame);
+ content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame);
+ QWebEngineUrlRequestInterceptor *pageInterceptor = getPageInterceptor(web_contents);
+ std::vector<network::mojom::HttpHeaderPtr> headers;
+ GURL to_url = url;
+ bool addedUserAgent = false;
+ if (profileInterceptor || pageInterceptor) {
+ QUrl initiator = web_contents ? toQt(web_contents->GetURL()) : QUrl();
+ auto *infoPrivate = new QWebEngineUrlRequestInfoPrivate(
+ QWebEngineUrlRequestInfo::ResourceTypeWebSocket,
+ QWebEngineUrlRequestInfo::NavigationTypeOther,
+ toQt(url), toQt(site_for_cookies.first_party_url()), initiator,
+ QByteArrayLiteral("GET"));
+ QWebEngineUrlRequestInfo requestInfo(infoPrivate);
+ if (profileInterceptor) {
+ profileInterceptor->interceptRequest(requestInfo);
+ pageInterceptor = getPageInterceptor(web_contents);
+ }
+ if (pageInterceptor && !requestInfo.changed())
+ pageInterceptor->interceptRequest(requestInfo);
+ if (infoPrivate->shouldBlockRequest)
+ return; // ### should we call OnFailure on handshake_client?
+ if (infoPrivate->shouldRedirectRequest)
+ to_url = toGurl(infoPrivate->url);
+ for (auto header = infoPrivate->extraHeaders.constBegin(); header != infoPrivate->extraHeaders.constEnd(); ++header) {
+ std::string h = header.key().toStdString();
+ if (base::EqualsCaseInsensitiveASCII(h, net::HttpRequestHeaders::kUserAgent))
+ addedUserAgent = true;
+ headers.push_back(network::mojom::HttpHeader::New(h, header.value().toStdString()));
+ }
+ }
+ if (!addedUserAgent && user_agent)
+ headers.push_back(network::mojom::HttpHeader::New(net::HttpRequestHeaders::kUserAgent, *user_agent));
+
+ std::move(factory).Run(to_url, std::move(headers), std::move(handshake_client), mojo::NullRemote(), mojo::NullRemote());
+}
+void ContentBrowserClientQt::SiteInstanceGotProcess(content::SiteInstance *site_instance)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
content::BrowserContext *context = site_instance->GetBrowserContext();
extensions::ExtensionRegistry *registry = extensions::ExtensionRegistry::Get(context);
- const extensions::Extension *extension = registry->enabled_extensions().GetExtensionOrAppByURL(site_instance->GetSiteURL());
+ if (!registry)
+ return;
+ if (site_instance->IsGuest())
+ return;
+ auto site_url = site_instance->GetSiteURL();
+ if (!site_url.SchemeIs(extensions::kExtensionScheme))
+ return;
+ const extensions::Extension *extension = registry->enabled_extensions().GetByID(site_url.host());
if (!extension)
return;
extensions::ProcessMap *processMap = extensions::ProcessMap::Get(context);
- processMap->Remove(extension->id(), site_instance->GetProcess()->GetID(), site_instance->GetId());
+ processMap->Insert(extension->id(), site_instance->GetProcess()->GetID());
#endif
}
-content::WebContentsViewDelegate *ContentBrowserClientQt::GetWebContentsViewDelegate(content::WebContents *web_contents)
+std::unique_ptr<content::WebContentsViewDelegate> ContentBrowserClientQt::GetWebContentsViewDelegate(content::WebContents *web_contents)
{
FormInteractionTabHelper::CreateForWebContents(web_contents);
+ FileSystemAccessPermissionRequestManagerQt::CreateForWebContents(web_contents);
if (auto *registry = performance_manager::PerformanceManagerRegistry::GetInstance())
registry->MaybeCreatePageNodeForWebContents(web_contents);
@@ -1240,4 +1348,36 @@ ContentBrowserClientQt::AllowWebBluetooth(content::BrowserContext *browser_conte
return content::ContentBrowserClient::AllowWebBluetoothResult::BLOCK_GLOBALLY_DISABLED;
}
+content::WebAuthenticationDelegate *ContentBrowserClientQt::GetWebAuthenticationDelegate()
+{
+ static base::NoDestructor<WebAuthenticationDelegateQt> delegate;
+ return delegate.get();
+}
+
+#if !BUILDFLAG(IS_ANDROID)
+std::unique_ptr<content::AuthenticatorRequestClientDelegate>
+ContentBrowserClientQt::GetWebAuthenticationRequestDelegate(
+ content::RenderFrameHost *render_frame_host)
+{
+ return std::make_unique<AuthenticatorRequestClientDelegateQt>(render_frame_host);
+}
+#endif
+
+void ContentBrowserClientQt::GetMediaDeviceIDSalt(content::RenderFrameHost *rfh,
+ const net::SiteForCookies & /*site_for_cookies*/,
+ const blink::StorageKey & /*storage_key*/,
+ base::OnceCallback<void(bool, const std::string&)> callback)
+{
+#if BUILDFLAG(ENABLE_WEBRTC)
+ content::BrowserContext *browser_context = rfh->GetBrowserContext();
+ if (!browser_context->IsOffTheRecord()) {
+ ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+ std::string mediaId = profile->GetMediaDeviceIDSalt();
+ std::move(callback).Run(true, mediaId);
+ return;
+ }
+#endif
+ std::move(callback).Run(false, "");
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 94ee69bf1..7d8e98028 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CONTENT_BROWSER_CLIENT_QT_H
#define CONTENT_BROWSER_CLIENT_QT_H
@@ -58,26 +22,24 @@ class ResourceContext;
class WebContents;
struct MainFunctionParams;
struct Referrer;
-}
+} // namespace content
-namespace gl {
-class GLShareGroup;
-}
+namespace device {
+class GeolocationManager;
+} // namespace device
namespace QtWebEngineCore {
-class ShareGroupQt;
+class BrowserMainPartsQt;
class ContentBrowserClientQt : public content::ContentBrowserClient
{
public:
ContentBrowserClientQt();
~ContentBrowserClientQt();
- std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(const content::MainFunctionParams&) override;
+ std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(bool is_integration_test) override;
void RenderProcessWillLaunch(content::RenderProcessHost *host) override;
- gl::GLShareGroup* GetInProcessGpuShareGroup() override;
content::MediaObserver* GetMediaObserver() override;
- scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override;
void OverrideWebkitPrefs(content::WebContents *web_contents,
blink::web_pref::WebPreferences *prefs) override;
void AllowCertificateError(content::WebContents *web_contents,
@@ -87,13 +49,13 @@ public:
bool is_main_frame_request,
bool strict_enforcement,
base::OnceCallback<void(content::CertificateRequestResultType)> callback) override;
- base::OnceClosure SelectClientCertificate(content::WebContents* web_contents,
+ base::OnceClosure SelectClientCertificate(content::BrowserContext* browser_context,
+ content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
net::ClientCertIdentityList client_certs,
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(content::BrowserContext *browser_context) override;
- content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override;
- content::PlatformNotificationService * GetPlatformNotificationService(content::BrowserContext *browser_context) override;
+ std::unique_ptr<content::DevToolsManagerDelegate> CreateDevToolsManagerDelegate() override;
std::string GetApplicationLocale() override;
std::string GetAcceptLangs(content::BrowserContext* context) override;
@@ -112,6 +74,8 @@ public:
void ExposeInterfacesToRenderer(service_manager::BinderRegistry *registry,
blink::AssociatedInterfaceRegistry *associated_registry,
content::RenderProcessHost *render_process_host) override;
+ void RegisterAssociatedInterfaceBindersForRenderFrameHost(content::RenderFrameHost &render_frame_host,
+ blink::AssociatedInterfaceRegistry &associated_registry) override;
bool CanCreateWindow(content::RenderFrameHost *opener,
const GURL &opener_url,
@@ -137,26 +101,30 @@ public:
int process_id,
int routing_id,
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> *receiver) override;
+ bool WillInterceptWebSocket(content::RenderFrameHost *frame) override;
+ void CreateWebSocket(
+ content::RenderFrameHost *frame,
+ WebSocketFactory factory,
+ const GURL &url,
+ const net::SiteForCookies &site_for_cookies,
+ const absl::optional<std::string> &user_agent,
+ mojo::PendingRemote<network::mojom::WebSocketHandshakeClient> handshake_client) override;
- bool AllowAppCache(const GURL &manifest_url,
- const GURL &first_party,
- const base::Optional<url::Origin> &top_frame_origin,
- content::BrowserContext *context) override;
content::AllowServiceWorkerResult AllowServiceWorker(
const GURL &scope,
- const GURL &site_for_cookies,
- const base::Optional<url::Origin> &top_frame_origin,
+ const net::SiteForCookies &site_for_cookies,
+ const absl::optional<url::Origin> &top_frame_origin,
const GURL &script_url,
content::BrowserContext *context) override;
void AllowWorkerFileSystem(const GURL &url,
content::BrowserContext *context,
- const std::vector<content::GlobalFrameRoutingId> &render_frames,
+ const std::vector<content::GlobalRenderFrameHostId> &render_frames,
base::OnceCallback<void(bool)> callback) override;
bool AllowWorkerIndexedDB(const GURL &url,
content::BrowserContext *context,
- const std::vector<content::GlobalFrameRoutingId> &render_frames) override;
+ const std::vector<content::GlobalRenderFrameHostId> &render_frames) override;
AllowWebBluetoothResult AllowWebBluetooth(content::BrowserContext *browser_context,
const url::Origin &requesting_origin,
const url::Origin &embedding_origin) override;
@@ -164,6 +132,8 @@ public:
#if QT_CONFIG(webengine_geolocation)
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider() override;
#endif
+ device::GeolocationManager *GetGeolocationManager() override;
+
bool ShouldIsolateErrorPage(bool in_main_frame) override;
bool ShouldUseProcessPerSite(content::BrowserContext *browser_context, const GURL &effective_url) override;
bool DoesSiteRequireDedicatedProcess(content::BrowserContext *browser_context,
@@ -180,10 +150,6 @@ public:
void GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings) override;
#endif
-#if QT_CONFIG(webengine_pepper_plugins)
- void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
-#endif
-
std::unique_ptr<content::LoginDelegate> CreateLoginDelegate(
const net::AuthChallengeInfo &auth_info,
content::WebContents *web_contents,
@@ -196,13 +162,16 @@ public:
bool HandleExternalProtocol(
const GURL &url,
- base::OnceCallback<content::WebContents*()> web_contents_getter,
- int child_id,
+ base::RepeatingCallback<content::WebContents*()> web_contents_getter,
+ int frame_tree_node_id,
content::NavigationUIData *navigation_data,
- bool is_main_frame,
+ bool is_primary_main_frame,
+ bool is_in_fenced_frame_tree,
+ network::mojom::WebSandboxFlags sandbox_flags,
ui::PageTransition page_transition,
bool has_user_gesture,
- const base::Optional<url::Origin> &initiating_origin,
+ const absl::optional<url::Origin> &initiating_origin,
+ content::RenderFrameHost *initiator_document,
mojo::PendingRemote<network::mojom::URLLoaderFactory> *out_factory) override;
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateURLLoaderThrottles(
@@ -217,19 +186,24 @@ public:
bool HasErrorPage(int http_status_code, content::WebContents *contents) override;
bool HasCustomSchemeHandler(content::BrowserContext *browser_context,
const std::string &scheme) override;
-
+ std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
+ WillCreateURLLoaderRequestInterceptors(content::NavigationUIData *navigation_ui_data,
+ int frame_tree_node_id,
+ int64_t navigation_id,
+ scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) override;
bool WillCreateURLLoaderFactory(content::BrowserContext *browser_context,
content::RenderFrameHost *frame,
int render_process_id,
URLLoaderFactoryType type,
const url::Origin &request_initiator,
- base::Optional<int64_t> navigation_id,
+ absl::optional<int64_t> navigation_id,
ukm::SourceIdObj ukm_source_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> *factory_receiver,
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient> *header_client,
bool *bypass_redirect_checks,
bool *disable_secure_dns,
- network::mojom::URLLoaderFactoryOverridePtr *factory_override) override;
+ network::mojom::URLLoaderFactoryOverridePtr *factory_override,
+ scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) override;
scoped_refptr<network::SharedURLLoaderFactory> GetSystemSharedURLLoaderFactory() override;
network::mojom::NetworkContext *GetSystemNetworkContext() override;
void OnNetworkServiceCreated(network::mojom::NetworkService *network_service) override;
@@ -244,24 +218,36 @@ public:
ukm::SourceIdObj ukm_source_id,
NonNetworkURLLoaderFactoryMap *factories) override;
void RegisterNonNetworkSubresourceURLLoaderFactories(int render_process_id, int render_frame_id,
+ const absl::optional<url::Origin>& request_initiator_origin,
NonNetworkURLLoaderFactoryMap *factories) override;
void RegisterNonNetworkWorkerMainResourceURLLoaderFactories(content::BrowserContext* browser_context,
NonNetworkURLLoaderFactoryMap* factories) override;
void RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(content::BrowserContext* browser_context,
NonNetworkURLLoaderFactoryMap* factories) override;
void SiteInstanceGotProcess(content::SiteInstance *site_instance) override;
- void SiteInstanceDeleting(content::SiteInstance *site_instance) override;
base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(content::BrowserContext *browser_context) override;
- content::WebContentsViewDelegate* GetWebContentsViewDelegate(content::WebContents* web_contents) override;
+ std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate(content::WebContents *web_contents) override;
static std::string getUserAgent();
std::string GetUserAgent() override { return getUserAgent(); }
+ blink::UserAgentMetadata GetUserAgentMetadata() override;
std::string GetProduct() override;
+ content::WebAuthenticationDelegate *GetWebAuthenticationDelegate() override;
+#if !BUILDFLAG(IS_ANDROID)
+ std::unique_ptr<content::AuthenticatorRequestClientDelegate>
+ GetWebAuthenticationRequestDelegate(content::RenderFrameHost *render_frame_host) override;
+#endif
+
+ void GetMediaDeviceIDSalt(content::RenderFrameHost *rfh,
+ const net::SiteForCookies &site_for_cookies,
+ const blink::StorageKey &storage_key,
+ base::OnceCallback<void(bool, const std::string&)> callback) override;
+
private:
- scoped_refptr<ShareGroupQt> m_shareGroupQt;
+ BrowserMainPartsQt *m_browserMainParts = nullptr;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index e06cde63d..b6a0909b0 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -1,50 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "content_client_qt.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
+#include "base/json/json_string_value_serializer.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
#include "base/version.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_constants.h"
@@ -53,6 +18,7 @@
#include "extensions/common/constants.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
+#include "media/cdm/supported_audio_codecs.h"
#include "media/media_buildflags.h"
#include "ui/base/layout.h"
#include "ui/base/l10n/l10n_util.h"
@@ -64,8 +30,10 @@
#include <QLibraryInfo>
#include <QString>
+
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_paths.h" // nogncheck
+#include "media/cdm/clear_key_cdm_common.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#if BUILDFLAG(ENABLE_WIDEVINE) && !BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
@@ -73,9 +41,9 @@
// File name of the CDM on different platforms.
const char kWidevineCdmFileName[] =
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
"widevinecdm.plugin";
-#elif defined(OS_WIN)
+#elif BUILDFLAG(IS_WIN)
"widevinecdm.dll";
#else // OS_LINUX, etc.
"libwidevinecdm.so";
@@ -84,17 +52,18 @@ const char kWidevineCdmFileName[] =
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if QT_CONFIG(webengine_printing_and_pdf)
+#include "components/pdf/common/internal_plugin_helpers.h"
#include "pdf/pdf.h"
-#include "pdf/pdf_ppapi.h"
-const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
const char kPdfPluginPath[] = "internal-pdf-viewer";
#endif // QT_CONFIG(webengine_printing_and_pdf)
+using Robustness = content::CdmInfo::Robustness;
+
static QString webenginePluginsPath()
{
// Look for plugins in /plugins/webengine or application dir.
static bool initialized = false;
- static QString potentialPluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath) % QLatin1String("/webengine");
+ static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/webengine");
if (!initialized) {
initialized = true;
if (!QFileInfo::exists(potentialPluginsPath))
@@ -131,18 +100,14 @@ static QString getProgramFilesDir(bool x86Dir = false)
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.Chromium file.
-#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/content_plugin_info.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
-namespace switches {
-const char kPpapiWidevinePath[] = "ppapi-widevine-path";
-}
-
static QString ppapiPluginsPath()
{
// Look for plugins in /plugins/ppapi or application dir.
static bool initialized = false;
- static QString potentialPluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi");
+ static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi");
if (!initialized) {
initialized = true;
if (!QFileInfo::exists(potentialPluginsPath))
@@ -151,28 +116,27 @@ static QString ppapiPluginsPath()
return potentialPluginsPath;
}
-void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins)
+void ComputeBuiltInPlugins(std::vector<content::ContentPluginInfo> *plugins)
{
#if QT_CONFIG(webengine_printing_and_pdf)
- content::PepperPluginInfo pdf_info;
+ static constexpr char kPDFPluginExtension[] = "pdf";
+ static constexpr char kPDFPluginDescription[] = "Portable Document Format";
+ content::ContentPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = "Chromium PDF Viewer";
- pdf_info.description = "Portable Document Format";
+ pdf_info.description = kPDFPluginDescription;
pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
- content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf", "Portable Document Format");
+ content::WebPluginMimeType pdf_mime_type(
+ pdf::kInternalPluginMimeType, kPDFPluginExtension, kPDFPluginDescription);
pdf_info.mime_types.push_back(pdf_mime_type);
- pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
- pdf_info.internal_entry_points.initialize_module = chrome_pdf::PPP_InitializeModule;
- pdf_info.internal_entry_points.shutdown_module = chrome_pdf::PPP_ShutdownModule;
- pdf_info.permissions = ppapi::PERMISSION_DEV | ppapi::PERMISSION_PDF;
plugins->push_back(pdf_info);
#endif // QT_CONFIG(webengine_printing_and_pdf)
}
namespace QtWebEngineCore {
-void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins)
+void ContentClientQt::AddPlugins(std::vector<content::ContentPluginInfo> *plugins)
{
ComputeBuiltInPlugins(plugins);
}
@@ -183,8 +147,42 @@ void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* p
namespace QtWebEngineCore {
#if defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT)
+#if defined(Q_OS_LINUX)
+static const QDir widevineCdmDirHint(const QDir &widevineDir)
+{
+ const QString hintFilePath = widevineDir.absolutePath() % QDir::separator()
+ % QLatin1String("latest-component-updated-widevine-cdm");
+ if (!QFileInfo::exists(hintFilePath)) {
+ // CDM hint file does not exist.
+ return widevineDir;
+ }
+
+ std::string jsonString;
+ if (!base::ReadFileToString(toFilePath(hintFilePath), &jsonString)) {
+ // Could not read the CDM hint file.
+ return widevineDir;
+ }
+
+ std::string error_message;
+ JSONStringValueDeserializer deserializer(jsonString);
+ std::unique_ptr<base::Value> dict = deserializer.Deserialize(nullptr, &error_message);
+ if (!dict || !dict->is_dict()) {
+ DLOG(ERROR) << "Could not deserialize the CDM hint file. Error: "
+ << error_message;
+ // Could not deserialize the CDM hint file.
+ return widevineDir;
+ }
+
+ std::string *widevineCdmDirPath = dict->GetDict().FindString("Path");
+ if (!widevineCdmDirPath)
+ return widevineDir;
+
+ return QDir(QString::fromStdString(*widevineCdmDirPath));
+}
+#endif // defined(Q_OS_LINUX)
+
static bool IsWidevineAvailable(base::FilePath *cdm_path,
- content::CdmCapability *capability)
+ media::CdmCapability *capability)
{
QStringList pluginPaths;
const base::CommandLine::StringType widevine_argument = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(switches::kCdmWidevinePath);
@@ -252,28 +250,76 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
}
}
#elif defined(Q_OS_LINUX)
- pluginPaths << QStringLiteral("/opt/google/chrome/libwidevinecdm.so") // Old Google Chrome
+ QList<QDir> potentialWidevineVersionDirs;
+
+ // Google Chrome widevine modules
+ QDir chromeWidevineDir(QDir::homePath() + "/.config/google-chrome/WidevineCdm");
+ if (chromeWidevineDir.exists())
+ potentialWidevineVersionDirs << widevineCdmDirHint(chromeWidevineDir);
+
+ // Firefox widevine modules
+ QDir firefoxPotentialProfilesDir(QDir::homePath() + "/.mozilla/firefox");
+ if (firefoxPotentialProfilesDir.exists()) {
+ QFileInfoList firefoxProfileDirs = firefoxPotentialProfilesDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+ for (const QFileInfo &info : firefoxProfileDirs) {
+ QDir widevinePluginsDir(info.absoluteFilePath() + "/gmp-widevinecdm");
+ if (widevinePluginsDir.exists())
+ potentialWidevineVersionDirs << widevinePluginsDir;
+ }
+ }
+
+ // Chromium widevine modules (might not work with proprietary codecs)
+ QDir chromiumWidevineDir(QDir::homePath() + "/.config/chromium/WidevineCdm");
+ if (chromiumWidevineDir.exists())
+ potentialWidevineVersionDirs << widevineCdmDirHint(chromiumWidevineDir);
+
+ // Search for widewine versions
+ for (const QDir &dir : potentialWidevineVersionDirs) {
+ QFileInfoList widevineVersionDirs = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+ widevineVersionDirs.prepend(QFileInfo(dir.absolutePath()));
+ // ### alternatively look up in the manifest.json and take the path from there.
#if Q_PROCESSOR_WORDSIZE == 8
- << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so")
+ const QString library = QLatin1String("/_platform_specific/linux_x64/libwidevinecdm.so");
#else
- << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so")
+ const QString library = QLatin1String("/_platform_specific/linux_x86/libwidevinecdm.so");
#endif
- << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch
+ for (const QFileInfo &info : widevineVersionDirs) {
+ pluginPaths << info.absoluteFilePath() + "/libwidevinecdm.so";
+ pluginPaths << info.absoluteFilePath() + library;
+ }
+ }
+
+ // Fixed paths:
+ pluginPaths << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch
<< QStringLiteral("/usr/lib/chromium-browser/libwidevinecdm.so") // Ubuntu/neon
- << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so"); // OpenSUSE style
+ << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so") // OpenSUSE style
+#if Q_PROCESSOR_WORDSIZE == 8
+ << QStringLiteral("/usr/lib64/chromium-browser/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Gentoo
+ << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Old Google Chrome
+#else
+ << QStringLiteral("/usr/lib/chromium-browser/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Gentoo
+ << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Old Google Chrome
+#endif
+ << QStringLiteral("/opt/google/chrome/libwidevinecdm.so"); // Older Google Chrome
#endif
}
- for (const QString &pluginPath : qAsConst(pluginPaths)) {
+ for (const QString &pluginPath : std::as_const(pluginPaths)) {
*cdm_path = QtWebEngineCore::toFilePath(pluginPath);
if (base::PathExists(*cdm_path)) {
// Add the supported codecs as if they came from the component manifest.
// This list must match the CDM that is being bundled with Chrome.
- capability->video_codecs.push_back(media::VideoCodec::kCodecVP8);
- capability->video_codecs.push_back(media::VideoCodec::kCodecVP9);
+ const std::vector<media::VideoCodecProfile> kAllProfiles = {};
+ capability->video_codecs.emplace(media::VideoCodec::kVP8, kAllProfiles);
+ capability->video_codecs.emplace(media::VideoCodec::kVP9, kAllProfiles);
+ capability->video_codecs.emplace(media::VideoCodec::kAV1, kAllProfiles);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
- capability->video_codecs.push_back(media::VideoCodec::kCodecH264);
+ capability->video_codecs.emplace(media::VideoCodec::kH264, kAllProfiles);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+ capability->video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles);
+#endif
+ capability->audio_codecs = media::GetCdmSupportedAudioCodecs();
// Add the supported encryption schemes as if they came from the
// component manifest. This list must match the CDM that is being
@@ -298,12 +344,12 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
if (cdms) {
#if defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT)
base::FilePath cdm_path;
- content::CdmCapability capability;
+ media::CdmCapability capability;
if (IsWidevineAvailable(&cdm_path, &capability)) {
const base::Version version;
- cdms->push_back(content::CdmInfo(kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
- kWidevineCdmFileSystemId, std::move(capability),
- kWidevineKeySystem, false));
+ cdms->push_back(content::CdmInfo(kWidevineKeySystem, Robustness::kSoftwareSecure, std::move(capability),
+ /*supports_sub_key_systems=*/false, kWidevineCdmDisplayName,
+ kWidevineCdmType, version, cdm_path));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT)
@@ -312,34 +358,27 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo>
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
base::FilePath clear_key_cdm_path = command_line->GetSwitchValuePath(switches::kClearKeyCdmPathForTesting);
if (!clear_key_cdm_path.empty() && base::PathExists(clear_key_cdm_path)) {
- // TODO(crbug.com/764480): Remove these after we have a central place for
- // External Clear Key (ECK) related information.
- // Normal External Clear Key key system.
- const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey";
- // A variant of ECK key system that has a different GUID.
- const char kExternalClearKeyDifferentGuidTestKeySystem[] =
- "org.chromium.externalclearkey.differentguid";
-
// Supported codecs are hard-coded in ExternalClearKeyProperties.
- content::CdmCapability capability(
- {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs},
+ media::CdmCapability capability(
+ {}, {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs},
{media::CdmSessionType::kTemporary,
media::CdmSessionType::kPersistentLicense});
- // Register kExternalClearKeyDifferentGuidTestKeySystem first separately.
+ // Register media::kExternalClearKeyDifferentCdmTypeTestKeySystem first separately.
// Otherwise, it'll be treated as a sub-key-system of normal
// kExternalClearKeyKeySystem. See MultipleCdmTypes test in
// ECKEncryptedMediaTest.
- cdms->push_back(content::CdmInfo(media::kClearKeyCdmDisplayName, media::kClearKeyCdmDifferentGuid,
- base::Version("0.1.0.0"), clear_key_cdm_path,
- media::kClearKeyCdmFileSystemId, capability,
- kExternalClearKeyDifferentGuidTestKeySystem, false));
-
- // Supported codecs are hard-coded in ExternalClearKeyProperties.
- cdms->push_back(content::CdmInfo(media::kClearKeyCdmDisplayName, media::kClearKeyCdmGuid,
- base::Version("0.1.0.0"), clear_key_cdm_path,
- media::kClearKeyCdmFileSystemId, capability,
- kExternalClearKeyKeySystem, true));
+ cdms->push_back(content::CdmInfo(media::kExternalClearKeyDifferentCdmTypeTestKeySystem,
+ Robustness::kSoftwareSecure, capability,
+ /*supports_sub_key_systems=*/false, media::kClearKeyCdmDisplayName,
+ media::kClearKeyCdmDifferentCdmType, base::Version("0.1.0.0"),
+ clear_key_cdm_path));
+
+ cdms->push_back(content::CdmInfo(media::kExternalClearKeyKeySystem,
+ Robustness::kSoftwareSecure, capability,
+ /*supports_sub_key_systems=*/true, media::kClearKeyCdmDisplayName,
+ media::kClearKeyCdmType, base::Version("0.1.0.0"),
+ clear_key_cdm_path));
}
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
}
@@ -358,7 +397,7 @@ void ContentClientQt::AddAdditionalSchemes(Schemes* schemes)
#endif
}
-base::StringPiece ContentClientQt::GetDataResource(int resource_id, ui::ScaleFactor scale_factor)
+base::StringPiece ContentClientQt::GetDataResource(int resource_id, ui::ResourceScaleFactor scale_factor)
{
return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(resource_id, scale_factor);
}
@@ -373,9 +412,24 @@ gfx::Image &ContentClientQt::GetNativeImageNamed(int resource_id)
return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
}
-base::string16 ContentClientQt::GetLocalizedString(int message_id)
+std::u16string ContentClientQt::GetLocalizedString(int message_id)
{
return l10n_util::GetStringUTF16(message_id);
}
+// This method is a copy from chrome/common/chrome_content_client.cc:
+// Copyright 2012 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.Chromium file.
+blink::OriginTrialPolicy *ContentClientQt::GetOriginTrialPolicy()
+{
+ // Prevent initialization race (see crbug.com/721144). There may be a
+ // race when the policy is needed for worker startup (which happens on a
+ // separate worker thread).
+ base::AutoLock auto_lock(origin_trial_policy_lock_);
+ if (!origin_trial_policy_)
+ origin_trial_policy_ = std::make_unique<embedder_support::OriginTrialPolicyImpl>();
+ return origin_trial_policy_.get();
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/content_client_qt.h b/src/core/content_client_qt.h
index a7fc7432a..f58e17f96 100644
--- a/src/core/content_client_qt.h
+++ b/src/core/content_client_qt.h
@@ -1,65 +1,40 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CONTENT_CLIENT_QT_H
#define CONTENT_CLIENT_QT_H
#include "qtwebenginecoreglobal_p.h"
+
#include "base/strings/string_piece.h"
+#include "base/synchronization/lock.h"
+#include "components/embedder_support/origin_trials/origin_trial_policy_impl.h"
#include "content/public/common/content_client.h"
#include "ui/base/layout.h"
+#include <memory>
+
namespace QtWebEngineCore {
class ContentClientQt : public content::ContentClient {
public:
#if QT_CONFIG(webengine_pepper_plugins)
- void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) override;
+ void AddPlugins(std::vector<content::ContentPluginInfo> *plugins) override;
#endif
void AddContentDecryptionModules(std::vector<content::CdmInfo> *cdms,
std::vector<media::CdmHostFilePath> *cdm_host_file_paths) override;
void AddAdditionalSchemes(Schemes* schemes) override;
- base::StringPiece GetDataResource(int, ui::ScaleFactor) override;
+ base::StringPiece GetDataResource(int, ui::ResourceScaleFactor) override;
base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
gfx::Image &GetNativeImageNamed(int resource_id) override;
- base::string16 GetLocalizedString(int message_id) override;
+ std::u16string GetLocalizedString(int message_id) override;
+ blink::OriginTrialPolicy *GetOriginTrialPolicy() override;
+
+private:
+ // Used to lock when |origin_trial_policy_| is initialized.
+ base::Lock origin_trial_policy_lock_;
+ std::unique_ptr<embedder_support::OriginTrialPolicyImpl> origin_trial_policy_;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index ec0e63858..f949d93a5 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -1,47 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "content_main_delegate_qt.h"
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
+#include "base/memory/ref_counted_memory.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
@@ -49,7 +14,6 @@
#include "content/public/browser/browser_main_runner.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
-#include "media/gpu/buildflags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/resource/resource_bundle.h"
@@ -65,31 +29,27 @@
#include "web_engine_context.h"
#include "web_engine_library_info.h"
-#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
+#if defined(ARCH_CPU_ARM_FAMILY) && (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX))
#include "base/cpu.h"
#endif
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
#include "media/audio/audio_manager.h"
#include "ui/base/ui_base_switches.h"
#endif
-// must be included before vaapi_wrapper.h
-#include <QtCore/qcoreapplication.h>
-
-#if defined(OS_WIN)
-#include "media/gpu/windows/dxva_video_decode_accelerator_win.h"
-#include "media/gpu/windows/media_foundation_video_encode_accelerator_win.h"
+#if BUILDFLAG(IS_WIN)
+#include "media/base/win/mf_initializer.h"
+#include "sandbox/policy/win/sandbox_warmup.h"
#endif
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
+#include "base/trace_event/trace_event.h"
#include "content/public/common/content_features.h"
#include "media/gpu/mac/vt_video_decode_accelerator_mac.h"
#endif
-#if BUILDFLAG(USE_VAAPI)
-#include "media/gpu/vaapi/vaapi_wrapper.h"
-#endif
+#include <QtCore/qcoreapplication.h>
namespace content {
ContentClient *GetContentClient();
@@ -111,23 +71,19 @@ struct LazyDirectoryListerCacher
{
LazyDirectoryListerCacher()
{
- base::DictionaryValue dict;
- dict.SetString("header", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_HEADER));
- dict.SetString("parentDirText", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_PARENT));
- dict.SetString("headerName", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_NAME));
- dict.SetString("headerSize", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_SIZE));
- dict.SetString("headerDateModified",
- l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_DATE_MODIFIED));
- dict.SetString("language", l10n_util::GetLanguage(base::i18n::GetConfiguredLocale()));
- dict.SetString("listingParsingErrorBoxText",
- l10n_util::GetStringFUTF16(IDS_DIRECTORY_LISTING_PARSING_ERROR_BOX_TEXT,
- toString16(QCoreApplication::applicationName())));
- dict.SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
+ base::Value::Dict dict;
+ dict.Set("header", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_HEADER));
+ dict.Set("parentDirText", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_PARENT));
+ dict.Set("headerName", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_NAME));
+ dict.Set("headerSize", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_SIZE));
+ dict.Set("headerDateModified", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_DATE_MODIFIED));
+ dict.Set("language", l10n_util::GetLanguage(base::i18n::GetConfiguredLocale()));
+ dict.Set("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
std::string html =
webui::GetI18nTemplateHtml(
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_DIR_HEADER_HTML),
- &dict);
- html_data = base::RefCountedString::TakeString(&html);
+ std::move(dict));
+ html_data = base::MakeRefCounted<base::RefCountedString>(std::move(html));
}
scoped_refptr<base::RefCountedMemory> html_data;
@@ -171,7 +127,7 @@ static logging::LoggingDestination DetermineLogMode(const base::CommandLine& com
void ContentMainDelegateQt::PreSandboxStartup()
{
-#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
+#if defined(ARCH_CPU_ARM_FAMILY) && (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX))
// Create an instance of the CPU class to parse /proc/cpuinfo and cache
// cpu_brand info.
base::CPU cpu_info;
@@ -204,42 +160,36 @@ void ContentMainDelegateQt::PreSandboxStartup()
}
}
-#if defined(OS_POSIX) && !defined(OS_ANDROID)
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
if (parsedCommandLine->HasSwitch(switches::kSingleProcess))
setlocale(LC_NUMERIC, "C");
#endif
- // from gpu_main.cc:
-#if BUILDFLAG(USE_VAAPI)
- media::VaapiWrapper::PreSandboxInitialization();
-#endif
-#if defined(OS_WIN)
- media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
- media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
+ bool isBrowserProcess = !parsedCommandLine->HasSwitch(switches::kProcessType);
+ if (isBrowserProcess) {
+ // from gpu_main.cc:
+#if BUILDFLAG(IS_WIN)
+ media::PreSandboxMediaFoundationInitialization();
#endif
-#if defined(OS_MAC)
- if (base::FeatureList::IsEnabled(features::kMacV2GPUSandbox)) {
- TRACE_EVENT0("gpu", "Initialize VideoToolbox");
- media::InitializeVideoToolbox();
- }
+#if BUILDFLAG(IS_MAC)
+ {
+ TRACE_EVENT0("gpu", "Initialize VideoToolbox");
+ media::InitializeVideoToolbox();
+ }
#endif
+ }
if (parsedCommandLine->HasSwitch(switches::kApplicationName)) {
std::string appName = parsedCommandLine->GetSwitchValueASCII(switches::kApplicationName);
appName = QByteArray::fromPercentEncoding(QByteArray::fromStdString(appName)).toStdString();
QCoreApplication::setApplicationName(QString::fromStdString(appName));
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
media::AudioManager::SetGlobalAppName(appName);
#endif
}
}
-void ContentMainDelegateQt::PostEarlyInitialization(bool)
-{
- PostFieldTrialInitialization();
-}
-
content::ContentClient *ContentMainDelegateQt::CreateContentClient()
{
return &m_contentClient;
@@ -259,7 +209,7 @@ content::ContentGpuClient *ContentMainDelegateQt::CreateContentGpuClient()
content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClient()
{
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
std::string process_type = parsedCommandLine->GetSwitchValueASCII(switches::kProcessType);
bool no_sandbox = parsedCommandLine->HasSwitch(sandbox::policy::switches::kNoSandbox);
@@ -301,10 +251,12 @@ static void SafeOverridePathImpl(const char *keyName, int key, const base::FileP
#define SafeOverridePath(KEY, PATH) SafeOverridePathImpl(#KEY, KEY, PATH)
-bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
+absl::optional<int> ContentMainDelegateQt::BasicStartupComplete()
{
SafeOverridePath(base::FILE_EXE, WebEngineLibraryInfo::getPath(base::FILE_EXE));
SafeOverridePath(base::DIR_QT_LIBRARY_DATA, WebEngineLibraryInfo::getPath(base::DIR_QT_LIBRARY_DATA));
+ SafeOverridePath(base::DIR_ASSETS, WebEngineLibraryInfo::getPath(base::DIR_ASSETS));
+ SafeOverridePath(base::DIR_EXE, WebEngineLibraryInfo::getPath(base::DIR_ASSETS));
SafeOverridePath(ui::DIR_LOCALES, WebEngineLibraryInfo::getPath(ui::DIR_LOCALES));
#if QT_CONFIG(webengine_spellchecker)
SafeOverridePath(base::DIR_APP_DICTIONARIES, WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES));
@@ -312,7 +264,7 @@ bool ContentMainDelegateQt::BasicStartupComplete(int *exit_code)
url::CustomScheme::LoadSchemes(base::CommandLine::ForCurrentProcess());
- return false;
+ return absl::nullopt;
}
} // namespace QtWebEngineCore
diff --git a/src/core/content_main_delegate_qt.h b/src/core/content_main_delegate_qt.h
index 170ccc3ca..a177bd6df 100644
--- a/src/core/content_main_delegate_qt.h
+++ b/src/core/content_main_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CONTENT_MAIN_DELEGATE_QT_H
#define CONTENT_MAIN_DELEGATE_QT_H
@@ -56,14 +20,13 @@ public:
// This is where the embedder puts all of its startup code that needs to run
// before the sandbox is engaged.
void PreSandboxStartup() override;
- void PostEarlyInitialization(bool) override;
content::ContentClient *CreateContentClient() override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentGpuClient* CreateContentGpuClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;
content::ContentUtilityClient* CreateContentUtilityClient() override;
- bool BasicStartupComplete(int* /*exit_code*/) override;
+ absl::optional<int> BasicStartupComplete() override;
private:
ContentClientQt m_contentClient;
diff --git a/src/core/content_utility_client_qt.cpp b/src/core/content_utility_client_qt.cpp
index f3b1e764d..7af90c7a1 100644
--- a/src/core/content_utility_client_qt.cpp
+++ b/src/core/content_utility_client_qt.cpp
@@ -1,48 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "content_utility_client_qt.h"
-#include "base/no_destructor.h"
#include "mojo/public/cpp/bindings/service_factory.h"
#include "services/proxy_resolver/proxy_resolver_factory_impl.h"
+#if BUILDFLAG(IS_WIN)
+#include "services/proxy_resolver_win/public/mojom/proxy_resolver_win.mojom.h"
+#include "services/proxy_resolver_win/windows_system_proxy_resolver_impl.h"
+#endif
+
namespace QtWebEngineCore {
ContentUtilityClientQt::ContentUtilityClientQt()
@@ -56,9 +24,21 @@ auto RunProxyResolver(mojo::PendingReceiver<proxy_resolver::mojom::ProxyResolver
return std::make_unique<proxy_resolver::ProxyResolverFactoryImpl>(std::move(receiver));
}
+#if BUILDFLAG(IS_WIN)
+auto RunWindowsSystemProxyResolver(
+ mojo::PendingReceiver<proxy_resolver_win::mojom::WindowsSystemProxyResolver> receiver)
+{
+ return std::make_unique<proxy_resolver_win::WindowsSystemProxyResolverImpl>(
+ std::move(receiver));
+}
+#endif
+
void ContentUtilityClientQt::RegisterIOThreadServices(mojo::ServiceFactory &services)
{
services.Add(RunProxyResolver);
+#if BUILDFLAG(IS_WIN)
+ services.Add(RunWindowsSystemProxyResolver);
+#endif
}
} // namespace
diff --git a/src/core/content_utility_client_qt.h b/src/core/content_utility_client_qt.h
index bcdf077f3..f2d287cf5 100644
--- a/src/core/content_utility_client_qt.h
+++ b/src/core/content_utility_client_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CONTENT_UTILITY_CLIENT_QT_H
#define CONTENT_UTILITY_CLIENT_QT_H
diff --git a/src/core/custom_handlers/protocol_handler_registry_delegate_qt.cpp b/src/core/custom_handlers/protocol_handler_registry_delegate_qt.cpp
new file mode 100644
index 000000000..a5074fb88
--- /dev/null
+++ b/src/core/custom_handlers/protocol_handler_registry_delegate_qt.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/custom_handlers/chrome_protocol_handler_registry_delegate.cc:
+// Copyright 2021 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 "protocol_handler_registry_delegate_qt.h"
+
+#include "content/public/browser/child_process_security_policy.h"
+#include "url/url_util_qt.h"
+
+namespace QtWebEngineCore {
+
+using content::ChildProcessSecurityPolicy;
+
+ProtocolHandlerRegistryDelegateQt::ProtocolHandlerRegistryDelegateQt() = default;
+
+ProtocolHandlerRegistryDelegateQt::~ProtocolHandlerRegistryDelegateQt() = default;
+
+// ProtocolHandlerRegistry::Delegate:
+void ProtocolHandlerRegistryDelegateQt::RegisterExternalHandler(const std::string &protocol)
+{
+ ChildProcessSecurityPolicy *policy = ChildProcessSecurityPolicy::GetInstance();
+ if (!policy->IsWebSafeScheme(protocol)) {
+ policy->RegisterWebSafeScheme(protocol);
+ }
+}
+
+bool ProtocolHandlerRegistryDelegateQt::IsExternalHandlerRegistered(const std::string &protocol)
+{
+ return url::IsHandledProtocol(protocol);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/custom_handlers/protocol_handler_registry_delegate_qt.h b/src/core/custom_handlers/protocol_handler_registry_delegate_qt.h
new file mode 100644
index 000000000..6a0753d22
--- /dev/null
+++ b/src/core/custom_handlers/protocol_handler_registry_delegate_qt.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/custom_handlers/chrome_protocol_handler_registry_delegate.h:
+// Copyright 2021 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.
+
+#ifndef PROTOCOL_HANDLER_REGISTRY_DELEGATE_QT_H_
+#define PROTOCOL_HANDLER_REGISTRY_DELEGATE_QT_H_
+
+#include <string>
+
+#include "components/custom_handlers/protocol_handler_registry.h"
+
+namespace QtWebEngineCore {
+
+// This class implements the ProtocolHandlerRegistry::Delegate
+// abstract class to provide an OS dependent implementation
+class ProtocolHandlerRegistryDelegateQt : public custom_handlers::ProtocolHandlerRegistry::Delegate {
+public:
+ ProtocolHandlerRegistryDelegateQt();
+ ~ProtocolHandlerRegistryDelegateQt() override;
+
+ ProtocolHandlerRegistryDelegateQt(const ProtocolHandlerRegistryDelegateQt &other) = delete;
+ ProtocolHandlerRegistryDelegateQt &operator=(const ProtocolHandlerRegistryDelegateQt &other) = delete;
+
+ // ProtocolHandlerRegistry::Delegate:
+ void RegisterExternalHandler(const std::string &protocol) override;
+ bool IsExternalHandlerRegistered(const std::string &protocol) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PROTOCOL_HANDLER_REGISTRY_DELEGATE_QT_H_
diff --git a/src/core/custom_handlers/protocol_handler_registry_factory.cpp b/src/core/custom_handlers/protocol_handler_registry_factory.cpp
new file mode 100644
index 000000000..50b17006b
--- /dev/null
+++ b/src/core/custom_handlers/protocol_handler_registry_factory.cpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/custom_handlers/protocol_handler_registry_factory.cc
+// 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 "protocol_handler_registry_factory.h"
+
+#include <memory>
+
+#include "base/memory/singleton.h"
+#include "components/custom_handlers/protocol_handler_registry.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+#include "protocol_handler_registry_delegate_qt.h"
+
+namespace QtWebEngineCore {
+
+// static
+ProtocolHandlerRegistryFactory *ProtocolHandlerRegistryFactory::GetInstance()
+{
+ return base::Singleton<ProtocolHandlerRegistryFactory>::get();
+}
+
+// static
+custom_handlers::ProtocolHandlerRegistry *ProtocolHandlerRegistryFactory::GetForBrowserContext(content::BrowserContext *context)
+{
+ return static_cast<custom_handlers::ProtocolHandlerRegistry *>(GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+ProtocolHandlerRegistryFactory::ProtocolHandlerRegistryFactory()
+ : BrowserContextKeyedServiceFactory("ProtocolHandlerRegistry", BrowserContextDependencyManager::GetInstance()) {}
+
+ProtocolHandlerRegistryFactory::~ProtocolHandlerRegistryFactory()
+{
+}
+
+// Will be created when initializing profile_io_data, so we might
+// as well have the framework create this along with other
+// PKSs to preserve orderly civic conduct :)
+bool ProtocolHandlerRegistryFactory::ServiceIsCreatedWithBrowserContext() const
+{
+ return true;
+}
+
+// Allows the produced registry to be used in incognito mode.
+content::BrowserContext *ProtocolHandlerRegistryFactory::GetBrowserContextToUse(content::BrowserContext *context) const
+{
+ return context;
+// return chrome::GetBrowserContextRedirectedInIncognito(context);
+}
+
+// Do not create this service for tests. MANY tests will fail
+// due to the threading requirements of this service. ALSO,
+// not creating this increases test isolation (which is GOOD!)
+bool ProtocolHandlerRegistryFactory::ServiceIsNULLWhileTesting() const
+{
+ return true;
+}
+
+KeyedService *ProtocolHandlerRegistryFactory::BuildServiceInstanceFor(content::BrowserContext *context) const
+{
+ custom_handlers::ProtocolHandlerRegistry *registry =
+ new custom_handlers::ProtocolHandlerRegistry(/*prefs*/ nullptr,
+ std::make_unique<ProtocolHandlerRegistryDelegateQt>());
+
+ // Must be called as a part of the creation process.
+ registry->InitProtocolSettings();
+
+ return registry;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/custom_handlers/protocol_handler_registry_factory.h b/src/core/custom_handlers/protocol_handler_registry_factory.h
new file mode 100644
index 000000000..6559addc0
--- /dev/null
+++ b/src/core/custom_handlers/protocol_handler_registry_factory.h
@@ -0,0 +1,57 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/custom_handlers/protocol_handler_registry_factory.h:
+// 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.
+
+#ifndef PROTOCOL_HANDLER_REGISTRY_FACTORY_H_
+#define PROTOCOL_HANDLER_REGISTRY_FACTORY_H_
+
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace custom_handlers {
+class ProtocolHandlerRegistry;
+}
+
+namespace base {
+template <typename T> struct DefaultSingletonTraits;
+}
+
+namespace QtWebEngineCore {
+
+// Singleton that owns all ProtocolHandlerRegistrys and associates them with
+// Profiles. Listens for the Profile's destruction notification and cleans up
+// the associated ProtocolHandlerRegistry.
+class ProtocolHandlerRegistryFactory : public BrowserContextKeyedServiceFactory {
+public:
+ // Returns the singleton instance of the ProtocolHandlerRegistryFactory.
+ static ProtocolHandlerRegistryFactory *GetInstance();
+
+ // Returns the ProtocolHandlerRegistry that provides intent registration for
+ // |context|. Ownership stays with this factory object.
+ static custom_handlers::ProtocolHandlerRegistry *GetForBrowserContext(content::BrowserContext *context);
+
+ ProtocolHandlerRegistryFactory(const ProtocolHandlerRegistryFactory &) = delete;
+ ProtocolHandlerRegistryFactory &operator=(const ProtocolHandlerRegistryFactory &) = delete;
+
+protected:
+ // BrowserContextKeyedServiceFactory implementation.
+ bool ServiceIsCreatedWithBrowserContext() const override;
+ content::BrowserContext *GetBrowserContextToUse(content::BrowserContext *context) const override;
+ bool ServiceIsNULLWhileTesting() const override;
+
+private:
+ friend struct base::DefaultSingletonTraits<ProtocolHandlerRegistryFactory>;
+
+ ProtocolHandlerRegistryFactory();
+ ~ProtocolHandlerRegistryFactory() override;
+
+ // BrowserContextKeyedServiceFactory implementation.
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *profile) const override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PROTOCOL_HANDLER_REGISTRY_FACTORY_H_
diff --git a/src/core/custom_handlers/register_protocol_handler_request_controller.h b/src/core/custom_handlers/register_protocol_handler_request_controller.h
new file mode 100644
index 000000000..6305ce5b7
--- /dev/null
+++ b/src/core/custom_handlers/register_protocol_handler_request_controller.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_H
+#define REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_H
+
+#include "request_controller.h"
+
+namespace QtWebEngineCore {
+
+class RegisterProtocolHandlerRequestController : public RequestController {
+public:
+ RegisterProtocolHandlerRequestController(QUrl origin, QString scheme)
+ : RequestController(std::move(origin))
+ , m_scheme(std::move(scheme))
+ {}
+
+ QString scheme() const { return m_scheme; }
+
+private:
+ QString m_scheme;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_H
diff --git a/src/core/custom_handlers/register_protocol_handler_request_controller_impl.cpp b/src/core/custom_handlers/register_protocol_handler_request_controller_impl.cpp
new file mode 100644
index 000000000..efaf54cd2
--- /dev/null
+++ b/src/core/custom_handlers/register_protocol_handler_request_controller_impl.cpp
@@ -0,0 +1,49 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "custom_handlers/register_protocol_handler_request_controller_impl.h"
+
+#include "components/custom_handlers/protocol_handler_registry.h"
+#include "content/public/browser/web_contents.h"
+
+#include "custom_handlers/protocol_handler_registry_factory.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+RegisterProtocolHandlerRequestControllerImpl::RegisterProtocolHandlerRequestControllerImpl(
+ content::WebContents *webContents,
+ custom_handlers::ProtocolHandler handler)
+ : RegisterProtocolHandlerRequestController(
+ toQt(handler.url()),
+ toQt(handler.protocol()))
+ , content::WebContentsObserver(webContents)
+ , m_handler(handler)
+{}
+
+RegisterProtocolHandlerRequestControllerImpl::~RegisterProtocolHandlerRequestControllerImpl()
+{
+ reject();
+}
+
+custom_handlers::ProtocolHandlerRegistry *RegisterProtocolHandlerRequestControllerImpl::protocolHandlerRegistry()
+{
+ content::WebContents *webContents = web_contents();
+ if (!webContents)
+ return nullptr;
+ content::BrowserContext *context = webContents->GetBrowserContext();
+ return ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
+}
+
+void RegisterProtocolHandlerRequestControllerImpl::accepted()
+{
+ if (custom_handlers::ProtocolHandlerRegistry *registry = protocolHandlerRegistry())
+ registry->OnAcceptRegisterProtocolHandler(m_handler);
+}
+
+void RegisterProtocolHandlerRequestControllerImpl::rejected()
+{
+ if (custom_handlers::ProtocolHandlerRegistry *registry = protocolHandlerRegistry())
+ registry->OnIgnoreRegisterProtocolHandler(m_handler);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/custom_handlers/register_protocol_handler_request_controller_impl.h b/src/core/custom_handlers/register_protocol_handler_request_controller_impl.h
new file mode 100644
index 000000000..073ca9bf8
--- /dev/null
+++ b/src/core/custom_handlers/register_protocol_handler_request_controller_impl.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_IMPL_H
+#define REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_IMPL_H
+
+#include "register_protocol_handler_request_controller.h"
+
+#include "content/public/browser/web_contents_observer.h"
+#include "components/custom_handlers/protocol_handler.h"
+
+namespace custom_handlers {
+class ProtocolHandlerRegistry;
+}
+
+namespace QtWebEngineCore {
+
+class RegisterProtocolHandlerRequestControllerImpl final : public RegisterProtocolHandlerRequestController,
+ private content::WebContentsObserver {
+public:
+ RegisterProtocolHandlerRequestControllerImpl(
+ content::WebContents *webContents,
+ custom_handlers::ProtocolHandler handler);
+
+ ~RegisterProtocolHandlerRequestControllerImpl();
+
+protected:
+ void accepted() override;
+ void rejected() override;
+
+private:
+ custom_handlers::ProtocolHandlerRegistry *protocolHandlerRegistry();
+ custom_handlers::ProtocolHandler m_handler;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_IMPL_H
diff --git a/src/core/delegated_frame_host_client_qt.cpp b/src/core/delegated_frame_host_client_qt.cpp
index e10ff9dd3..ad1de91f6 100644
--- a/src/core/delegated_frame_host_client_qt.cpp
+++ b/src/core/delegated_frame_host_client_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "delegated_frame_host_client_qt.h"
@@ -65,7 +29,7 @@ void DelegatedFrameHostClientQt::OnFrameTokenChanged(uint32_t frame_token, base:
float DelegatedFrameHostClientQt::GetDeviceScaleFactor() const
{
- return p->m_screenInfo.device_scale_factor;
+ return p->GetScreenInfo().device_scale_factor;
}
void DelegatedFrameHostClientQt::InvalidateLocalSurfaceIdOnEviction()
diff --git a/src/core/delegated_frame_host_client_qt.h b/src/core/delegated_frame_host_client_qt.h
index f9bc99d24..184b84d7a 100644
--- a/src/core/delegated_frame_host_client_qt.h
+++ b/src/core/delegated_frame_host_client_qt.h
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DELEGATED_FRAME_HOST_CLIENT_QT_H
#define DELEGATED_FRAME_HOST_CLIENT_QT_H
-#include "qtwebenginecoreglobal_p.h"
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include "content/browser/renderer_host/delegated_frame_host.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
diff --git a/src/core/desktop_media_controller.cpp b/src/core/desktop_media_controller.cpp
new file mode 100644
index 000000000..50ac0a40c
--- /dev/null
+++ b/src/core/desktop_media_controller.cpp
@@ -0,0 +1,244 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "desktop_media_controller.h"
+#include "desktop_media_controller_p.h"
+#include "type_conversion.h"
+
+#include "base/containers/contains.h"
+#include "base/functional/callback.h"
+#include "chrome/browser/media/webrtc/desktop_capturer_wrapper.h"
+#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
+#include "content/public/browser/desktop_media_id.h"
+
+#if QT_CONFIG(webengine_webrtc)
+#include "content/public/browser/desktop_capture.h"
+#endif // QT_CONFIG(webengine_webrtc)
+
+namespace QtWebEngineCore {
+namespace {
+DesktopMediaList::Type toMediaListType(DesktopMediaType type)
+{
+ switch (type) {
+ case DesktopMediaType::Screen:
+ return DesktopMediaList::Type::kScreen;
+ case DesktopMediaType::Window:
+ return DesktopMediaList::Type::kWindow;
+ default:
+ return DesktopMediaList::Type::kNone;
+ }
+}
+
+std::unique_ptr<DesktopMediaList> createMediaList(DesktopMediaType type)
+{
+#if QT_CONFIG(webengine_webrtc)
+ DesktopMediaList::Type listType = toMediaListType(type);
+ webrtc::DesktopCaptureOptions options = content::desktop_capture::CreateDesktopCaptureOptions();
+
+ switch (listType) {
+ case DesktopMediaList::Type::kScreen: {
+ std::unique_ptr<webrtc::DesktopCapturer> screenCapturer =
+ webrtc::DesktopCapturer::CreateScreenCapturer(options);
+ std::unique_ptr<DesktopCapturerWrapper> capturer =
+ std::make_unique<DesktopCapturerWrapper>(std::move(screenCapturer));
+ return std::make_unique<NativeDesktopMediaList>(listType, std::move(capturer));
+ }
+ case DesktopMediaList::Type::kWindow: {
+ std::unique_ptr<webrtc::DesktopCapturer> windowCapturer =
+ webrtc::DesktopCapturer::CreateWindowCapturer(options);
+ std::unique_ptr<DesktopCapturerWrapper> capturer =
+ std::make_unique<DesktopCapturerWrapper>(std::move(windowCapturer));
+ return std::make_unique<NativeDesktopMediaList>(
+ listType, std::move(capturer),
+ !content::desktop_capture::ShouldEnumerateCurrentProcessWindows());
+ }
+ default: {
+ Q_UNREACHABLE();
+ }
+ }
+#else
+ return nullptr;
+#endif // QT_CONFIG(webengine_webrtc)
+}
+} // namespace
+
+class DesktopMediaListQtPrivate : public DesktopMediaListObserver
+{
+public:
+ DesktopMediaListQtPrivate(DesktopMediaType type, DesktopMediaListQt *qq);
+
+ void init();
+ void startUpdating();
+ const DesktopMediaList::Source& getSource(int index) const;
+
+ void OnSourceAdded(int index) override;
+ void OnSourceRemoved(int index) override;
+ void OnSourceMoved(int old_index, int new_index) override;
+ void OnSourceNameChanged(int index) override;
+ void OnSourceThumbnailChanged(int index) override { }
+ void OnSourcePreviewChanged(size_t index) override { }
+ void OnDelegatedSourceListSelection() override { }
+ void OnDelegatedSourceListDismissed() override { }
+
+ bool isInitialized;
+ std::unique_ptr<DesktopMediaList> mediaList;
+ DesktopMediaListQt *q_ptr;
+ Q_DECLARE_PUBLIC(DesktopMediaListQt)
+};
+
+DesktopMediaListQtPrivate::DesktopMediaListQtPrivate(DesktopMediaType type, DesktopMediaListQt *qq)
+ : isInitialized(false)
+ , mediaList(createMediaList(type))
+ , q_ptr(qq)
+{
+}
+
+const DesktopMediaList::Source& DesktopMediaListQtPrivate::getSource(int index) const
+{
+ return mediaList->GetSource(index);
+}
+
+void DesktopMediaListQtPrivate::init()
+{
+ // Work around the asynchronous initialization of the source list.
+ // DesktopMediaList::Update populates the list and notifies the controller when it completes.
+ // This makes direct 'selectScreen/Window' calls possible from the frontend.
+ // Note: StartUpdating should be called after Update is completed as it can overwrite the
+ // internal cb.
+ base::OnceCallback<void()> onComplete = base::BindOnce(
+ [](DesktopMediaListQtPrivate *observer) {
+ observer->isInitialized = true;
+ Q_EMIT observer->q_ptr->initialized();
+ observer->startUpdating();
+ },
+ this);
+ mediaList->Update(std::move(onComplete));
+}
+
+void DesktopMediaListQtPrivate::startUpdating()
+{
+ mediaList->StartUpdating(this);
+}
+
+void DesktopMediaListQtPrivate::OnSourceAdded(int index)
+{
+ Q_Q(DesktopMediaListQt);
+ Q_EMIT q->sourceAdded(index);
+}
+
+void DesktopMediaListQtPrivate::OnSourceRemoved(int index)
+{
+ Q_Q(DesktopMediaListQt);
+ Q_EMIT q->sourceRemoved(index);
+}
+
+void DesktopMediaListQtPrivate::OnSourceMoved(int old_index, int new_index)
+{
+ Q_Q(DesktopMediaListQt);
+ Q_EMIT q->sourceMoved(old_index, new_index);
+}
+
+void DesktopMediaListQtPrivate::OnSourceNameChanged(int index)
+{
+ Q_Q(DesktopMediaListQt);
+ Q_EMIT q->sourceNameChanged(index);
+}
+
+DesktopMediaListQt::DesktopMediaListQt(DesktopMediaType type)
+ : d(new DesktopMediaListQtPrivate(type, this))
+{
+}
+
+DesktopMediaListQt::~DesktopMediaListQt() { }
+
+QString DesktopMediaListQt::getSourceName(int index) const
+{
+ const auto &source = d->getSource(index);
+ return toQt(source.name);
+}
+
+int DesktopMediaListQt::getSourceCount() const
+{
+ return d->mediaList->GetSourceCount();
+}
+
+bool DesktopMediaListQt::isInitialized() const
+{
+ return d->isInitialized;
+}
+
+DesktopMediaControllerPrivate::DesktopMediaControllerPrivate(
+ base::OnceCallback<void(content::DesktopMediaID)> doneCallback)
+ : doneCallback(std::move(doneCallback))
+ , screens(new DesktopMediaListQt(DesktopMediaType::Screen))
+ , windows(new DesktopMediaListQt(DesktopMediaType::Window))
+{
+}
+
+void DesktopMediaControllerPrivate::selectScreen(int index)
+{
+ const auto &source = screens->d->getSource(index);
+ std::move(doneCallback).Run(source.id);
+}
+
+void DesktopMediaControllerPrivate::selectWindow(int index)
+{
+ const auto &source = windows->d->getSource(index);
+ std::move(doneCallback).Run(source.id);
+}
+
+void DesktopMediaControllerPrivate::cancel()
+{
+ std::move(doneCallback).Run({});
+}
+
+DesktopMediaController::DesktopMediaController(DesktopMediaControllerPrivate *dd)
+ : d(dd)
+{
+ // Make sure both lists are populated before sending the request.
+ DesktopMediaListQt *screens = DesktopMediaController::screens();
+ DesktopMediaListQt *windows = DesktopMediaController::windows();
+ QObject::connect(screens, &DesktopMediaListQt::initialized, [windows, this]() {
+ if (windows->isInitialized())
+ Q_EMIT mediaListsInitialized();
+ });
+
+ QObject::connect(windows, &DesktopMediaListQt::initialized, [screens, this]() {
+ if (screens->isInitialized())
+ Q_EMIT mediaListsInitialized();
+ });
+
+ screens->d->init();
+ windows->d->init();
+}
+
+DesktopMediaController::~DesktopMediaController()
+{
+}
+
+void DesktopMediaController::selectScreen(int index)
+{
+ d->selectScreen(index);
+}
+
+void DesktopMediaController::selectWindow(int index)
+{
+ d->selectWindow(index);
+}
+
+void DesktopMediaController::cancel()
+{
+ d->cancel();
+}
+
+DesktopMediaListQt *DesktopMediaController::screens() const
+{
+ return d->screens.data();
+}
+
+DesktopMediaListQt *DesktopMediaController::windows() const
+{
+ return d->windows.data();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/desktop_media_controller.h b/src/core/desktop_media_controller.h
new file mode 100644
index 000000000..0cb741225
--- /dev/null
+++ b/src/core/desktop_media_controller.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef DESKTOP_MEDIA_CONTROLLER_H
+#define DESKTOP_MEDIA_CONTROLLER_H
+
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtCore/QObject>
+
+#include <QString>
+
+namespace QtWebEngineCore {
+class DesktopMediaListQtPrivate;
+class DesktopMediaControllerPrivate;
+
+enum DesktopMediaType { Screen = 0, Window };
+
+class Q_WEBENGINECORE_EXPORT DesktopMediaListQt : public QObject
+{
+ Q_OBJECT
+public:
+ ~DesktopMediaListQt() override;
+
+ QString getSourceName(int index) const;
+ int getSourceCount() const;
+
+Q_SIGNALS:
+ void initialized();
+ void itemSelected(int index);
+ void sourceAdded(int index);
+ void sourceRemoved(int index);
+ void sourceMoved(int oldIndex, int newIndex);
+ void sourceNameChanged(int index);
+
+private:
+ friend class DesktopMediaController;
+ friend class DesktopMediaControllerPrivate;
+ bool isInitialized() const;
+ explicit DesktopMediaListQt(DesktopMediaType type);
+ std::unique_ptr<DesktopMediaListQtPrivate> d;
+};
+
+class Q_WEBENGINECORE_EXPORT DesktopMediaController : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DesktopMediaController(DesktopMediaControllerPrivate *dd);
+ ~DesktopMediaController() override;
+
+ DesktopMediaListQt *screens() const;
+ DesktopMediaListQt *windows() const;
+
+ void selectScreen(int index);
+ void selectWindow(int index);
+ void cancel();
+
+Q_SIGNALS:
+ void mediaListsInitialized();
+
+private:
+ std::unique_ptr<DesktopMediaControllerPrivate> d;
+};
+
+} // namespace QtWebEngineCore
+#endif // DESKTOP_MEDIA_CONTROLLER_H
diff --git a/src/core/desktop_media_controller_p.h b/src/core/desktop_media_controller_p.h
new file mode 100644
index 000000000..4bb3a6312
--- /dev/null
+++ b/src/core/desktop_media_controller_p.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef DESKTOP_MEDIA_CONTROLLER_P_H
+#define DESKTOP_MEDIA_CONTROLLER_P_H
+
+#include <QtCore/QObject>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+
+#include "content/public/browser/desktop_media_id.h"
+#include "base/functional/callback.h"
+
+namespace QtWebEngineCore {
+class Q_WEBENGINECORE_EXPORT DesktopMediaControllerPrivate
+{
+public:
+ DesktopMediaControllerPrivate(base::OnceCallback<void(content::DesktopMediaID)> doneCallback);
+ void selectScreen(int index);
+ void selectWindow(int index);
+ void cancel();
+ base::OnceCallback<void(content::DesktopMediaID)> doneCallback;
+ QScopedPointer<DesktopMediaListQt> screens;
+ QScopedPointer<DesktopMediaListQt> windows;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // DESKTOP_MEDIA_CONTROLLER_P_H
diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp
index fd7a2c54f..fb68f7b09 100644
--- a/src/core/desktop_screen_qt.cpp
+++ b/src/core/desktop_screen_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "desktop_screen_qt.h"
@@ -46,6 +10,15 @@
#include <QGuiApplication>
#include <QScreen>
+#if defined(USE_OZONE)
+#include "ui/ozone/buildflags.h"
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+#define USE_XSCREENSAVER
+#include "ui/base/x/x11_screensaver.h"
+#include "ui/base/x/x11_util.h"
+#endif
+#endif
+
#include <cmath>
namespace QtWebEngineCore {
@@ -69,12 +42,21 @@ display::Display toDisplayDisplay(int id, const QScreen *screen)
{
auto display = display::Display(id, toGfx(screen->geometry()));
display.set_work_area(toGfx(screen->availableGeometry()));
- display.set_device_scale_factor(screen->devicePixelRatio());
display.set_is_monochrome(screen->depth() == 1);
display.set_color_depth(screen->depth());
display.set_depth_per_component(8); // FIXME: find the real value
display.set_display_frequency(std::ceil(screen->refreshRate()));
display.set_rotation(toDisplayRotation(screen->orientation()));
+
+ // FIXME: support lower scale factor
+ float pixelRatio = screen->devicePixelRatio();
+ if (pixelRatio < 1) {
+ qWarning("Unsupported scale factor (%f) detected on Display%d", pixelRatio, id);
+ display.set_device_scale_factor(qGuiApp->devicePixelRatio());
+ } else {
+ display.set_device_scale_factor(pixelRatio);
+ }
+
if (screen->nativeOrientation() != Qt::PrimaryOrientation)
display.set_panel_rotation(toDisplayRotation(screen->nativeOrientation()));
return display;
@@ -87,7 +69,7 @@ DesktopScreenQt::DesktopScreenQt()
DesktopScreenQt::~DesktopScreenQt()
{
- for (auto conn : qAsConst(m_connections))
+ for (auto conn : std::as_const(m_connections))
QObject::disconnect(conn);
}
@@ -137,4 +119,38 @@ display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow /*wi
return GetPrimaryDisplay();
}
+#if defined(USE_XSCREENSAVER)
+class XScreenSuspender : public display::Screen::ScreenSaverSuspender
+{
+public:
+ XScreenSuspender()
+ {
+ ui::SuspendX11ScreenSaver(true);
+ }
+ ~XScreenSuspender() override
+ {
+ ui::SuspendX11ScreenSaver(false);
+ }
+};
+#endif
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
+std::unique_ptr<display::Screen::ScreenSaverSuspender> DesktopScreenQt::SuspendScreenSaver()
+{
+#if defined(USE_XSCREENSAVER)
+ return std::make_unique<XScreenSuspender>();
+#else
+ return nullptr;
+#endif
+}
+#endif
+
+bool DesktopScreenQt::IsScreenSaverActive() const
+{
+#if defined(USE_XSCREENSAVER)
+ return ui::IsXScreensaverActive();
+#else
+ return false;
+#endif
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/desktop_screen_qt.h b/src/core/desktop_screen_qt.h
index 1b2e095a4..a322c4840 100644
--- a/src/core/desktop_screen_qt.h
+++ b/src/core/desktop_screen_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DESKTOP_SCREEN_QT_H
#define DESKTOP_SCREEN_QT_H
@@ -53,6 +17,10 @@ public:
~DesktopScreenQt() override;
display::Display GetDisplayNearestWindow(gfx::NativeWindow /*window*/) const override;
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
+ std::unique_ptr<ScreenSaverSuspender> SuspendScreenSaver() override;
+#endif
+ bool IsScreenSaverActive() const override;
private:
void initializeScreens();
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index 9a7736964..7cea68390 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on content/shell/browser/shell_devtools_frontend.cc:
// Copyright 2013 The Chromium Authors. All rights reserved.
@@ -44,164 +8,44 @@
#include "devtools_frontend_qt.h"
-#include "profile_adapter.h"
#include "profile_qt.h"
#include "web_contents_adapter.h"
+#include "web_contents_delegate_qt.h"
-#include "base/base64.h"
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/json/string_escape.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
-#include "base/values.h"
#include "chrome/browser/devtools/devtools_eye_dropper.h"
-#include "chrome/common/url_constants.h"
-#include "components/prefs/in_memory_pref_store.h"
-#include "components/prefs/json_pref_store.h"
+#include "chrome/browser/devtools/devtools_ui_bindings.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/file_url_loader.h"
+#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/shared_cors_origin_access_list.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/url_constants.h"
-#include "content/public/common/url_utils.h"
-#include "ipc/ipc_channel.h"
-#include "net/http/http_response_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/simple_url_loader.h"
-#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
+#include "content/public/browser/page_navigator.h"
+#include "content/public/browser/site_instance.h"
+#include "url/gurl.h"
using namespace QtWebEngineCore;
namespace {
-
-constexpr char kScreencastEnabled[] = "screencastEnabled";
-
-std::unique_ptr<base::DictionaryValue> BuildObjectForResponse(const net::HttpResponseHeaders *rh,
- bool success,
- int net_error)
-{
- auto response = std::make_unique<base::DictionaryValue>();
- int responseCode = 200;
- if (rh) {
- responseCode = rh->response_code();
- } else if (!success) {
- // In case of no headers, assume file:// URL and failed to load
- responseCode = 404;
- }
- response->SetInteger("statusCode", responseCode);
- response->SetInteger("netError", net_error);
- response->SetString("netErrorName", net::ErrorToString(net_error));
-
- auto headers = std::make_unique<base::DictionaryValue>();
- size_t iterator = 0;
- std::string name;
- std::string value;
- // TODO(caseq): this probably needs to handle duplicate header names
- // correctly by folding them.
- while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
- headers->SetString(name, value);
-
- response->Set("headers", std::move(headers));
- return response;
-}
+static const char kScreencastEnabled[] = "screencastEnabled";
static std::string GetFrontendURL()
{
return "devtools://devtools/bundled/inspector.html";
}
-
-} // namespace
+} // namespace
namespace QtWebEngineCore {
-class DevToolsFrontendQt::NetworkResourceLoader
- : public network::SimpleURLLoaderStreamConsumer {
-public:
- NetworkResourceLoader(int stream_id,
- int request_id,
- DevToolsFrontendQt *bindings,
- std::unique_ptr<network::SimpleURLLoader> loader,
- network::mojom::URLLoaderFactory *url_loader_factory)
- : stream_id_(stream_id),
- request_id_(request_id),
- bindings_(bindings),
- loader_(std::move(loader))
- {
- loader_->SetOnResponseStartedCallback(base::BindOnce(
- &NetworkResourceLoader::OnResponseStarted, base::Unretained(this)));
- loader_->DownloadAsStream(url_loader_factory, this);
- }
-
-private:
- void OnResponseStarted(const GURL &final_url,
- const network::mojom::URLResponseHead &response_head)
- {
- response_headers_ = response_head.headers;
- }
-
- void OnDataReceived(base::StringPiece chunk, base::OnceClosure resume) override
- {
- base::Value chunkValue;
-
- bool encoded = !base::IsStringUTF8(chunk);
- if (encoded) {
- std::string encoded_string;
- base::Base64Encode(chunk, &encoded_string);
- chunkValue = base::Value(std::move(encoded_string));
- } else {
- chunkValue = base::Value(chunk);
- }
- base::Value id(stream_id_);
- base::Value encodedValue(encoded);
-
- bindings_->CallClientFunction("DevToolsAPI.streamWrite", &id, &chunkValue, &encodedValue);
- std::move(resume).Run();
- }
-
- void OnComplete(bool success) override
- {
- auto response = BuildObjectForResponse(response_headers_.get(), success, loader_->NetError());
- bindings_->SendMessageAck(request_id_, response.get());
- bindings_->m_loaders.erase(bindings_->m_loaders.find(this));
- }
-
- void OnRetry(base::OnceClosure start_retry) override { NOTREACHED(); }
-
- const int stream_id_;
- const int request_id_;
- DevToolsFrontendQt *const bindings_;
- std::unique_ptr<network::SimpleURLLoader> loader_;
- scoped_refptr<net::HttpResponseHeaders> response_headers_;
-
- DISALLOW_COPY_AND_ASSIGN(NetworkResourceLoader);
-};
-
-// This constant should be in sync with
-// the constant at devtools_ui_bindings.cc.
-const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
-
// static
-DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter> frontendAdapter, content::WebContents *inspectedContents)
+DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter> frontendAdapter,
+ content::WebContents *inspectedContents)
{
DCHECK(frontendAdapter);
DCHECK(inspectedContents);
if (!frontendAdapter->isInitialized()) {
- scoped_refptr<content::SiteInstance> site =
- content::SiteInstance::CreateForURL(frontendAdapter->profile(), GURL(GetFrontendURL()));
+ scoped_refptr<content::SiteInstance> site = content::SiteInstance::CreateForURL(
+ frontendAdapter->profile(), GURL(GetFrontendURL()));
frontendAdapter->initialize(site.get());
}
@@ -213,13 +57,15 @@ DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter>
return nullptr;
}
- DevToolsFrontendQt *devtoolsFrontend = new DevToolsFrontendQt(frontendAdapter, inspectedContents);
+ DevToolsFrontendQt *devtoolsFrontend =
+ new DevToolsFrontendQt(frontendAdapter, inspectedContents);
if (contents->GetURL() == GURL(GetFrontendURL())) {
- contents->GetController().Reload(content::ReloadType::ORIGINAL_REQUEST_URL, false);
- } else {
+ contents->GetController().LoadOriginalRequestURL();
+ } else {
content::NavigationController::LoadURLParams loadParams((GURL(GetFrontendURL())));
- loadParams.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_TOPLEVEL | ui::PAGE_TRANSITION_FROM_API);
+ loadParams.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_TOPLEVEL
+ | ui::PAGE_TRANSITION_FROM_API);
contents->GetController().LoadURLWithParams(loadParams);
}
@@ -230,24 +76,22 @@ DevToolsFrontendQt::DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webCon
content::WebContents *inspectedContents)
: content::WebContentsObserver(webContentsAdapter->webContents())
, m_frontendAdapter(webContentsAdapter)
- , m_inspectedAdapter(static_cast<WebContentsDelegateQt *>(inspectedContents->GetDelegate())
- ->webContentsAdapter())
, m_inspectedContents(inspectedContents)
- , m_inspect_element_at_x(-1)
- , m_inspect_element_at_y(-1)
- , m_prefStore(nullptr)
- , m_weakFactory(this)
+ , m_outermostContents(inspectedContents->GetOutermostWebContents())
+ , m_bindings(new DevToolsUIBindings(webContentsAdapter->webContents()))
{
- // We use a separate prefstore than one in ProfileQt, because that one is in-memory only, and this
- // needs to be stored or it will show introduction text on every load.
- if (webContentsAdapter->profileAdapter()->isOffTheRecord())
- m_prefStore = scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore());
- else
- CreateJsonPreferences(false);
-
- m_frontendDelegate = static_cast<WebContentsDelegateQt *>(webContentsAdapter->webContents()->GetDelegate());
-}
+ // bindings take ownership over devtools
+ m_bindings->SetDelegate(this);
+ m_bindings->AttachTo(content::DevToolsAgentHost::GetOrCreateFor(m_inspectedContents));
+
+ auto *prefService = m_bindings->profile()->GetPrefs();
+ const auto &devtoolsPrefs = prefService->GetDict(prefs::kDevToolsPreferences);
+ if (!devtoolsPrefs.Find(kScreencastEnabled)) {
+ ScopedDictPrefUpdate update(prefService, prefs::kDevToolsPreferences);
+ update->Set(kScreencastEnabled, "false");
+ }
+}
DevToolsFrontendQt::~DevToolsFrontendQt()
{
@@ -257,7 +101,7 @@ DevToolsFrontendQt::~DevToolsFrontendQt()
void DevToolsFrontendQt::Activate()
{
- m_frontendDelegate->ActivateContents(web_contents());
+ web_contents()->GetDelegate()->ActivateContents(web_contents());
}
void DevToolsFrontendQt::Focus()
@@ -267,12 +111,11 @@ void DevToolsFrontendQt::Focus()
void DevToolsFrontendQt::InspectElementAt(int x, int y)
{
- if (m_agentHost)
- m_agentHost->InspectElement(m_inspectedContents->GetFocusedFrame(), x, y);
- else {
- m_inspect_element_at_x = x;
- m_inspect_element_at_y = y;
- }
+ if (!m_inspectedContents)
+ return;
+ scoped_refptr<content::DevToolsAgentHost> agent(
+ content::DevToolsAgentHost::GetOrCreateFor(m_inspectedContents));
+ agent->InspectElement(m_inspectedContents->GetFocusedFrame(), x, y);
}
void DevToolsFrontendQt::Close()
@@ -283,275 +126,56 @@ void DevToolsFrontendQt::Close()
void DevToolsFrontendQt::DisconnectFromTarget()
{
- if (!m_agentHost)
- return;
- m_agentHost->DetachClient(this);
- m_agentHost = nullptr;
+ m_bindings->Detach();
}
-void DevToolsFrontendQt::ReadyToCommitNavigation(content::NavigationHandle *navigationHandle)
+WebContentsDelegateQt *DevToolsFrontendQt::frontendDelegate() const
{
- // ShellDevToolsFrontend does this in RenderViewCreated,
- // but that doesn't work for us for some reason.
- content::RenderFrameHost *frame = navigationHandle->GetRenderFrameHost();
- if (navigationHandle->IsInMainFrame()) {
- // If the frontend for some reason goes to some place other than devtools, stop the bindings
- if (navigationHandle->GetURL() != GetFrontendURL())
- m_frontendHost.reset(nullptr);
- else if (!m_frontendHost)
- m_frontendHost = content::DevToolsFrontendHost::Create(
- frame,
- base::Bind(&DevToolsFrontendQt::HandleMessageFromDevToolsFrontend,
- base::Unretained(this)));
- }
+ return static_cast<WebContentsDelegateQt *>(web_contents()->GetDelegate());
}
-void DevToolsFrontendQt::DocumentAvailableInMainFrame()
+void DevToolsFrontendQt::ColorPickedInEyeDropper(int r, int g, int b, int a)
{
- if (!m_inspectedContents)
- return;
- // Don't call AttachClient multiple times for the same DevToolsAgentHost.
- // Otherwise it will call AgentHostClosed which closes the DevTools window.
- // This may happen in cases where the DevTools content fails to load.
- scoped_refptr<content::DevToolsAgentHost> agent_host =
- content::DevToolsAgentHost::GetOrCreateFor(m_inspectedContents);
- if (agent_host != m_agentHost) {
- if (m_agentHost)
- m_agentHost->DetachClient(this);
- m_agentHost = agent_host;
- m_agentHost->AttachClient(this);
- if (m_inspect_element_at_x != -1) {
- m_agentHost->InspectElement(m_inspectedContents->GetFocusedFrame(), m_inspect_element_at_x, m_inspect_element_at_y);
- m_inspect_element_at_x = -1;
- m_inspect_element_at_y = -1;
- }
- }
+ base::Value::Dict color;
+ color.Set("r", r);
+ color.Set("g", g);
+ color.Set("b", b);
+ color.Set("a", a);
+ m_bindings->CallClientMethod("DevToolsAPI", "eyeDropperPickedColor", base::Value(std::move(color)));
}
+// content::WebContentsObserver implementation
void DevToolsFrontendQt::WebContentsDestroyed()
{
- if (m_inspectedAdapter)
- m_inspectedAdapter->devToolsFrontendDestroyed(this);
-
- if (m_agentHost) {
- m_agentHost->DetachClient(this);
- m_agentHost = nullptr;
- }
- delete this;
-}
+ // If m_inspectedContents was a guest view it was probably already destroyed,
+ // but its embedder still lives.
+ WebContentsAdapter *inspectedAdapter =
+ static_cast<WebContentsDelegateQt *>(m_outermostContents->GetDelegate())
+ ->webContentsAdapter();
+ if (inspectedAdapter)
+ inspectedAdapter->devToolsFrontendDestroyed(this);
-void DevToolsFrontendQt::SetPreference(const std::string &name, const std::string &value)
-{
- DCHECK(m_prefStore);
- m_prefStore->SetValue(name, base::WrapUnique(new base::Value(value)), 0);
+ delete m_bindings; // it will call ~DevToolsFrontendQt()
}
-void DevToolsFrontendQt::RemovePreference(const std::string &name)
+// DevToolsUIBindings::Delegate implementation
+void DevToolsFrontendQt::ActivateWindow()
{
- DCHECK(m_prefStore);
- m_prefStore->RemoveValue(name, 0);
-}
-
-void DevToolsFrontendQt::ClearPreferences()
-{
- ProfileQt *profile = static_cast<ProfileQt *>(web_contents()->GetBrowserContext());
- if (profile->IsOffTheRecord() || profile->profileAdapter()->storageName().isEmpty())
- m_prefStore = scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore());
- else
- CreateJsonPreferences(true);
+ web_contents()->Focus();
}
-void DevToolsFrontendQt::CreateJsonPreferences(bool clear)
+void DevToolsFrontendQt::OnLoadCompleted()
{
- content::BrowserContext *browserContext = web_contents()->GetBrowserContext();
- DCHECK(!browserContext->IsOffTheRecord());
- JsonPrefStore *jsonPrefStore = new JsonPrefStore(
- browserContext->GetPath().Append(FILE_PATH_LITERAL("devtoolsprefs.json")));
- // We effectively clear the preferences by not calling ReadPrefs
- if (!clear)
- jsonPrefStore->ReadPrefs();
-
- m_prefStore = scoped_refptr<PersistentPrefStore>(jsonPrefStore);
+ m_bindings->CallClientMethod("DevToolsAPI", "setUseSoftMenu", base::Value(true));
}
-void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &message)
+void DevToolsFrontendQt::OpenInNewTab(const std::string &url)
{
- if (!m_agentHost)
- return;
- std::string method;
- base::ListValue *params = nullptr;
- base::DictionaryValue *dict = nullptr;
- std::unique_ptr<base::Value> parsed_message = base::JSONReader::ReadDeprecated(message);
- if (!parsed_message || !parsed_message->GetAsDictionary(&dict) || !dict->GetString("method", &method))
- return;
- int request_id = 0;
- dict->GetInteger("id", &request_id);
- dict->GetList("params", &params);
-
- if (method == "dispatchProtocolMessage" && params && params->GetSize() == 1) {
- std::string protocol_message;
- if (!params->GetString(0, &protocol_message))
- return;
- m_agentHost->DispatchProtocolMessage(this, base::as_bytes(base::make_span(protocol_message)));
- } else if (method == "loadCompleted") {
- web_contents()->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);"),
- base::NullCallback());
- } else if (method == "loadNetworkResource" && params->GetSize() == 3) {
- // TODO(pfeldman): handle some of the embedder messages in content.
- std::string url;
- std::string headers;
- int stream_id;
- if (!params->GetString(0, &url) || !params->GetString(1, &headers) || !params->GetInteger(2, &stream_id))
- return;
-
- GURL gurl(url);
- if (!gurl.is_valid()) {
- base::DictionaryValue response;
- response.SetInteger("statusCode", 404);
- response.SetBoolean("urlValid", false);
- SendMessageAck(request_id, &response);
- return;
- }
-
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation(
- "devtools_handle_front_end_messages", R"(
- semantics {
- sender: "Developer Tools"
- description:
- "When user opens Developer Tools, the browser may fetch "
- "additional resources from the network to enrich the debugging "
- "experience (e.g. source map resources)."
- trigger: "User opens Developer Tools to debug a web page."
- data: "Any resources requested by Developer Tools."
- destination: OTHER
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting:
- "It's not possible to disable this feature from settings."
- chrome_policy {
- DeveloperToolsAvailability {
- policy_options {mode: MANDATORY}
- DeveloperToolsAvailability: 2
- }
- }
- })");
- auto resource_request = std::make_unique<network::ResourceRequest>();
- resource_request->url = gurl;
- // TODO(caseq): this preserves behavior of URLFetcher-based implementation.
- // We really need to pass proper first party origin from the front-end.
- resource_request->site_for_cookies = net::SiteForCookies::FromUrl(gurl);
- resource_request->headers.AddHeadersFromString(headers);
-
- mojo::Remote<network::mojom::URLLoaderFactory> file_url_loader_factory;
- scoped_refptr<network::SharedURLLoaderFactory> network_url_loader_factory;
- network::mojom::URLLoaderFactory *url_loader_factory;
- if (gurl.SchemeIsFile()) {
- file_url_loader_factory.Bind(content::CreateFileURLLoaderFactory(base::FilePath(), nullptr));
- url_loader_factory = file_url_loader_factory.get();
- } else if (content::HasWebUIScheme(gurl)) {
- base::DictionaryValue response;
- response.SetInteger("statusCode", 403);
- SendMessageAck(request_id, &response);
- return;
- } else {
- auto *partition = content::BrowserContext::GetStoragePartitionForSite(
- web_contents()->GetBrowserContext(), gurl);
- network_url_loader_factory = partition->GetURLLoaderFactoryForBrowserProcess();
- url_loader_factory = network_url_loader_factory.get();
- }
- auto simple_url_loader = network::SimpleURLLoader::Create(
- std::move(resource_request), traffic_annotation);
- auto resource_loader = std::make_unique<NetworkResourceLoader>(
- stream_id, request_id, this, std::move(simple_url_loader),
- url_loader_factory);
- m_loaders.insert(std::move(resource_loader));
- return;
- } else if (method == "getPreferences") {
- // Screencast is enabled by default if it's not present in the preference store.
- if (!m_prefStore->GetValue(kScreencastEnabled, NULL))
- SetPreference(kScreencastEnabled, "false");
-
- m_preferences = std::move(*m_prefStore->GetValues());
- SendMessageAck(request_id, &m_preferences);
- return;
- } else if (method == "setPreference") {
- std::string name;
- std::string value;
- if (!params->GetString(0, &name) || !params->GetString(1, &value))
- return;
- SetPreference(name, value);
- } else if (method == "removePreference") {
- std::string name;
- if (!params->GetString(0, &name))
- return;
- RemovePreference(name);
- } else if (method == "clearPreferences") {
- ClearPreferences();
- } else if (method == "requestFileSystems") {
- web_contents()->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([]);"),
- base::NullCallback());
- } else if (method == "reattach") {
- if (!m_agentHost)
- return;
- m_agentHost->DetachClient(this);
- m_agentHost->AttachClient(this);
- } else if (method == "inspectedURLChanged" && params && params->GetSize() >= 1) {
- std::string url;
- if (!params->GetString(0, &url))
- return;
- const std::string kHttpPrefix = "http://";
- const std::string kHttpsPrefix = "https://";
- const std::string simplified_url =
- base::StartsWith(url, kHttpsPrefix, base::CompareCase::SENSITIVE)
- ? url.substr(kHttpsPrefix.length())
- : base::StartsWith(url, kHttpPrefix, base::CompareCase::SENSITIVE)
- ? url.substr(kHttpPrefix.length())
- : url;
- // DevTools UI is not localized.
- web_contents()->UpdateTitleForEntry(web_contents()->GetController().GetActiveEntry(),
- base::UTF8ToUTF16(
- base::StringPrintf("DevTools - %s", simplified_url.c_str())));
- } else if (method == "openInNewTab") {
- std::string urlString;
- if (!params->GetString(0, &urlString))
- return;
- GURL url(urlString);
- if (!url.is_valid())
- return;
- content::OpenURLParams openParams(GURL(url),
- content::Referrer(),
- WindowOpenDisposition::NEW_FOREGROUND_TAB,
- ui::PAGE_TRANSITION_LINK,
- false);
- // OpenURL will (via WebContentsDelegateQt::OpenURLFromTab) call
- // application code, which may decide to close this devtools view (see
- // quicknanobrowser for example).
- //
- // Chromium always calls SendMessageAck through a callback bound to a
- // WeakPtr, we do the same here, except without the callback.
- base::WeakPtr<DevToolsFrontendQt> weakThis = m_weakFactory.GetWeakPtr();
- web_contents()->OpenURL(openParams);
- if (!weakThis)
- return;
- } else if (method == "bringToFront") {
- Activate();
- } else if (method == "closeWindow") {
- web_contents()->Close();
- } else if (method == "setEyeDropperActive" && params->GetSize() == 1) {
- bool active;
- if (!params->GetBoolean(0, &active))
- return;
- SetEyeDropperActive(active);
- } else {
- VLOG(1) << "Unimplemented devtools method: " << message;
- return;
- }
+ content::OpenURLParams params(GURL(url), content::Referrer(),
+ WindowOpenDisposition::NEW_FOREGROUND_TAB,
+ ui::PAGE_TRANSITION_LINK, false);
- if (request_id)
- SendMessageAck(request_id, nullptr);
+ m_inspectedContents->OpenURL(params);
}
void DevToolsFrontendQt::SetEyeDropperActive(bool active)
@@ -560,84 +184,38 @@ void DevToolsFrontendQt::SetEyeDropperActive(bool active)
return;
if (active) {
m_eyeDropper.reset(new DevToolsEyeDropper(
- m_inspectedContents,
- base::Bind(&DevToolsFrontendQt::ColorPickedInEyeDropper,
- base::Unretained(this))));
+ m_inspectedContents,
+ base::BindRepeating(&DevToolsFrontendQt::ColorPickedInEyeDropper,
+ base::Unretained(this))));
} else {
m_eyeDropper.reset();
}
}
-void DevToolsFrontendQt::ColorPickedInEyeDropper(int r, int g, int b, int a)
+// static
+bool DevToolsFrontendQt::IsValidFrontendURL(const GURL &url)
{
- base::DictionaryValue color;
- color.SetInteger("r", r);
- color.SetInteger("g", g);
- color.SetInteger("b", b);
- color.SetInteger("a", a);
- CallClientFunction("DevToolsAPI.eyeDropperPickedColor", &color, nullptr, nullptr);
+ // NOTE: the inspector app does not change the frontend url.
+ // If we bring back the devtools_app, the url must be sanitized
+ // according to chrome/browser/devtools/devtools_ui_bindings.cc.
+ return url.spec() == GetFrontendURL();
}
-void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *agentHost, base::span<const uint8_t> message)
+void DevToolsFrontendQt::InspectedContentsClosing()
{
- Q_UNUSED(agentHost);
- base::StringPiece message_sp(reinterpret_cast<const char*>(message.data()), message.size());
- if (message_sp.length() < kMaxMessageChunkSize) {
- std::string param;
- base::EscapeJSONString(message_sp, true, &param);
- std::string code = "DevToolsAPI.dispatchMessage(" + param + ");";
- base::string16 javascript = base::UTF8ToUTF16(code);
- web_contents()->GetMainFrame()->ExecuteJavaScript(javascript, base::NullCallback());
- return;
- }
-
- size_t total_size = message_sp.length();
- for (size_t pos = 0; pos < message_sp.length(); pos += kMaxMessageChunkSize) {
- std::string param;
- base::EscapeJSONString(message_sp.substr(pos, kMaxMessageChunkSize), true, &param);
- std::string code = "DevToolsAPI.dispatchMessageChunk(" + param + ","
- + std::to_string(pos ? 0 : total_size) + ");";
- base::string16 javascript = base::UTF8ToUTF16(code);
- web_contents()->GetMainFrame()->ExecuteJavaScript(javascript, base::NullCallback());
- }
-}
-
-void DevToolsFrontendQt::CallClientFunction(const std::string &function_name,
- const base::Value *arg1,
- const base::Value *arg2,
- const base::Value *arg3)
-{
- std::string javascript = function_name + "(";
- if (arg1) {
- std::string json;
- base::JSONWriter::Write(*arg1, &json);
- javascript.append(json);
- if (arg2) {
- base::JSONWriter::Write(*arg2, &json);
- javascript.append(", ").append(json);
- if (arg3) {
- base::JSONWriter::Write(*arg3, &json);
- javascript.append(", ").append(json);
- }
- }
- }
- javascript.append(");");
- web_contents()->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(javascript), base::NullCallback());
+ // Called for already destroyed guest views
+ m_inspectedContents = nullptr;
+ web_contents()->ClosePage();
}
-void DevToolsFrontendQt::SendMessageAck(int request_id, const base::Value *arg)
+std::string DevToolsFrontendQt::GetId(content::WebContents *inspectedContents)
{
- base::Value id_value(request_id);
- CallClientFunction("DevToolsAPI.embedderMessageAck", &id_value, arg, nullptr);
+ return content::DevToolsAgentHost::GetOrCreateFor(inspectedContents)->GetId();
}
-void DevToolsFrontendQt::AgentHostClosed(content::DevToolsAgentHost *agentHost)
+void DevToolsFrontendQt::CloseWindow()
{
- DCHECK(agentHost == m_agentHost.get());
- m_agentHost = nullptr;
- m_inspectedContents = nullptr;
- m_inspectedAdapter = nullptr;
- Close();
+ web_contents()->Close();
}
} // namespace QtWebEngineCore
diff --git a/src/core/devtools_frontend_qt.h b/src/core/devtools_frontend_qt.h
index aac5909dc..b867d4af1 100644
--- a/src/core/devtools_frontend_qt.h
+++ b/src/core/devtools_frontend_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DEVTOOLS_FRONTEND_QT_H
#define DEVTOOLS_FRONTEND_QT_H
@@ -45,35 +9,26 @@
#include "web_contents_delegate_qt.h"
-#include "base/compiler_specific.h"
#include "base/containers/unique_ptr_adapters.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/values.h"
-#include "content/public/browser/devtools_agent_host.h"
-#include "content/public/browser/devtools_frontend_host.h"
+#include "chrome/browser/devtools/devtools_ui_bindings.h"
#include "content/public/browser/web_contents_observer.h"
-namespace base {
-class Value;
-}
+class DevToolsEyeDropper;
namespace content {
-class NavigationHandle;
-class RenderViewHost;
+class DevToolsAgentHost;
class WebContents;
-} // namespace content
-
-class DevToolsEyeDropper;
-class PersistentPrefStore;
+} // namespace content
namespace QtWebEngineCore {
+class WebContentsAdapter;
-class DevToolsFrontendQt : public content::WebContentsObserver
- , public content::DevToolsAgentHostClient {
+class DevToolsFrontendQt : public DevToolsUIBindings::Delegate, public content::WebContentsObserver
+{
public:
- static DevToolsFrontendQt *Show(QSharedPointer<WebContentsAdapter> frontendAdapter, content::WebContents *inspectedContents);
+ static DevToolsFrontendQt *Show(QSharedPointer<WebContentsAdapter> frontendAdapter,
+ content::WebContents *inspectedContents);
void Activate();
void Focus();
@@ -82,62 +37,50 @@ public:
void DisconnectFromTarget();
- void CallClientFunction(const std::string& function_name,
- const base::Value* arg1,
- const base::Value* arg2,
- const base::Value* arg3);
+ WebContentsDelegateQt *frontendDelegate() const;
- WebContentsDelegateQt *frontendDelegate() const
- {
- return m_frontendDelegate;
- }
+ static bool IsValidFrontendURL(const GURL &url);
+ static std::string GetId(content::WebContents *inspectedContents);
protected:
- DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webContentsAdapter, content::WebContents *inspectedContents);
+ DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webContentsAdapter,
+ content::WebContents *inspectedContents);
~DevToolsFrontendQt() override;
- // content::DevToolsAgentHostClient implementation.
- void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
- void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, base::span<const uint8_t> message) override;
-
- void SetPreferences(const std::string& json);
- virtual void HandleMessageFromDevToolsFrontend(const std::string& message);
-
private:
- // WebContentsObserver overrides
- void ReadyToCommitNavigation(content::NavigationHandle* navigation_handle) override;
- void DocumentAvailableInMainFrame() override;
+ void ColorPickedInEyeDropper(int r, int g, int b, int a);
+
+ // content::WebContentsObserver overrides
void WebContentsDestroyed() override;
- void SendMessageAck(int request_id, const base::Value* arg1);
- void SetPreference(const std::string &name, const std::string &value);
- void RemovePreference(const std::string &name);
- void ClearPreferences();
- void CreateJsonPreferences(bool clear);
- void SetEyeDropperActive(bool active);
- void ColorPickedInEyeDropper(int r, int g, int b, int a);
+ // DevToolsUIBindings::Delegate overrides
+ void ActivateWindow() override;
+ void SetEyeDropperActive(bool active) override;
+ void OpenInNewTab(const std::string &url) override;
+ void InspectedContentsClosing() override;
+ void OnLoadCompleted() override;
+
+ void InspectElementCompleted() override{};
+ void CloseWindow() override;
+ void Inspect(scoped_refptr<content::DevToolsAgentHost>) override{};
+ void SetInspectedPageBounds(const gfx::Rect &) override{};
+ void SetIsDocked(bool) override{};
+ void SetWhitelistedShortcuts(const std::string &) override{};
+ void OpenNodeFrontend() override{};
+ void ReadyForTest() override{};
+ void ConnectionReady() override{};
+ void SetOpenNewWindowForPopups(bool) override{};
+ void RenderProcessGone(bool) override{};
+ void ShowCertificateViewer(const std::string &) override{};
// We shouldn't be keeping it alive
QWeakPointer<WebContentsAdapter> m_frontendAdapter;
- WebContentsAdapter *m_inspectedAdapter;
- WebContentsDelegateQt *m_frontendDelegate;
content::WebContents *m_inspectedContents;
- scoped_refptr<content::DevToolsAgentHost> m_agentHost;
- int m_inspect_element_at_x;
- int m_inspect_element_at_y;
- std::unique_ptr<content::DevToolsFrontendHost> m_frontendHost;
+ content::WebContents *m_outermostContents;
std::unique_ptr<DevToolsEyeDropper> m_eyeDropper;
-
- class NetworkResourceLoader;
- std::set<std::unique_ptr<NetworkResourceLoader>, base::UniquePtrComparator> m_loaders;
-
- base::DictionaryValue m_preferences;
- scoped_refptr<PersistentPrefStore> m_prefStore;
- base::WeakPtrFactory<DevToolsFrontendQt> m_weakFactory;
-
- DISALLOW_COPY_AND_ASSIGN(DevToolsFrontendQt);
+ DevToolsUIBindings *m_bindings;
};
} // namespace QtWebEngineCore
-#endif // DEVTOOLS_FRONTEND_QT_H
+#endif // DEVTOOLS_FRONTEND_QT_H
diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index 51f00d3e5..6654ead0e 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on content/shell/browser/shell_devtools_manager_delegate.cc:
// Copyright 2013 The Chromium Authors. All rights reserved.
@@ -43,31 +7,19 @@
// found in the LICENSE.Chromium file.
#include "devtools_manager_delegate_qt.h"
+#include "qtwebengine/grit/qt_webengine_resources.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
#include "content/browser/devtools/devtools_http_handler.h"
#include "content/public/browser/devtools_agent_host.h"
-#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/devtools_socket_factory.h"
-#include "content/public/browser/favicon_status.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_switches.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/socket/tcp_server_socket.h"
#include "ui/base/resource/resource_bundle.h"
-#include "qtwebengine/grit/qt_webengine_resources.h"
-
-#include "type_conversion.h"
-
using content::DevToolsAgentHost;
namespace {
@@ -93,7 +45,6 @@ private:
const std::string m_address;
int m_port;
int m_backlog;
- DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
};
} // namespace
@@ -189,4 +140,4 @@ bool DevToolsManagerDelegateQt::HasBundledFrontendResources()
return true;
}
-} //namespace QtWebEngineCore
+} // namespace QtWebEngineCore
diff --git a/src/core/devtools_manager_delegate_qt.h b/src/core/devtools_manager_delegate_qt.h
index 3a519a03f..6e02b04a4 100644
--- a/src/core/devtools_manager_delegate_qt.h
+++ b/src/core/devtools_manager_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H
#define DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H
diff --git a/src/core/doc/about_credits_entry.tmpl b/src/core/doc/about_credits_entry.tmpl
index 2bb9cff4e..aa94f2945 100644
--- a/src/core/doc/about_credits_entry.tmpl
+++ b/src/core/doc/about_credits_entry.tmpl
@@ -1,5 +1,6 @@
/*!
-\page qtwebengine-3rdparty-{{name-sanitized}}.html attribution
+\page qtwebengine-3rdparty-{{name-sanitized}}.html
+\attribution
\ingroup qtwebengine-licensing
\brief {{license-type}}
\title {{name}}
diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf
index ed95ae0ca..6b78f13f8 100644
--- a/src/core/doc/qtwebengine.qdocconf
+++ b/src/core/doc/qtwebengine.qdocconf
@@ -31,7 +31,8 @@ qhp.QtWebEngine.subprojects.examples.selectors = doc:example
qhp.QtWebEngine.subprojects.examples.sortPages = true
manifestmeta.highlighted.names += "QtWebEngine/WebEngine Widgets Simple Browser Example" \
- "QtWebEngine/WebEngine Quick Nano Browser"
+ "QtWebEngine/WebEngine Quick Nano Browser" \
+ "QtWebEngine/Recipe Browser"
tagfile = ../../../doc/qtwebengine/qtwebengine.tags
@@ -45,7 +46,6 @@ depends += qtcore \
qtcore5compat \
qtdesigner \
qtgui \
- qtlocation \
qtnetwork \
qtprintsupport \
qtpositioning \
@@ -92,5 +92,5 @@ navigation.qmltypespage = "Qt WebEngine QML Types"
# \QWE macro expands to 'Qt WebEngine' without auto-linking anywhere.
macro.QWE = "Qt \\WebEngine"
-# Fail the documentation build if there are more warnings than the limit
+# Enforce zero documentation warnings
warninglimit = 0
diff --git a/src/core/doc/snippets/qtwebengine_qwebenginepage_snippet.cpp b/src/core/doc/snippets/qtwebengine_qwebenginepage_snippet.cpp
index b948fa597..6b39eed03 100644
--- a/src/core/doc/snippets/qtwebengine_qwebenginepage_snippet.cpp
+++ b/src/core/doc/snippets/qtwebengine_qwebenginepage_snippet.cpp
@@ -1,36 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
void wrapInFunction()
{
//! [0]
- m_view->page()->findText(QStringLiteral("Qt"), QWebEnginePage::FindFlags(), [this](bool found) {
- if (!found) QMessageBox::information(m_view, QString(), QStringLiteral("No occurrences found"));
+ m_view->page()->findText(QStringLiteral("Qt"), QWebEnginePage::FindFlags(), [this](const QWebEngineFindTextResult &result) {
+ if (result.numberOfMatches() == 0) QMessageBox::information(m_view, QString(), QStringLiteral("No occurrences found"));
});
//! [0]
diff --git a/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc
index 43421bafb..9a7370d62 100644
--- a/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc
+++ b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc
@@ -1,40 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [0]
QT += webenginecore
//! [0]
-
-//! [1]
-#include <QtWebEngineCore>
-//! [1]
-
//! [2]
-find_package(Qt6 COMPONENTS WebEngineCore REQUIRED)
-target_link_libraries(target PRIVATE Qt::WebEngineCore)
+find_package(Qt6 REQUIRED COMPONENTS WebEngineCore)
+target_link_libraries(target PRIVATE Qt6::WebEngineCore)
//! [2]
diff --git a/src/core/doc/src/external-resources.qdoc b/src/core/doc/src/external-resources.qdoc
index df6c40c4f..775492c7e 100644
--- a/src/core/doc/src/external-resources.qdoc
+++ b/src/core/doc/src/external-resources.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\externalpage http://www.chromium.org
diff --git a/src/core/doc/src/qt6-changes.qdoc b/src/core/doc/src/qt6-changes.qdoc
index 6ae6918ca..5061c77ab 100644
--- a/src/core/doc/src/qt6-changes.qdoc
+++ b/src/core/doc/src/qt6-changes.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-changes-qt6.html
diff --git a/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc b/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc
index cbb4a41fd..6af681cc5 100644
--- a/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc
+++ b/src/core/doc/src/qt_webengine_add_convert_dictionary.qdoc
@@ -1,39 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\page qt_add_webengine_dictionary.html
-\ingroup cmake-commands
+\page qt-add-webengine-dictionary.html
+\ingroup cmake-commands-qtwebenginecore
\title qt_add_webengine_dictionary
-\target qt6_add_webengine_dictionary
+\keyword qt6_add_webengine_dictionary
\brief Converts the hunspell dictionary format into \e bdict binary format.
+\cmakecommandsince 6.3
+
\section1 Synopsis
\badcode
@@ -51,7 +29,7 @@ qt_add_webengine_dictionary(
A spell checker in Qt Web Engine needs dictionaries in a specific binary format.
This CMake command converts dictionaries from the \l{Hunspell project}. into the \c bdict
- binary format. It creates a \c webengine_dictionaries target, which your project can
+ binary format. It creates a \c qtwebengine_dictionaries target, which your project can
use as a dependency. This way your project can easily add dictionaries for the spell
checker. Refer to the \l{WebEngine Widgets Spellchecker Example}{spell checker example}
for more details.
@@ -59,7 +37,7 @@ qt_add_webengine_dictionary(
\section1 Arguments
\c TARGET is an optinal argument and specifies the name of the application target that should
- depend on \c webengine_dictionaries target. In other words it is used to define a build
+ depend on \c qtwebengine_dictionaries target. In other words it is used to define a build
dependency to create the binary format of dictionaries before building \c TARGET.
\c SOURCE is the absolute path to the \l{Hunspell project} dictionary for which
@@ -69,7 +47,8 @@ qt_add_webengine_dictionary(
of the dictionary will be created. If not specified, \c CMAKE_CURRENT_BINARY_DIR will be used
as \c OUTPUT_DIRECTORY.
- \note The \c webengine_dictionaries directory or \c <CONFIG>/webengine_dictionaries directories
- in the case of the multi-config generator is appended to OUTPUT_DIRECTORY. This helps to
- utilize dictionaries, as the \c webengine_dictionaries directory is the default search location.
+ \note The \c qtwebengine_dictionaries directory or \c <CONFIG>/qtwebengine_dictionaries
+ directories in the case of the multi-config generator is appended to OUTPUT_DIRECTORY. This
+ helps to utilize dictionaries, as the \c webengine_dictionaries directory is the default
+ search location.
*/
diff --git a/src/core/doc/src/qtwebengine-debugging.qdoc b/src/core/doc/src/qtwebengine-debugging.qdoc
index f84cca312..3dd4d9276 100644
--- a/src/core/doc/src/qtwebengine-debugging.qdoc
+++ b/src/core/doc/src/qtwebengine-debugging.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-debugging.html
@@ -52,10 +28,14 @@
\QWE based browser, such as the Chrome browser.
To activate the developer tools, start an application that uses \QWE
- with the command-line arguments:
+ with the command-line argument \c {--remote-debugging-port=<portnumber>}.
+
+ \note Any WebEngine command line options should be specified after the
+ \c {--webEngineArgs} option, which is used to separate the user's application
+ specific options from the WebEngine's ones.
\badcode
- --remote-debugging-port=<port_number>
+ --webEngineArgs --remote-debugging-port=<portnumber>
\endcode
Where \c <port_number> refers to a local network port. The web developer
@@ -69,6 +49,12 @@
interface on, so that you can access the developer tools from a remote
device.
+ To avoid WebSocket errors during remote debugging, add an additional command-line
+ argument \c {--remote-allow-origins=<origin>[,<origin>, ...]}, where \c <origin> refers to the request origin.
+ Use \c {--remote-allow-origins=*} to allow connections from all origins. If nothing is specified,
+ \QWE will add \c {--remote-allow-origins=*} to command-line arguments when remote-debugging is enabled,
+ thereby allowing requests from all origins.
+
For a detailed explanation of the capabilities of developer tools, see the
\l {Chrome DevTools} page.
@@ -112,6 +98,15 @@
QTWEBENGINE_CHROMIUM_FLAGS="--disable-logging" mybrowser
\endcode
- QTWEBENGINE_CHROMIUM_FLAGS can also be set using {qputenv} from within the
+ QTWEBENGINE_CHROMIUM_FLAGS can also be set using \c qputenv from within the
application if called before QtWebEngineQuick::initialize().
+
+ \section1 Dump WebEngineContext Information
+
+ For dumping the WebEngineContext information, you can set the \c QT_LOGGING_RULES
+ environment variable to \c "qt.webenginecontext.debug=true".
+
+ The output contains information about the graphical backend, and the way how \QWE
+ is initialized for the application. This is particularly useful for reproducing
+ issues.
*/
diff --git a/src/core/doc/src/qtwebengine-deploying.qdoc b/src/core/doc/src/qtwebengine-deploying.qdoc
index 7b9f3fd4a..3d8a976c8 100644
--- a/src/core/doc/src/qtwebengine-deploying.qdoc
+++ b/src/core/doc/src/qtwebengine-deploying.qdoc
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-deploying.html
\title Deploying Qt WebEngine Applications
+ \ingroup explanations-webtechnologies
The way to package and deploy applications varies between operating systems.
For Windows and \macos, \l{The Windows Deployment Tool}{windeployqt} and
@@ -121,6 +98,12 @@
\li \c icudtl.dat provides support for International Components for
Unicode (ICU). It is the Chromium version of ICU, which is not
needed if \QWE was configured to use the system ICU.
+ \li \c v8_context_snapshot.bin contains a previously prepared snapshot
+ of a v8 context used to speed up initialization. Debug builds use
+ separate snapshots with the file name extension \c .debug.bin instead
+ of \c .bin. On \macos, there is a snapshot for each architecture named
+ accordingly, for example \c v8_context_snapshot.arm64.bin or
+ \c v8_context_snapshot.arm64.debug.bin.
\endlist
Resources are searched from the following locations:
@@ -129,8 +112,12 @@
\li On Linux and Windows: the \c resources directory in the directory
specified by QLibraryInfo::location(QLibraryInfo::DataPath)
\li On \macos: \c .app/Content/Resources
+ \li The application directory specified by QCoreApplication::applicationDirPath()
\endlist
+ Alternatively, a resources directory path can be set as a value of the
+ \c QTWEBENGINE_RESOURCES_PATH environment variable.
+
\section2 Translations
Locale data (such as \c en-US.pak) is searched form the following locations:
@@ -142,6 +129,9 @@
QLibraryInfo::location(QLibraryInfo::TranslationsPath)
\endlist
+ Alternatively, a locales directory path can be set as a value of the
+ \c QTWEBENGINE_LOCALES_PATH environment variable.
+
\section2 JavaScript Files in Qt Resource Files
If your WebEngine application is built using the Qt Quick Compiler, and the application ships
@@ -155,4 +145,55 @@
QTQUICK_COMPILER_SKIPPED_RESOURCES += resources/my_resource.qrc
\endcode
+ \section2 \macos Specific Deployment Steps
+
+ To deploy a \QWE application on \macos, you will need to ensure that the \QWE process is signed
+ with an entitlements file that at least contains the entitlements listed in
+ QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/Resources/QtWebEngineProcess.entitlements.
+
+ To deploy a \QWE application that accesses the microphone or camera
+ on \macos, you will need to provide texts for the messages that will be shown to the user to
+ explain why the application asks for permission to access to the camera or microphone.
+ To do this, add the texts to the application's \c Info.plist file using the keys
+ described below.
+
+ For the camera usage message, provide a text using the following key:
+ \code
+ <key>NSCameraUsageDescription</key>
+ <string>Your message text for camera usage.</string>
+ \endcode
+
+ See also \l{https://developer.apple.com/documentation/bundleresources/information_property_list/nscamerausagedescription}
+ {Apple's property list file documentation}.
+
+ For the microphone usage message, provide a text using the following key:
+ \code
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Your message text for microphone usage.</string>
+ \endcode
+
+ See also \l{https://developer.apple.com/documentation/bundleresources/information_property_list/nsmicrophoneusagedescription}
+ {Apple's property list file documentation}.
+
+ To notarize an application that accesses the camera or the microphone,
+ you will need to add the corresponding keys to your application's entitlements file used for
+ deployment and notarization.
+
+ To enable access to the camera, add:
+ \code
+ <key>com.apple.security.device.camera</key>
+ <true/>
+ \endcode
+
+ See also \l{https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_camera}
+ {Apple's camera entitlement documentation}.
+
+ To enable access to the microphone, add:
+ \code
+ <key>com.apple.security.device.microphone</key>
+ <true/>
+ \endcode
+
+ See also \l{https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_device_microphone}
+ {Apple's microphone entitlement documentation}.
*/
diff --git a/src/core/doc/src/qtwebengine-features.qdoc b/src/core/doc/src/qtwebengine-features.qdoc
index 3b34ffbf6..9465d75a2 100644
--- a/src/core/doc/src/qtwebengine-features.qdoc
+++ b/src/core/doc/src/qtwebengine-features.qdoc
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-features.html
\title Qt WebEngine Features
+ \ingroup explanations-webtechnologies
\brief Summarizes \QWE features.
@@ -35,16 +12,20 @@
\list
\li \l{Audio and Video Codecs}
+ \li \l{WebEngineDriver}
\li \l{Chromium DevTools}
\li \l{Client Certificates}
\li \l{Custom Schemes}
\li \l{Drag and Drop}
+ \li \l{Favicon}
\li \l{Fullscreen}
+ \li \l{Hardware Acceleration}
\li \l{HTML5 DRM}
\li \l{HTML5 Geolocation}
+ \li \l{HTML5 WebSockets}
\li \l{HTTP/2 Protocol}
+ \li \l{Local Storage}
\li \l{Native Dialogs}
- \li \l{Pepper Plugin API}
\li \l{PDF File Viewing}
\li \l{Page Lifecycle API}
\li \l{Print to PDF}
@@ -52,9 +33,9 @@
\li \l{Spellchecker}
\li \l{Touch}
\li \l{View Source}
- \li \l{webrtc_feature}{WebRTC}
\li \l{Web Notifications}
- \li \l{Favicon Handling}
+ \li \l{WebGL}
+ \li \l{webrtc_feature}{WebRTC}
\endlist
\section1 Audio and Video Codecs
@@ -64,14 +45,14 @@
(MP3), have been enabled. Proprietary codecs can be enabled by passing the
following option to the \c configure tool when configuring Qt:
- \code
+ \badcode
-webengine-proprietary-codecs
\endcode
For example, the following option could be passed when configuring Qt for
building it at the top level:
- \code
+ \badcode
configure -webengine-proprietary-codecs
\endcode
@@ -81,7 +62,7 @@
command can be used to configure and build (in this example, the \QWE source code is
located in \c {C:\qt\qtwebengine}):
- \code
+ \badcode
qt-configure-module C:\qt\qtwebengine -webengine-proprietary-codecs
cmake --build . --parallel
\endcode
@@ -95,6 +76,68 @@
codecs, open source implementations, such as \l{OpenH264 Project Homepage}
{OpenH264}, are available.
+ \section1 WebEngineDriver
+
+ With WebEngineDriver, you can automate the testing of web sites across browsers.
+ WebEngineDriver is based on ChromeDriver and can be used the same way.
+ For more information about ChromeDriver and its use, visit
+ \l {https://chromedriver.chromium.org/}{ChromeDriver user site}.
+
+ WebEngineDriver has slight modifications compared to ChromeDriver to be able to connect to
+ \QWE based browsers. It is compatible with \QWE example browsers, such as
+ \l {WebEngine Widgets Simple Browser Example}{Simple Browser} or
+ \l{WebEngine Quick Nano Browser}{Nano Browser}.
+
+ The browser automation is scripted through a WebDriver client like the
+ \l {https://www.selenium.dev/}{Selenium WebDriver}.
+ For example, WebEngineDriver can be used with the Python lanugage bindings of
+ Selenium WebDriver:
+
+ \code
+ from selenium import webdriver
+ from selenium.webdriver.chrome.service import Service
+
+ service = Service(executable_path='QTDIR/libexec/webenginedriver')
+ options = webdriver.ChromeOptions()
+ options.binary_location = 'path/to/browser_binary'
+
+ driver = webdriver.Chrome(service=service, options=options)
+ driver.get("http://www.google.com/")
+ driver.quit()
+ \endcode
+
+ In this example,
+ \list
+ \li \c executable_path has to be set to the WebEngineDriver's binary path
+ \li \c QTDIR is the directory where Qt is installed
+ \li \c options.binary_location has to be set to the browser's binary path
+ \endlist
+
+ \note On Windows: \c executable_path='QTDIR/bin/webenginedriver.exe'
+
+ Before executing the script, the \c QTWEBENGINE_REMOTE_DEBUGGING environment variable has to
+ be set. Its value is a port number what is used by both the browser and WebEngineDriver to
+ communicate with each other.
+ \badcode
+ export QTWEBENGINE_REMOTE_DEBUGGING=12345
+ \endcode
+
+ By executing, the script opens the specified web browser and loads the Google web site.
+
+ WebEngineDriver can be also attached to an already running browser if it was started with the
+ remote debugging port set. \c options.debugger_address has to be set to the remote debugging
+ address in the script:
+
+ \code
+ options.debugger_address = 'localhost:12345'
+ \endcode
+
+ In this case, \c options.binary_location should not be set because the browser is already
+ running. The environment variable \c QTWEBENGINE_REMOTE_DEBUGGING is not used by the
+ WebEngineDriver if \c options.debugger_address is set.
+
+ \note WebEngineDriver must be built with the same version of Chromium as \QWE is using.
+
\section1 Chromium DevTools
The Chromium DevTools provide the ability to inspect and debug layout and
@@ -102,11 +145,25 @@
This feature can be tested by launching a \QWE application with the
command line option \c {--remote-debugging-port=[your-port]} or by setting
- the environment variable \c QTWEBENGINE_REMOTE_DEBUGGING, and then using a
+ the environment variable \c QTWEBENGINE_REMOTE_DEBUGGING and then using a
Chromium based browser (such as \l{WebEngine Widgets Simple Browser Example}
{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}) to connect
to \c {http://localhost:[your-port]}.
+ \note Any WebEngine command line options should be specified after the
+ \c {--webEngineArgs} option, which is used to separate the user's application
+ specific options from the WebEngine's ones.
+
+ \badcode
+ --webEngineArgs --remote-debugging-port=5000
+ \endcode
+
+ To avoid WebSocket errors during remote debugging, add an additional command-line argument
+ \c {--remote-allow-origins=<origin>[,<origin>, ...]}, where \c <origin> refers to the request origin.
+ Use \c {--remote-allow-origins=*} to allow connections from all origins. If nothing is specified,
+ \QWE will add \c {--remote-allow-origins=*} to command-line arguments when remote-debugging is enabled,
+ thereby allowing requests from all origins.
+
The Chromium DevTools page can also be shown within the application. To set
this up, you can call either QWebEnginePage::setInspectedPage() to the page
to be inspected, which implicitly loads the DevTools into the \c this page,
@@ -137,6 +194,16 @@
recommended to always give the user a choice before uniquely identifying them
to a remote server.
+ In addition to the client certificate stored in system settings, \QWE offers also
+ the in-memory store. The QWebEngineClientCertificateStore instance can be obtained with
+ the QWebEngineProfile::clientCertificateStore() method. An application can use this
+ class to add a new certificate with a QWebEngineClientCertificateStore::add() call.
+ Note that during the \c selectClientCertificate calls, \QWE lists both system
+ and in-memory stored clients certificates.
+
+ See also \l{WebEngine Widgets Client Certificate Example}{Client Certificate Example}
+ for more implementation details.
+
\section1 Custom Schemes
\QWE makes it possible for the application to define its own custom
@@ -144,7 +211,7 @@
Custom schemes can be used to implement alternative network protocols with
all the usual web security policies, privileged internal schemes for
- displaying user interface compoments or debugging information, sandboxed
+ displaying user interface components or debugging information, sandboxed
schemes with extra restrictions, and so on.
For more information, see \l QWebEngineUrlScheme and \l
@@ -165,6 +232,61 @@
Support for this feature was added in Qt 5.7.0.
+ \section1 Favicon
+
+ \QWE supports the web site URL icon, \e favicon. Each icon is stored in the internal
+ database for each \l QWebEngineProfile and can be accessed using a \l QWebEnginePage::icon()
+ call or a \l {WebEngineView::icon}{WebEngineView.icon} property for the currently loaded content.
+
+ Moreover \QWE provides API for accessing already stored icons in the internal profile's database.
+
+ \note The icon database is not available for off-the-record profiles.
+
+ \section2 QML Favicon Handling
+
+ For accessing icons a \c QQuickImageProvider is registered. This provider can be
+ accessed by a special URL where the scheme is "image:" and the host is "favicon".
+
+ \qml
+ Image {
+ source: "image://favicon/url"
+ }
+ \endqml
+
+ The \c url can be the URL of the favicon:
+
+ \qml
+ Image {
+ source: "image://favicon/https://www.qt.io/hubfs/2016_Qt_Logo/qt_logo_green_rgb_16x16.png"
+ }
+ \endqml
+
+ The \c url also can be a page URL to access its icon:
+
+ \qml
+ Image {
+ source: "image://favicon/https://www.qt.io/"
+ }
+ \endqml
+
+ If more than one icon is available, the \l {Image::sourceSize} property can be
+ specified to choose the icon with the desired size. If \l {Image::sourceSize}
+ is not specified or 0, the largest available icon will be chosen.
+
+ The image provider looks up the requested icon in the existing \l {WebEngineView}
+ instances. First, it tries to match the currently displayed icons. If no match
+ has been found it requests the icon from the database. Each profile has its
+ own icon database and it is stored in the persistent storage thus the stored icons
+ can be accessed without network connection too. The icon must be previously loaded
+ to be stored in the database.
+
+ \section2 C++ Favicon Handling
+
+ A user can request an icon from the previously loaded content for each
+ \l QWebEngineProfile using the \l QWebEngineProfile::requestIconForPageURL() or
+ \l QWebEngineProfile::requestIconForIconURL() calls. Note that the profile's database is
+ stored in the persistent storage and can be accessed without a network connection.
+
\section1 Fullscreen
\QWE supports viewing web content in fullscreen mode. For more
@@ -181,6 +303,20 @@
Support for this feature was added in Qt 5.6.0.
+ \section1 Hardware Acceleration
+
+ QtWebEngine tries to use hardware acceleration for rendering the content. It uses
+ \c OpenGL or \c OpenGLES APIs to execute rendering calls on the GPU. As a fallback,
+ software rendering is used whenever the hardware does not meet the required set of
+ OpenGL functionality. A user can check the current hardware acceleration state by
+ loading the \c {chrome://gpu} internal page. Moreover, the acceleration can be explicitly
+ disabled with \c {QTWEBENGINE_CHROMIUM_FLAGS} using the \c {disable-gpu} switch.
+ For example on Linux:
+
+ \badcode
+ export QTWEBENGINE_CHROMIUM_FLAGS=--disable-gpu
+ \endcode
+
\section1 HTML5 DRM
\QWE supports viewing DRM protected videos if the \l{Widevine CDM} plugin has been installed.
@@ -193,17 +329,17 @@
location can be also passed with \c {QTWEBENGINE_CHROMIUM_FLAGS} using \c {widevine-path}.
On Windows:
- \code
+ \badcode
set QTWEBENGINE_CHROMIUM_FLAGS=--widevine-path="C:/some path/widevinecdm.dll"
\endcode
On Linux:
- \code
+ \badcode
export QTWEBENGINE_CHROMIUM_FLAGS=--widevine-path="/some path/libwidevinecdm.so"
\endcode
On macOS:
- \code
+ \badcode
export QTWEBENGINE_CHROMIUM_FLAGS=--widevine-path="/some path/libwidevinecdm.dylib"
\endcode
@@ -221,18 +357,41 @@
\section1 HTML5 Geolocation
\QWE supports JavaScript Geolocation API with \l {Qt Positioning} as a
- backend. The application has to explicitly allow the feature by using
- QWebEnginePage::Geolocation or \l{WebEngineView::Feature}
- {WebEngineView.Feature}.
+ backend. HTML5 geolocation is disabled by default. To explicitly allow it, the application
+ needs to listen to QWebEnginePage::featurePermissionRequested. Use QWebEnginePage::Geolocation
+ with a QWebEnginePage::setFeaturePermission() call or \l{WebEngineView::Feature}
+ with a \l{WebEngineView::grantFeaturePermission} {WebEngineView.grantFeaturePermission}() call
+ to grant the required permission.
- If Qt Positioning has been built before \QWE then this feature can be
+ If \QWE was built with Qt Positioning support then this feature can be
tested by using \l{WebEngine Widgets Maps Example}{Maps} and allowing it to
- find the current position of the user. Note that on Windows an external GPS
- receiver must be connected to the application. For more information, see
- \l{Qt Positioning}.
+ find the current position of the user.
+
+ \note On Windows 11, enable settings to grant the maps example access to
+ Windows location services. In the Settings App under
+ \uicontrol {Privacy & Security} > \uicontrol {Location}, enable \uicontrol
+ {Location services}, \uicontrol {Let apps access your location} and \uicontrol
+ {Let desktop apps access your location}.
+
+ See \l{Qt Positioning} for a possible backend setup like the GPS or IP based positioning.
Support for this feature was added in Qt 5.5.0.
+ \section1 HTML5 WebSockets
+
+ \QWE supports the WebSocket JavaScript API to communicate with WebSocket servers
+ using the \c {ws://} or \c {wss://} protocols. Moreover, integration with Qt WebChannel
+ and Qt WebSockets enables communication between JavaScript and the native side of
+ the application.
+
+ The Qt WebChannel module has a great example for a
+ \l[QtWebChannel]{Qt WebChannel ChatServer Example}{chat server}
+ and its web based
+ \l[QtWebChannel]{Qt WebChannel ChatClient HTML Example}{chat client}.
+ The client works out of the box in the example browsers of \QWE
+ (such as \l{WebEngine Widgets Simple Browser Example}
+ {Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}).
+
\section1 HTTP/2 Protocol
\QWE supports the Chromium implementation of the \l{HTTP/2}
@@ -242,6 +401,31 @@
\l{Akamai HTTP/2 Demo}, in \l{WebEngine Widgets Simple Browser Example}
{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}.
+ \section1 Local Storage
+
+ \QWE supports saving key-value pairs in a \c {Local Storage} with no expiration date.
+ This is a part of the \l
+ {https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API}
+ {Web Storage API}, where a user can access a \c Storage object for the given domains
+ using the \c Window.localStorage JavaScript property. The stored data will persist even
+ after the page or the browser application is closed.
+
+ Note that the \c Local Storage can be also disabled with a
+ \l QWebEngineSettings::LocalStorageEnabled
+ setting. Moreover, the storage path can be adjusted with a
+ \l QWebEngineProfile::setPersistentStoragePath
+ call.
+
+ \code
+ QWebEngineProfile profile("MyProfile");
+ profile.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, isEnabled);
+ profile.setPersistentStoragePath("/path/to/storage");
+ \endcode
+
+ \QWE offers also an easy way of investigating the content of the \c {Local Storage}
+ with \l {Qt WebEngine Developer Tools} by visiting the \uicontrol Application panel
+ and expanding the \uicontrol {Local Storage} menu.
+
\section1 Native Dialogs
A web page might request dialogs for the following functions:
@@ -274,33 +458,6 @@
WebEngineView::colorDialogRequested(),
WebEngineView::fileDialogRequested(), and
WebEngineView::formValidationMessageRequested() signals. For an example,
- see \l{WebEngine Qt Quick Custom Dialogs Example}.
-
- \section1 Pepper Plugin API
-
- \QWE supports loading Pepper Plugin API (PPAPI) plugins if
- WebEngineSettings::pluginsEnabled or QWebEngineSettings::PluginsEnabled
- is set.
-
- 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.
-
- Support for this feature was added in Qt 5.6.0.
\section1 PDF File Viewing
@@ -532,6 +689,15 @@
This feature can be tested by building and running the
\l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}.
+ \QWE can be compiled also without spellchecker support with the use of
+ a \c {webengine-spellchecker} configure switch.
+
+ \badcode
+ qt-configure-module path\to\qtwebengine\sources -no-webengine-spellchecker
+ \endcode
+
+ For more information, see \l{Qt Configure Options}.
+
Support for this feature was added in Qt 5.8.0.
\section1 Touch
@@ -565,30 +731,19 @@
For opening the source view in the current tab, URLs with \l{view-source URI scheme}
are also supported. For example, you can type the following URL to the URL bar
to view the HTML source of the qt.io web page:
- \code
+ \badcode
view-source:https://www.qt.io/
\endcode
Auto-completion of incomplete URLs with \l{view-source URI scheme} makes the usage of
this feature more comfortable. For example, the following incomplete URL also loads
the source view of the qt.io web page:
- \code
+ \badcode
view-source:qt.io
\endcode
Support for this feature was added in Qt 5.8.0.
- \target webrtc_feature
- \section1 WebRTC
-
- WebRTC provides browsers with Real-Time Communications (RTC) capabilities
- via simple APIs. For more information, see \l{WebEngineView::Feature}
- {WebEngineView.Feature} and QWebEnginePage::Feature.
-
- This feature can be tested by setting up a webcam or microphone and then
- opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser
- Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}.
-
\section1 Web Notifications
Qt WebEngine supports JavaScript \l{Web Notifications API}.
@@ -598,41 +753,25 @@
Support for this feature was added in Qt 5.13.0.
- \section1 Favicon Handling
+ \section1 WebGL
- For accessing icons a \c QQuickImageProvider is registered. This provider can be
- accessed by a special URL where the scheme is "image:" and the host is "favicon".
- For example,
- \qml
- Image {
- source: "image://favicon/url"
- }
- \endqml
+ \QWE supports WebGL for some graphics stacks setups. A user can visit the
+ chrome://gpu page using the QtWebEngine powered application. The \e {Graphics Feature Status}
+ overview states if WebGL is supported for the current platform setup. A user can also
+ check the \l {https://webglreport.com}{WebGL Report}.
- The \c url can be the URL of the favicon. For example,
- \qml
- Image {
- source: "image://favicon/https://www.qt.io/hubfs/2016_Qt_Logo/qt_logo_green_rgb_16x16.png"
- }
- \endqml
+ The WebGL support is enabled by default. You can disable it with the
+ \l QWebEngineSettings::WebGLEnabled setting.
- The \c url also can be a page URL to access its icon. For example,
- \qml
- Image {
- source: "image://favicon/https://www.qt.io/"
- }
- \endqml
+ \target webrtc_feature
+ \section1 WebRTC
- If more than one icon is available, the \l {Image::sourceSize} property can be
- specified to choose the icon with the desired size. If \l {Image::sourceSize}
- is not specified or 0, the largest available icon will be chosen.
+ WebRTC provides browsers with Real-Time Communications (RTC) capabilities
+ via simple APIs. For more information, see \l{WebEngineView::Feature}
+ {WebEngineView.Feature}, and QWebEnginePage::Feature.
- The image provider looks up the requested icon in the existing \l {WebEngineView}
- instances. First, it tries to match the currently displayed icons. If no match
- has been found it requests the icon from the database. Each profile has its
- own icon database and it is stored in the persistent storage thus the stored icons
- can be accessed without network connection too. The icon must be previously loaded
- to be stored in the database.
+ This feature can be tested by setting up a webcam or microphone and then
+ opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser
+ Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}.
- \note The icon database is not available for off-the-record profiles.
*/
diff --git a/src/core/doc/src/qtwebengine-global.qdoc b/src/core/doc/src/qtwebengine-global.qdoc
new file mode 100644
index 000000000..7f6636c16
--- /dev/null
+++ b/src/core/doc/src/qtwebengine-global.qdoc
@@ -0,0 +1,56 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \headerfile <qtwebenginecoreglobal.h>
+ \inmodule QtWebEngineCore
+ \title Global Qt WebEngine Core Declarations
+ \ingroup funclists
+
+ \brief Helper functions for the \QWE Core module.
+
+*/
+
+
+/*!
+ \fn const char *qWebEngineVersion() noexcept
+ \relates <qtwebenginecoreglobal.h>
+ \since 6.2
+
+ Returns the version number of \QWE at run-time as a string
+ (for example, "6.2.0"). This may be a different version than the
+ version the application was compiled against, and a different version
+ than Qt.
+*/
+
+/*!
+ \fn const char *qWebEngineChromiumVersion() noexcept
+ \relates <qtwebenginecoreglobal.h>
+ \since 6.2
+
+ Returns the version number of Chromium used by \QWE at run-time
+ as a string (for example, "83.0.4103.122").
+*/
+
+/*!
+ \fn const char *qWebEngineChromiumSecurityPatchVersion() noexcept
+ \relates <qtwebenginecoreglobal.h>
+ \since 6.3
+
+ Returns the version number of last Chromium version security patches have been
+ merged from.
+*/
+
+/*!
+ \fn QString qWebEngineGetDomainAndRegistry(const QUrl &url)
+ \relates <qtwebenginecoreglobal.h>
+ \since 6.6
+
+ Returns the domain of the host, that is, the effective top-level domain
+ (eTLD) and the first domain below it, from \a url.
+
+ This function supports internationalized domain names (IDN). In this case,
+ it returns the domain encoded in Punycode.
+
+ If the host is not a domain, returns an empty string.
+*/
diff --git a/src/core/doc/src/qtwebengine-index.qdoc b/src/core/doc/src/qtwebengine-index.qdoc
index 4c1dedaa9..b20a96dc1 100644
--- a/src/core/doc/src/qtwebengine-index.qdoc
+++ b/src/core/doc/src/qtwebengine-index.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-index.html
diff --git a/src/core/doc/src/qtwebengine-modules.qdoc b/src/core/doc/src/qtwebengine-modules.qdoc
index 759284ad9..ee1ad8188 100644
--- a/src/core/doc/src/qtwebengine-modules.qdoc
+++ b/src/core/doc/src/qtwebengine-modules.qdoc
@@ -1,48 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-modules.html
\title Qt WebEngine C++ Classes and Namespaces
\brief Provides functionality for rendering regions of dynamic web content.
- \e {Qt WebEngine} provides functionality for rendering regions of dynamic web content.
+ \QWE provides functionality for rendering regions of dynamic web content.
\section1 Namespaces
\annotatedlist qtwebengine-namespaces
\section1 Classes
- \section2 Qt WebEngineCore Module
+ \section2 Qt WebEngine Core Module
\generatelist {classesbymodule QtWebEngineCore}
- \section2 Qt WebEngineWidgets Module
+ \section2 Qt WebEngine Widgets Module
\generatelist {classesbymodule QtWebEngineWidgets}
- \section2 Qt WebEngineQuick Module
+ \section2 Qt WebEngine Quick Module
\generatelist {classesbymodule QtWebEngineQuick}
+
*/
diff --git a/src/core/doc/src/qtwebengine-overview.qdoc b/src/core/doc/src/qtwebengine-overview.qdoc
index d7d5b50da..6eccc669e 100644
--- a/src/core/doc/src/qtwebengine-overview.qdoc
+++ b/src/core/doc/src/qtwebengine-overview.qdoc
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-overview.html
\title Qt WebEngine Overview
+ \ingroup explanations-webtechnologies
The \QWE 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.
@@ -82,6 +59,9 @@
The \QWE 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.
+ Even though the QtNetwork stack is not used, its setup can be synchronized with the \QWE.
+ See \l {Proxy Support}, \l {Managing Certificates}, \l {Client Certificates}, and
+ \l {QWebEngineCookieStore} for more details.
\note \QWE 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.
@@ -89,8 +69,20 @@
\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.
- This version of \QWE is based on Chromium version 90.0.4430, with additional security
- fixes from newer versions.
+ The Chromium version used is the one used by the latest stable Chrome version at the time of Qt feature freeze
+ for the current version of \QWE. Additional security patches are cherry picked from newer Chrome releases on
+ every patch release, security patches released in time for the Qt patch release freeze will be included.
+ If Chrome releases critical fixes outside our release window, the next patch release is sped up to ensure a
+ patched \QWE is released before the patch details goes public.
+
+ If you need a newer \QWE beyond security fixes, and can not update all of Qt, \QWE supports building with
+ older version of Qt back to the last Qt LTS. For instance \QWE 6.3, 6.4, and 6.5 can all be built with Qt 6.2.
+ In Qt LTS releases, \QWE may be fully replaced with such a newer version to make security patching easier.
+
+ The relevant Chromium versions in question can also be read at runtime using the
+ \l qWebEngineChromiumVersion() method, and \l qWebEngineChromiumSecurityPatchVersion()
+ to read the current security patch level. You can also find the versions in the \QWE
+ sources in the CHROMIUM_VERSION file.
\section2 Qt WebEngine Process
@@ -171,7 +163,7 @@
The following sample QML application loads a web page using the \l{WebEngineView::}{url}
property:
- \quotefromfile webenginequick/minimal/main.qml
+ \quotefromfile minimal/main.qml
\skipto import
\printuntil /^\}/
@@ -225,7 +217,7 @@
open SSL connections. Instead, \QWE uses the root CA certificates from the operating
system to validate the peer's certificate.
- The \l{WebEngineCertificateError::error} and \l{QWebEngineCertificateError::Type} enumerations
+ The \l{WebEngineCertificateError::type} and \l{QWebEngineCertificateError::Type} 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 connecting to the
QWebEnginePage::certificateError signal.
diff --git a/src/core/doc/src/qtwebengine-platform-notes.qdoc b/src/core/doc/src/qtwebengine-platform-notes.qdoc
index c94262950..33bac101a 100644
--- a/src/core/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/core/doc/src/qtwebengine-platform-notes.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebengine-platform-notes.html
@@ -35,7 +11,7 @@
Static builds are not supported.
- The requirements for building Qt 5 modules from source are listed separately for each supported
+ The requirements for building Qt modules from source are listed separately for each supported
platform:
\list
@@ -53,19 +29,17 @@
\li \l {macOS}
\endlist
- The tests for skipping the \QWE build are located in the
- \c qtwebengine repository, in the \c tools\qmake\mkspecs subdirectory.
- They can be found by searching for \c skipBuild.
-
\section2 All Platforms
On all platforms, the following tools are required at build time:
\list
- \li \l Python 2.7.5 or later. Python 3 is not supported.
+ \li C++20 compiler support
+ \li CMake 3.19 or newer
+ \li \l Python 3 with html5lib library
\li Bison, Flex
\li GPerf
- \li Node.js version 8 or later (version 12 or later is recommended)
+ \li Node.js version 14 or later
\endlist
\section2 Windows
@@ -73,22 +47,17 @@
On Windows, the following additional tools are required:
\list
- \li Visual Studio 2017 version 15.8 or later, or clang-cl version 8 or later
+ \li Visual Studio 2019 or later, or clang-cl version 10 or later
\li Active Template Library (ATL), usually included in the Visual Studio
installation
- \li Windows 10 SDK version 10.0.19041 or later
+ \li Windows 11 SDK version 10.0.22621.0 or later
\endlist
- \QWE can only be built on 64-bit Windows, with a x64-bit toolchain.
- For building \QWE for x86 applications, you need to configure
- and compile Qt with the Visual Studio 2017 x64 to x86 cross-compile
- toolchain. This toolchain can be set up on the command line by running
- \c{vcvarsall.bat amd64_x86}.
+ \note It is not recommended to use tools from \c msys2 or \c cygwin to build \QWE as it may result in build errors.
\section2 Linux
- On Linux, Clang or GCC version 5 or later is required.
- Supported configurations are \c linux-g++, \c{linux-clang} and \c{linux-clang-libc++}
+ On Linux, Clang or GCC version 9 or later is required.
\QWE requires \c pkg-config to detect most of its dependencies. The
following \c pkg-config files are required:
@@ -111,16 +80,14 @@
\li \c xtst
\endlist
- Further, development packages for \c khr and \c libcap need to be installed.
-
\section2 \macos
On \macos, the following are required:
\list
- \li \macos 10.13 or later
- \li Xcode 10.0 or later
- \li \macos 10.13 SDK or later
+ \li \macos 10.14 or later
+ \li Xcode 12.0 or later
+ \li \macos 11 SDK or later
\endlist
\note \QWE cannot be built for the 32-bit mode of \macos (using the
@@ -129,8 +96,8 @@
\section1 Using Earlier Qt Versions to Build \QWE
Building \QWE with earlier Qt versions (down to the last LTS
- version) is supported. It means that \QWE 5.15 can be built with
- Qt 5.12.x, Qt 5.14.x, and Qt 5.15.
+ version) is supported. It means that \QWE 6.4 can be built with
+ Qt 6.2.x, Qt 6.3.x, and Qt 6.4.
To use an earlier Qt version to build Qt Webengine:
@@ -221,16 +188,36 @@
or VoiceOver on \macos.
\endlist
- Due to some limitations, the Linux QPA plugin almost always reports that accessibility should
- be activated. On big HTML pages, this can cause a significant slowdown in rendering speed.
+ On some old Linux configurations, accessibility can cause a significant slowdown
+ on large HTML pages.
- Because of that, from Qt 5.9 onwards, \QWE accessibility support is disabled by default
- on Linux.
- It can be re-enabled by setting the \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
- variable to a non-empty value.
+ Because of that, \QWE accessibility support can be disabled on Linux, by setting the
+ \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0.
\section1 Popups in Fullscreen Applications on Windows
Because of a limitation in the Windows compositor, applications that show a fullscreen web
engine view will not properly display popups or other top-level windows. The reason and
workaround is described in \l {Fullscreen OpenGL Based Windows}.
+
+ \target windows_manifest
+ \section1 Windows Application Manifest
+ A manifest is an XML file that is read when the program starts and informs Windows how to run the program.
+ Some \QWE features may require adding a manifest file for the user application to work correctly on Windows.
+
+ The following snippets show the manifest file's structure and how to embed it into the program.
+
+ \note These code snippets are taken from the \l {WebEngine Quick Nano Browser} example.
+
+ The manifest file defines which Windows versions the application supports.
+ \l {QWebEngineProfile::} {httpUserAgent} needs this information to report the correct Windows version.
+ \quotefile ../../../../examples/webenginequick/quicknanobrowser/quicknanobrowser.exe.manifest
+
+ To embed the file into the executable, add it to the sources:
+ \quotefromfile ../../../../examples/webenginequick/quicknanobrowser/CMakeLists.txt
+ \skipto qt_add_executable
+ \dots
+ \printuntil endif
+ \dots
+
+ For more information, see the \l {https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests} {Application manifest documentation page}.
*/
diff --git a/src/core/doc/src/qtwebenginecore-index.qdoc b/src/core/doc/src/qtwebenginecore-index.qdoc
index 0fdde2257..e6fc0b307 100644
--- a/src/core/doc/src/qtwebenginecore-index.qdoc
+++ b/src/core/doc/src/qtwebenginecore-index.qdoc
@@ -1,45 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebenginecore-index.html
\title Qt WebEngine Core
- \brief Provides common API shared by \QWE and \QWE Widgets.
+ \brief Provides common API shared by \QWE Quick and \QWE Widgets.
- \QWE Core provides API shared by \l {Qt WebEngine} and \l {Qt WebEngine Widgets}.
+ \QWE Core provides API shared by \l {Qt WebEngine QML Types}{Qt WebEngine Quick} and
+ \l {Qt WebEngine Widgets C++ Classes}{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
diff --git a/src/core/doc/src/qtwebenginecore-module.qdoc b/src/core/doc/src/qtwebenginecore-module.qdoc
index 033d81116..188609793 100644
--- a/src/core/doc/src/qtwebenginecore-module.qdoc
+++ b/src/core/doc/src/qtwebenginecore-module.qdoc
@@ -1,48 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\module QtWebEngineCore
\title Qt WebEngine Core C++ Classes
- \brief Provides public API shared by both QtWebEngine and QtWebEngineWidgets.
+ \brief Provides public API shared by both QtWebEngineQuick and QtWebEngineWidgets.
\since 5.6
\ingroup qtwebengine-modules
\ingroup modules
\qtvariable webenginecore
\qtcmakepackage WebEngineCore
- 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, \QWE Core is usually
- indirectly included through the \l{Qt WebEngine QML Types}{Qt WebEngine} or
+ indirectly included through the \l{Qt WebEngine QML Types}{Qt WebEngine Quick} or
\l{Qt WebEngine Widgets C++ Classes}{Qt WebEngine Widgets} modules.
\if !defined(qtforpython)
diff --git a/src/core/doc/src/qwebengine-licensing.qdoc b/src/core/doc/src/qwebengine-licensing.qdoc
index f6a0a6c32..796a9664d 100644
--- a/src/core/doc/src/qwebengine-licensing.qdoc
+++ b/src/core/doc/src/qwebengine-licensing.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\group qtwebengine-licensing
@@ -38,11 +14,16 @@ respect the licenses of Chromium, and third-party code included in
Chromium. The arguably most restrictive license to be respected by
all users is LGPLv2.1.
+\note Any GPL licenses listed below are only used to access Linux system
+resources. \QWE does not link to nor distribute GPL binary code, and
+it does not affect users of \QWE.
+
Third party licenses included in the sources are:
*/
/*!
-\page qtwebengine-3rdparty-chromium-global.html attribution
+\page qtwebengine-3rdparty-chromium-global.html
+\attribution
\ingroup qtwebengine-licensing
\title Chromium License
\brief BSD
diff --git a/src/core/doc/src/qwebenginehistory_lgpl.qdoc b/src/core/doc/src/qwebenginehistory_lgpl.qdoc
index 37f96e7c1..f61bb3b85 100644
--- a/src/core/doc/src/qwebenginehistory_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginehistory_lgpl.qdoc
@@ -1,22 +1,6 @@
-/*
- Copyright (C) 2015 The Qt Company Ltd.
- Copyright (C) 2008 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.
-*/
+// Copyright (C) 2015 The Qt Company Ltd.
+// Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// The documentation in this file was imported from QtWebKit and is thus constrained
// by its LGPL license. Documentation written from scratch for new methods should be
diff --git a/src/core/doc/src/qwebenginepage_lgpl.qdoc b/src/core/doc/src/qwebenginepage_lgpl.qdoc
index 43195deb2..c2515cd13 100644
--- a/src/core/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginepage_lgpl.qdoc
@@ -1,24 +1,8 @@
-/*
- Copyright (C) 2019 The Qt Company Ltd.
- Copyright (C) 2008, 2009, 2012 Nokia Corporation and/or its subsidiary(-ies)
- Copyright (C) 2007 Staikos Computing Services Inc.
- Copyright (C) 2007 Apple Inc.
-
- 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.
-*/
+// Copyright (C) 2019 The Qt Company Ltd.
+// Copyright (C) 2008, 2009, 2012 Nokia Corporation and/or its subsidiary(-ies)
+// Copyright (C) 2007 Staikos Computing Services Inc.
+// Copyright (C) 2007 Apple Inc.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// The documentation in this file was imported from QtWebKit and is thus constrained
// by its LGPL license. Documentation written from scratch for new methods should be
@@ -131,85 +115,86 @@
should be enabled to get automatic focus.
\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. Requires implementation of
- \l createWindow() or \l newWindowRequested() (Added in Qt 5.6)
- \value OpenLinkInNewTab Open the current link in a new tab. Requires implementation of
- \l createWindow() or \l newWindowRequested(). (Added in Qt 5.6)
- \value OpenLinkInNewBackgroundTab Open the current link in a new background tab. Requires
- implementation of \l createWindow() or \l newWindowRequested(). (Added in Qt 5.7)
- \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. Requires a slot for
- \l{QWebEngineProfile::}{downloadRequested()}. (Added in Qt 5.6)
- \value DownloadImageToDisk Download the highlighted image to the disk. Requires a slot for
- \l{QWebEngineProfile::}{downloadRequested()}. (Added in Qt 5.6)
- \value DownloadMediaToDisk Download the hovered audio or video to the disk. Requires a slot for
- \l{QWebEngineProfile::}{downloadRequested()}. (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}
+ \value [since 5.6] OpenLinkInThisWindow Open the current link in the current window.
+ \value [since 5.6] OpenLinkInNewWindow Open the current link in a new window. Requires implementation of
+ \l createWindow() or \l newWindowRequested().
+ \value [since 5.6] OpenLinkInNewTab Open the current link in a new tab. Requires implementation of
+ \l createWindow() or \l newWindowRequested().
+ \value [since 5.7] OpenLinkInNewBackgroundTab Open the current link in a new background tab. Requires
+ implementation of \l createWindow() or \l newWindowRequested().
+ \value [since 5.6] CopyLinkToClipboard Copy the current link to the clipboard.
+
+ \value [since 5.6] CopyImageToClipboard Copy the clicked image to the clipboard.
+ \value [since 5.6] CopyImageUrlToClipboard Copy the clicked image's URL to the clipboard.
+ \value [since 5.6] CopyMediaUrlToClipboard Copy the hovered audio or video's URL to the clipboard.
+ \value [since 5.6] ToggleMediaControls Toggle between showing and hiding the controls for the hovered audio
+ or video element.
+ \value [since 5.6] ToggleMediaLoop Toggle whether the hovered audio or video should loop on completetion or
+ not.
+ \value [since 5.6] ToggleMediaPlayPause Toggle the play/pause state of the hovered audio or video element.
+ \value [since 5.6] ToggleMediaMute Mute or unmute the hovered audio or video element.
+ \value [since 5.6] DownloadLinkToDisk Download the current link to the disk. Requires a slot for
+ \l{QWebEngineProfile::}{downloadRequested()}.
+ \value [since 5.6] DownloadImageToDisk Download the highlighted image to the disk. Requires a slot for
+ \l{QWebEngineProfile::}{downloadRequested()}.
+ \value [since 5.6] DownloadMediaToDisk Download the hovered audio or video to the disk. Requires a slot for
+ \l{QWebEngineProfile::}{downloadRequested()}.
+
+ \value [since 5.6] InspectElement Trigger any attached Web Inspector to inspect the highlighed element.
+ \value [since 5.6] ExitFullScreen Exit the fullscreen mode.
+ \value [since 5.6] 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)
- \value Unselect Clear the current selection. (Added in Qt 5.7)
- \value SavePage Save the current page to disk. MHTML is the default format that is used to store
+ request is confirmed, \c windowCloseRequested is emitted.
+ \value [since 5.7] Unselect Clear the current selection.
+ \value [since 5.7] SavePage Save the current page to disk. MHTML is the default format that is used to store
the web page on disk. Requires a slot for \l{QWebEngineProfile::}{downloadRequested()}.
- (Added in Qt 5.7)
- \value ViewSource Show the source of the current page in a new tab. Requires implementation of
- \l createWindow() or \l newWindowRequested(). (Added in Qt 5.8)
+ \value [since 5.8] ViewSource Show the source of the current page in a new tab. Requires implementation of
+ \l createWindow() or \l newWindowRequested().
- \value ToggleBold
+ \value [since 5.10] ToggleBold
Toggles boldness for the selection or at the cursor position.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value ToggleItalic
+ Requires \c contenteditable="true".
+ \value [since 5.10] ToggleItalic
Toggles italics for the selection or at the cursor position.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value ToggleUnderline
+ Requires \c contenteditable="true".
+ \value [since 5.10] ToggleUnderline
Toggles underlining of the selection or at the cursor position.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value ToggleStrikethrough
+ Requires \c contenteditable="true".
+ \value [since 5.10] ToggleStrikethrough
Toggles striking through the selection or at the cursor position.
- Requires \c contenteditable="true". (Added in Qt 5.10)
+ Requires \c contenteditable="true".
- \value AlignLeft
+ \value [since 5.10] AlignLeft
Aligns the lines containing the selection or the cursor to the left.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value AlignCenter
+ Requires \c contenteditable="true".
+ \value [since 5.10] AlignCenter
Aligns the lines containing the selection or the cursor at the center.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value AlignRight
+ Requires \c contenteditable="true".
+ \value [since 5.10] AlignRight
Aligns the lines containing the selection or the cursor to the right.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value AlignJustified
+ Requires \c contenteditable="true".
+ \value [since 5.10] AlignJustified
Stretches the lines containing the selection or the cursor so that each
line has equal width.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value Indent
+ Requires \c contenteditable="true".
+ \value [since 5.10] Indent
Indents the lines containing the selection or the cursor.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value Outdent
+ Requires \c contenteditable="true".
+ \value [since 5.10] Outdent
Outdents the lines containing the selection or the cursor.
- Requires \c contenteditable="true". (Added in Qt 5.10)
+ Requires \c contenteditable="true".
- \value InsertOrderedList
+ \value [since 5.10] InsertOrderedList
Inserts an ordered list at the current cursor position, deleting the current selection.
- Requires \c contenteditable="true". (Added in Qt 5.10)
- \value InsertUnorderedList
+ Requires \c contenteditable="true".
+ \value [since 5.10] InsertUnorderedList
Inserts an unordered list at the current cursor position,
deleting the current selection.
- Requires \c contenteditable="true". (Added in Qt 5.10)
+ Requires \c contenteditable="true".
+ \value [since 6.6] ChangeTextDirectionLTR
+ Changes text direction to left-to-right in the focused input element.
+ \value [since 6.6] ChangeTextDirectionRTL
+ Changes text direction to right-to-left in the focused input element.
\omitvalue WebActionCount
*/
@@ -225,8 +210,8 @@
A web browser tab.
\value WebDialog
A window without decoration.
- \value WebBrowserBackgroundTab
- A web browser tab without hiding the current visible WebEngineView. (Added in Qt 5.7)
+ \value [since 5.7] WebBrowserBackgroundTab
+ A web browser tab without hiding the current visible WebEngineView.
*/
/*!
@@ -252,6 +237,8 @@
Return multiple file names.
\value FileSelectUploadFolder
Allows users to specify a single existing folder for upload.
+ \value FileSelectSave
+ Specify a new file to be created.
\sa chooseFiles()
*/
@@ -278,7 +265,7 @@
\value NavigationTypeFormSubmitted The navigation request resulted from a form submission.
\value NavigationTypeBackForward The navigation request resulted from a back or forward action.
\value NavigationTypeReload The navigation request resulted from a reload action.
- \value NavigationTypeRedirect The navigation request resulted from a content or server controlled redirect. This also includes automatic reloads. (Added in Qt 5.14)
+ \value [since 5.14] NavigationTypeRedirect The navigation request resulted from a content or server controlled redirect. This also includes automatic reloads.
\value NavigationTypeOther The navigation request was triggered by other means not covered by the above.
\sa acceptNavigationRequest()
@@ -303,11 +290,18 @@
\value MouseLock
Mouse locking, which locks the mouse pointer to the web view and is typically used in
games.
- \value DesktopVideoCapture
+ \value [since 5.10] DesktopVideoCapture
Video output capture, that is, the capture of the user's display,
- for screen sharing purposes for example. (Added in Qt 5.10)
- \value DesktopAudioVideoCapture
- Both audio and video output capture. (Added in Qt 5.10)
+ for screen sharing purposes for example.
+ \value [since 5.10] DesktopAudioVideoCapture
+ Both audio and video output capture.
+ \value [since 6.8] ClipboardReadWrite
+ Read and write access for the clipboard. If both \l{QWebEngineSettings::JavascriptCanPaste}
+ {JavascriptCanPaste} and \l{QWebEngineSettings::JavascriptCanAccessClipboard}
+ {JavascriptCanAccessClipboard} settings are enabled, this permission will always be granted
+ automatically and no feature requests will be made.
+ \value [since 6.8] LocalFontsAccess
+ Access to the fonts installed on the user's machine. Only available on desktop platforms.
\sa featurePermissionRequested(), featurePermissionRequestCanceled(), setFeaturePermission(), PermissionPolicy
@@ -465,6 +459,9 @@
The action is owned by the QWebEnginePage but you can customize the look by
changing its properties.
+ \l{QWebEnginePage::action(WebAction action)} does not have a default styled icon.
+ Use \l{QWebEngineView::pageAction()} to have an action with a default styled icon.
+
QWebEnginePage also takes care of implementing the action, so that upon
triggering the corresponding action is performed on the page.
@@ -720,6 +717,7 @@
is empty, it is assumed that the content is \c{text/plain,charset=US-ASCII}.
External objects referenced in the content are located relative to \a baseUrl.
+ For external objects with relative URLs to be loaded, \c baseUrl cannot be empty.
The \a data is loaded immediately; external objects are loaded asynchronously.
@@ -826,3 +824,15 @@
\sa url()
*/
+
+/*!
+ \fn void QWebEnginePage::webAuthUxRequested(QWebEngineWebAuthUxRequest *request);
+ \since 6.7
+
+ This signal is emitted when a WebAuth authenticator needs user interaction
+ during the authentication process. These requests are handled by displaying a dialog to the user.
+
+ The \a request contains the information and API required to complete the WebAuth UX request.
+
+ \sa QWebEngineWebAuthUxRequest
+*/
diff --git a/src/core/doc/src/qwebenginesettings_lgpl.qdoc b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
index bfe2713a2..cd7ff8e8c 100644
--- a/src/core/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
@@ -1,22 +1,6 @@
-/*
- Copyright (C) 2015 The Qt Company Ltd.
- Copyright (C) 2008 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.
-*/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// The documentation in this file was imported from QtWebKit and is thus constrained
// by its LGPL license. Documentation written from scratch for new methods should be
@@ -31,8 +15,8 @@
\inmodule QtWebEngineCore
QWebEngineSettings allows configuration of browser properties, such as font sizes and
- families, the location of a custom style sheet, and generic attributes, such as JavaScript
- support. Individual attributes are set using the setAttribute() function. The
+ families, and generic attributes, such as JavaScript support.
+ Individual attributes are set using the setAttribute() function. The
\l{QWebEngineSettings::WebAttribute}{WebAttribute} enum further describes each attribute.
Each QWebEnginePage object has its own QWebEngineSettings object, which configures the
@@ -56,7 +40,7 @@
\value CursiveFont
\value FantasyFont
\value PictographFont
- (added in Qt 5.7)
+ (added in Qt 5.7, deprecated Qt 6.4)
*/
/*!
@@ -89,19 +73,18 @@
Allows JavaScript programs to read from and write to the clipboard.
Writing to the clipboard is always allowed if it is specifically requested by the user.
See JavascriptCanPaste to also allow pasting the content of the clipboard content from
- JavaScript.
+ JavaScript. Since unrestricted clipboard access is a potential security concern, it is
+ recommended that applications leave this disabled and instead respond to
+ \l{QWebEnginePage::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
Disabled by default.
\value LinksIncludedInFocusChain
Includes hyperlinks in the keyboard focus chain. Enabled by default.
\value LocalStorageEnabled
Enables support for the HTML 5 local storage feature. Enabled by default.
\value LocalContentCanAccessRemoteUrls
- Allows locally loaded documents to ignore cross-origin rules so that they can access
- remote resources that would normally be blocked, since remote resources are
- considered cross-origin for a local document. Remote access that would not be blocked by
- cross-origin rules is still possible when this setting is disabled (default).
- Note that disabling this setting does not prevent media elements in local files from
- accessing remote content. Disabled by default.
+ Allows local origin documents to access remote resources that would normally be blocked.
+ Disabled by default. Note DnsPrefetchEnabled below operates independently of this setting,
+ and can if enabled, cause remote accesses from local content.
\value XSSAuditingEnabled
Obsolete and has no effect.
\value SpatialNavigationEnabled
@@ -170,8 +153,11 @@
similar to Chrome on desktops. To overwrite the default behavior,
disable this setting. (Added in Qt 5.11)
\value JavascriptCanPaste
- Enables JavaScript \c{execCommand("paste")}. This also requires
- enabling JavascriptCanAccessClipboard.
+ Enables JavaScript \c{execCommand("paste")}. This also requires enabling
+ JavascriptCanAccessClipboard. Since unrestricted clipboard access is a potential
+ security concern, it is recommended that applications leave this disabled
+ and instead respond to \l{QWebEnginePage::ClipboardReadWrite}{ClipboardReadWrite}
+ feature permission requests.
Disabled by default. (Added in Qt 5.11)
\value WebRTCPublicInterfacesOnly
Limits WebRTC to public IP addresses only. When disabled WebRTC may also use
@@ -184,6 +170,16 @@
\value PdfViewerEnabled Specifies that PDF documents will be opened in the internal PDF viewer
instead of being downloaded.
Enabled by default. (Added in Qt 5.13)
+ \value NavigateOnDropEnabled Specifies that navigations can be triggered by dropping URLs on
+ the view.
+ Enabled by default. (Added in Qt 6.4)
+ \value ReadingFromCanvasEnabled Specifies that reading from all canvas elements is enabled.
+ This setting will have impact on all HTML5 canvas elements irrespective of origin, and can be disabled
+ to prevent canvas fingerprinting.
+ Enabled by default. (Added in Qt 6.6)
+ \value ForceDarkMode Specifies that all web contents will be rendered using a dark theme.
+ For more information, see \l{https://developer.chrome.com/blog/auto-dark-theme/}{Auto dark theme}.
+ Disabled by default. (Added in Qt 6.7)
*/
/*!
@@ -206,6 +202,24 @@
*/
/*!
+ \enum QWebEngineSettings::ImageAnimationPolicy
+ \since Qt 6.8
+
+ This enum describes how an image animation should be handled when the image frames
+ are rendered for animation.
+
+ \value AllowImageAnimation
+ Allows image animation when the image frames are rendered.
+ \value AnimateImageOnce
+ Animate the image once when the image frames are rendered.
+ \value DisallowImageAnimation
+ Disallows image animation when the image frames are rendered.
+ \omitvalue InheritedImageAnimationPolicy
+
+ \sa imageAnimationPolicy setImageAnimationPolicy resetImageAnimationPolicy
+*/
+
+/*!
\fn void QWebEngineSettings::setFontSize(FontSize type, int size)
Sets the font size for \a type to \a size in pixels.
*/
@@ -293,3 +307,26 @@
Resets the setting of \a attribute to the value specified in the
profile that the page belongs to.
*/
+
+/*!
+ \fn QWebEngineSettings::ImageAnimationPolicy QWebEngineSettings::imageAnimationPolicy() const
+ \since Qt 6.8
+ Returns the currently selected policy for handling image animation when the image frames are rendered.
+ Default is \l{QWebEngineSettings::AllowImageAnimation}.
+ \sa setImageAnimationPolicy resetImageAnimationPolicy
+*/
+
+/*!
+ \fn void QWebEngineSettings::setImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy)
+ \since Qt 6.8
+ Sets the policy for handling image animation when the image frames are rendered to \a policy.
+ Default is \l{QWebEngineSettings::AllowImageAnimation}.
+ \sa imageAnimationPolicy resetImageAnimationPolicy
+*/
+
+/*!
+ \fn void QWebEngineSettings::resetImageAnimationPolicy()
+ \since Qt 6.7
+ Removes the policy for handling image animation.
+ \sa imageAnimationPolicy setImageAnimationPolicy
+*/
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 58f6507a7..c0fd0d3ee 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -1,46 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "download_manager_delegate_qt.h"
-#include "base/files/file_util.h"
-#include "base/time/time_to_iso8601.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/save_page_type.h"
@@ -49,9 +11,7 @@
#include "net/http/http_content_disposition.h"
#include <QDir>
-#include <QFile>
#include <QFileInfo>
-#include <QMap>
#include <QMimeDatabase>
#include <QStandardPaths>
@@ -83,7 +43,7 @@ void DownloadManagerDelegateQt::GetNextId(content::DownloadIdCallback callback)
download::DownloadItem *DownloadManagerDelegateQt::findDownloadById(quint32 downloadId)
{
- content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_profileAdapter->profile());
+ content::DownloadManager *dlm = m_profileAdapter->profile()->GetDownloadManager();
return dlm->GetDownload(downloadId);
}
@@ -94,14 +54,18 @@ void DownloadManagerDelegateQt::cancelDownload(content::DownloadTargetCallback c
download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
download::DownloadItem::UNKNOWN,
base::FilePath(),
- base::nullopt,
+ base::FilePath(),
+ std::string(),
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
}
-void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
+bool DownloadManagerDelegateQt::cancelDownload(quint32 downloadId)
{
- if (download::DownloadItem *download = findDownloadById(downloadId))
+ if (download::DownloadItem *download = findDownloadById(downloadId)) {
download->Cancel(/* user_cancel */ true);
+ return true;
+ }
+ return false;
}
void DownloadManagerDelegateQt::pauseDownload(quint32 downloadId)
@@ -135,14 +99,43 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download::DownloadItem::VALIDATED,
item->GetForcedFilePath(),
- base::nullopt,
+ item->GetFileNameToReportUser(),
+ item->GetMimeType(),
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
return true;
}
- QString suggestedFilename = toQt(item->GetSuggestedFilename());
+ bool acceptedByDefault = false;
+ QString suggestedFilePath;
+ QString suggestedFilename;
+ bool isSavePageDownload = false;
+ WebContentsAdapterClient *adapterClient = nullptr;
+ if (content::WebContents *webContents = content::DownloadItemUtils::GetWebContents(item)) {
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate());
+ adapterClient = contentsDelegate->adapterClient();
+ if (SavePageInfo *spi = contentsDelegate->savePageInfo()) {
+ // We end up here when saving non text-based files (MHTML, PDF or images)
+ suggestedFilePath = spi->requestedFilePath;
+ const QFileInfo fileInfo(suggestedFilePath);
+ if (fileInfo.isRelative()) {
+ const QDir downloadDir(m_profileAdapter->downloadPath());
+ suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath);
+ }
+ suggestedFilename = fileInfo.fileName();
+
+ if (!suggestedFilePath.isEmpty() && !suggestedFilename.isEmpty())
+ acceptedByDefault = true;
+ isSavePageDownload = true;
+
+ // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved.
+ contentsDelegate->setSavePageInfo(nullptr);
+ }
+ }
+
QString mimeTypeString = toQt(item->GetMimeType());
+ if (suggestedFilename.isEmpty())
+ suggestedFilename = toQt(item->GetSuggestedFilename());
if (suggestedFilename.isEmpty())
suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), net::kCharsetLatin1).filename());
@@ -165,16 +158,12 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
QDir defaultDownloadDirectory(m_profileAdapter->downloadPath());
- QString suggestedFilePath = m_profileAdapter->determineDownloadPath(defaultDownloadDirectory.absolutePath(), suggestedFilename, item->GetStartTime().ToTimeT());
+ if (suggestedFilePath.isEmpty())
+ suggestedFilePath = m_profileAdapter->determineDownloadPath(defaultDownloadDirectory.absolutePath(), suggestedFilename, item->GetStartTime().ToTimeT());
item->AddObserver(this);
QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
if (!clients.isEmpty()) {
- content::WebContents *webContents = content::DownloadItemUtils::GetWebContents(item);
- WebContentsAdapterClient *adapterClient = nullptr;
- if (webContents)
- adapterClient = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->adapterClient();
-
Q_ASSERT(m_currentId == item->GetId());
ProfileAdapterClient::DownloadItemInfo info = {
item->GetId(),
@@ -185,17 +174,17 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
mimeTypeString,
suggestedFilePath,
ProfileAdapterClient::UnknownSavePageFormat,
- false /* accepted */,
+ acceptedByDefault,
false /* paused */,
false /* done */,
- false /* isSavePageDownload */,
+ isSavePageDownload,
item->GetLastReason(),
adapterClient,
suggestedFilename,
item->GetStartTime().ToTimeT()
};
- for (ProfileAdapterClient *client : qAsConst(clients)) {
+ for (ProfileAdapterClient *client : std::as_const(clients)) {
client->downloadRequested(info);
if (info.accepted)
break;
@@ -204,14 +193,14 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
QFileInfo suggestedFile(info.path);
if (info.accepted && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
// TODO: Remove this when https://bugreports.qt.io/browse/QTBUG-85997 is fixed.
QDir suggestedDir = QDir(suggestedFile.absolutePath());
if (!suggestedDir.isRoot() || !suggestedDir.exists()) {
#endif
qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data());
info.accepted = false;
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
}
#endif
}
@@ -227,7 +216,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *
download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
download::DownloadItem::VALIDATED,
filePathForCallback.AddExtension(toFilePathString("download")),
- base::nullopt,
+ base::FilePath(),
+ item->GetMimeType(),
download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE);
} else
cancelDownload(std::move(*callback));
@@ -257,12 +247,18 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
if (clients.isEmpty())
return;
+ bool acceptedByDefault = false;
+ QString suggestedFilePath;
+ ProfileAdapterClient::SavePageFormat suggestedSaveFormat = ProfileAdapterClient::UnknownSavePageFormat;
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
web_contents->GetDelegate());
- const SavePageInfo &spi = contentsDelegate->savePageInfo();
+ if (SavePageInfo *spi = contentsDelegate->savePageInfo()) {
+ suggestedFilePath = spi->requestedFilePath;
+ suggestedSaveFormat = static_cast<ProfileAdapterClient::SavePageFormat>(spi->requestedFormat);
+ // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved.
+ contentsDelegate->setSavePageInfo(nullptr);
+ }
- bool acceptedByDefault = false;
- QString suggestedFilePath = spi.requestedFilePath;
if (suggestedFilePath.isEmpty()) {
suggestedFilePath = QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName()
+ QStringLiteral(".mhtml");
@@ -274,14 +270,9 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath);
}
- ProfileAdapterClient::SavePageFormat suggestedSaveFormat
- = static_cast<ProfileAdapterClient::SavePageFormat>(spi.requestedFormat);
if (suggestedSaveFormat == ProfileAdapterClient::UnknownSavePageFormat)
suggestedSaveFormat = ProfileAdapterClient::MimeHtmlSaveFormat;
- // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved.
- contentsDelegate->setSavePageInfo(SavePageInfo());
-
WebContentsAdapterClient *adapterClient = nullptr;
if (web_contents)
adapterClient = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())->adapterClient();
@@ -291,7 +282,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
++m_currentId,
toQt(web_contents->GetURL()),
download::DownloadItem::IN_PROGRESS,
- 0, /* totalBytes */
+ -1, /* totalBytes */
0, /* receivedBytes */
QStringLiteral("application/x-mimearchive"),
suggestedFilePath,
@@ -306,7 +297,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
QDateTime::currentMSecsSinceEpoch()
};
- for (ProfileAdapterClient *client : qAsConst(clients)) {
+ for (ProfileAdapterClient *client : std::as_const(clients)) {
client->downloadRequested(info);
if (info.accepted)
break;
@@ -316,8 +307,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
return;
std::move(callback).Run(toFilePath(info.path), static_cast<content::SavePageType>(info.savePageFormat),
- base::Bind(&DownloadManagerDelegateQt::savePackageDownloadCreated,
- m_weakPtrFactory.GetWeakPtr()));
+ base::BindOnce(&DownloadManagerDelegateQt::savePackageDownloadCreated,
+ m_weakPtrFactory.GetWeakPtr()));
}
void DownloadManagerDelegateQt::savePackageDownloadCreated(download::DownloadItem *item)
@@ -354,7 +345,7 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(download::DownloadItem *downlo
download->GetStartTime().ToTimeT()
};
- for (ProfileAdapterClient *client : qAsConst(clients)) {
+ for (ProfileAdapterClient *client : std::as_const(clients)) {
client->downloadUpdated(info);
}
}
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index 7b8de08df..cc6d49764 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DOWNLOAD_MANAGER_DELEGATE_QT_H
#define DOWNLOAD_MANAGER_DELEGATE_QT_H
@@ -60,8 +24,6 @@ class DownloadItem;
namespace QtWebEngineCore {
class ProfileAdapter;
-class DownloadManagerDelegateInstance;
-class DownloadTargetHelper;
class DownloadManagerDelegateQt
: public content::DownloadManagerDelegate
@@ -84,7 +46,7 @@ public:
bool can_save_as_complete,
content::SavePackagePathPickedCallback callback) override;
- void cancelDownload(quint32 downloadId);
+ bool cancelDownload(quint32 downloadId);
void pauseDownload(quint32 downloadId);
void resumeDownload(quint32 downloadId);
void removeDownload(quint32 downloadId);
@@ -101,11 +63,8 @@ private:
uint32_t m_currentId;
base::WeakPtrFactory<DownloadManagerDelegateQt> m_weakPtrFactory;
-
- friend class DownloadManagerDelegateInstance;
- DISALLOW_COPY_AND_ASSIGN(DownloadManagerDelegateQt);
};
} // namespace QtWebEngineCore
-#endif //DOWNLOAD_MANAGER_DELEGATE_QT_H
+#endif // DOWNLOAD_MANAGER_DELEGATE_QT_H
diff --git a/src/core/extensions/component_extension_resource_manager_qt.cpp b/src/core/extensions/component_extension_resource_manager_qt.cpp
index 2b6a24541..428f673d3 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.cpp
+++ b/src/core/extensions/component_extension_resource_manager_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/browser/extensions/chrome_component_extension_resource_manager.cc:
// Copyright 2014 The Chromium Authors. All rights reserved.
@@ -45,7 +9,7 @@
#include "component_extension_resource_manager_qt.h"
#include "base/check.h"
-#include "base/logging.h"
+#include "base/containers/contains.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/values.h"
@@ -73,12 +37,12 @@ ComponentExtensionResourceManagerQt::ComponentExtensionResourceManagerQt()
AddComponentResourceEntries(kPdfResources, kPdfResourcesSize);
#endif
#if BUILDFLAG(ENABLE_PDF)
- base::Value dict(base::Value::Type::DICTIONARY);
+ base::Value::Dict dict;
pdf_extension_util::AddStrings(pdf_extension_util::PdfViewerContext::kPdfViewer, &dict);
- pdf_extension_util::AddAdditionalData(&dict);
+ pdf_extension_util::AddAdditionalData(/*enable_annotations=*/true, &dict);
ui::TemplateReplacements pdf_viewer_replacements;
- ui::TemplateReplacementsFromDictionaryValue(base::Value::AsDictionaryValue(dict), &pdf_viewer_replacements);
+ ui::TemplateReplacementsFromDictionaryValue(dict, &pdf_viewer_replacements);
template_replacements_[extension_misc::kPdfExtensionId] = std::move(pdf_viewer_replacements);
#endif
}
diff --git a/src/core/extensions/component_extension_resource_manager_qt.h b/src/core/extensions/component_extension_resource_manager_qt.h
index b029a7f71..4da18890e 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.h
+++ b/src/core/extensions/component_extension_resource_manager_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -47,7 +11,6 @@
#include <map>
#include "base/files/file_path.h"
-#include "base/macros.h"
#include "extensions/browser/component_extension_resource_manager.h"
#include "ui/base/webui/resource_path.h"
@@ -74,8 +37,6 @@ private:
// A map from an extension ID to its i18n template replacements.
std::map<std::string, ui::TemplateReplacements> template_replacements_;
-
- DISALLOW_COPY_AND_ASSIGN(ComponentExtensionResourceManagerQt);
};
} // namespace extensions
diff --git a/src/core/extensions/extension_host_delegate_qt.cpp b/src/core/extensions/extension_host_delegate_qt.cpp
index 4db1aeb71..aa408a544 100644
--- a/src/core/extensions/extension_host_delegate_qt.cpp
+++ b/src/core/extensions/extension_host_delegate_qt.cpp
@@ -1,48 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "extension_host_delegate_qt.h"
+
+#include "desktop_media_controller.h"
+#include "desktop_media_controller_p.h"
#include "extension_web_contents_observer_qt.h"
#include "media_capture_devices_dispatcher.h"
#include "extension_system_qt.h"
+#include "web_contents_view_qt.h"
+#include "base/functional/callback.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "extensions/browser/extension_host.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
+
+using namespace QtWebEngineCore;
namespace extensions {
@@ -69,26 +43,47 @@ content::JavaScriptDialogManager *ExtensionHostDelegateQt::GetJavaScriptDialogMa
void ExtensionHostDelegateQt::CreateTab(std::unique_ptr<content::WebContents> web_contents,
const std::string &extension_id,
WindowOpenDisposition disposition,
- const gfx::Rect &initial_rect,
+ const blink::mojom::WindowFeatures &features,
bool user_gesture)
{
Q_UNUSED(web_contents);
Q_UNUSED(extension_id);
Q_UNUSED(disposition);
- Q_UNUSED(initial_rect);
+ Q_UNUSED(features);
Q_UNUSED(user_gesture);
Q_UNREACHABLE();
}
+static void processMediaAccessRequest(content::WebContents *webContents,
+ const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback,
+ content::DesktopMediaID id)
+{
+ MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(
+ webContents, request, std::move(callback), id);
+}
+
void ExtensionHostDelegateQt::ProcessMediaAccessRequest(content::WebContents *web_contents,
const content::MediaStreamRequest &request,
content::MediaResponseCallback callback,
const Extension *extension)
{
Q_UNUSED(extension);
-
- QtWebEngineCore::MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(web_contents, request, std::move(callback));
+ base::OnceCallback<void(content::DesktopMediaID)> cb = base::BindOnce(
+ &processMediaAccessRequest, web_contents, std::move(request), std::move(callback));
+
+ // ownership is taken by the request
+ auto *controller = new DesktopMediaController(new DesktopMediaControllerPrivate(std::move(cb)));
+ base::WeakPtr<content::WebContents> webContents = web_contents->GetWeakPtr();
+ QObject::connect(controller, &DesktopMediaController::mediaListsInitialized, [controller, webContents]() {
+ if (webContents) {
+ auto *client = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents.get())->GetView())->client();
+ client->desktopMediaRequested(controller);
+ } else {
+ controller->deleteLater();
+ }
+ });
}
bool ExtensionHostDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *render_frame_host,
@@ -105,13 +100,9 @@ bool ExtensionHostDelegateQt::CheckMediaAccessPermission(content::RenderFrameHos
return false;
}
-content::PictureInPictureResult ExtensionHostDelegateQt::EnterPictureInPicture(content::WebContents *web_contents,
- const viz::SurfaceId &surface_id,
- const gfx::Size &natural_size)
+content::PictureInPictureResult ExtensionHostDelegateQt::EnterPictureInPicture(content::WebContents *web_contents)
{
Q_UNUSED(web_contents);
- Q_UNUSED(surface_id);
- Q_UNUSED(natural_size);
Q_UNREACHABLE();
return content::PictureInPictureResult::kNotSupported;
diff --git a/src/core/extensions/extension_host_delegate_qt.h b/src/core/extensions/extension_host_delegate_qt.h
index 04ffb9d16..1c2688933 100644
--- a/src/core/extensions/extension_host_delegate_qt.h
+++ b/src/core/extensions/extension_host_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef EXTENSION_HOST_DELEGATE_QT_H
#define EXTENSION_HOST_DELEGATE_QT_H
@@ -56,7 +20,7 @@ public:
void CreateTab(std::unique_ptr<content::WebContents> web_contents,
const std::string &extension_id,
WindowOpenDisposition disposition,
- const gfx::Rect &initial_rect,
+ const blink::mojom::WindowFeatures &features,
bool user_gesture) override;
void ProcessMediaAccessRequest(content::WebContents *web_contents,
const content::MediaStreamRequest &request,
@@ -66,9 +30,7 @@ public:
const GURL &security_origin,
blink::mojom::MediaStreamType type,
const Extension *extension) override;
- content::PictureInPictureResult EnterPictureInPicture(content::WebContents *web_contents,
- const viz::SurfaceId &surface_id,
- const gfx::Size &natural_size) override;
+ content::PictureInPictureResult EnterPictureInPicture(content::WebContents *web_contents) override;
void ExitPictureInPicture() override;
};
diff --git a/src/core/extensions/extension_system_factory_qt.cpp b/src/core/extensions/extension_system_factory_qt.cpp
index b63b41a86..63d88fcaf 100644
--- a/src/core/extensions/extension_system_factory_qt.cpp
+++ b/src/core/extensions/extension_system_factory_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
diff --git a/src/core/extensions/extension_system_factory_qt.h b/src/core/extensions/extension_system_factory_qt.h
index 6e840b6d6..b6f6acc5d 100644
--- a/src/core/extensions/extension_system_factory_qt.h
+++ b/src/core/extensions/extension_system_factory_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -44,7 +8,6 @@
#ifndef EXTENSION_SYSTEM_FACTORY_QT_H_
#define EXTENSION_SYSTEM_FACTORY_QT_H_
-#include "base/macros.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "extensions/browser/extension_system_provider.h"
@@ -73,8 +36,6 @@ private:
KeyedService *BuildServiceInstanceFor(content::BrowserContext *context) const override;
content::BrowserContext *GetBrowserContextToUse(content::BrowserContext *context) const override;
bool ServiceIsCreatedWithBrowserContext() const override;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionSystemFactoryQt);
};
} // namespace extensions
diff --git a/src/core/extensions/extension_system_qt.cpp b/src/core/extensions/extension_system_qt.cpp
index 99b56786b..b9f11646d 100644
--- a/src/core/extensions/extension_system_qt.cpp
+++ b/src/core/extensions/extension_system_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -47,7 +11,7 @@
#include "base/base_paths.h"
#include "base/base_switches.h"
-#include "base/bind.h"
+#include "base/functional/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -57,20 +21,21 @@
#include "base/path_service.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/common/buildflags.h"
#include "components/crx_file/id_util.h"
+#include "components/value_store/value_store_factory.h"
+#include "components/value_store/value_store_factory_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
-#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/common/webplugininfo.h"
+#include "extensions/browser/app_sorting.h"
#include "extensions/browser/content_verifier.h"
#include "extensions/browser/content_verifier_delegate.h"
#include "extensions/browser/extension_pref_store.h"
@@ -78,51 +43,53 @@
#include "extensions/browser/extension_pref_value_map_factory.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/info_map.h"
-#include "extensions/browser/notification_types.h"
-#include "extensions/browser/null_app_sorting.h"
#include "extensions/browser/quota_service.h"
#include "extensions/browser/renderer_startup_helper.h"
-#include "extensions/browser/runtime_data.h"
#include "extensions/browser/service_worker_manager.h"
+#include "extensions/browser/task_queue_util.h"
#include "extensions/browser/user_script_manager.h"
-#include "extensions/browser/value_store/value_store_factory_impl.h"
#include "extensions/common/constants.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/mime_types_handler.h"
#include "extensions/common/manifest_url_handlers.h"
#include "net/base/mime_util.h"
+#include "pdf/buildflags.h"
+#include "ppapi/buildflags/buildflags.h"
#include "qtwebengine/grit/qt_webengine_resources.h"
#include "ui/base/resource/resource_bundle.h"
+#if BUILDFLAG(ENABLE_PLUGINS)
+#include "content/public/browser/plugin_service.h"
+#endif
+
using content::BrowserThread;
namespace extensions {
namespace {
-std::string GenerateId(const base::DictionaryValue *manifest, const base::FilePath &path)
+std::string GenerateId(const base::Value::Dict &manifest, const base::FilePath &path)
{
- std::string raw_key;
+ const std::string *raw_key;
std::string id_input;
- CHECK(manifest->GetString(manifest_keys::kPublicKey, &raw_key));
- CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
+ CHECK(raw_key = manifest.FindString(manifest_keys::kPublicKey));
+ CHECK(Extension::ParsePEMKeyBytes(*raw_key, &id_input));
std::string id = crx_file::id_util::GenerateId(id_input);
return id;
}
// Implementation based on ComponentLoader::ParseManifest.
-std::unique_ptr<base::DictionaryValue> ParseManifest(const std::string &manifest_contents)
+absl::optional<base::Value::Dict> ParseManifest(base::StringPiece manifest_contents)
{
JSONStringValueDeserializer deserializer(manifest_contents);
- std::unique_ptr<base::Value> manifest(deserializer.Deserialize(NULL, NULL));
+ std::unique_ptr<base::Value> manifest = deserializer.Deserialize(nullptr, nullptr);
if (!manifest.get() || !manifest->is_dict()) {
LOG(ERROR) << "Failed to parse extension manifest.";
- return NULL;
+ return absl::nullopt;
}
- // Transfer ownership to the caller.
- return base::DictionaryValue::From(std::move(manifest));
+
+ return std::move(*manifest).TakeDict();
}
} // namespace
@@ -161,38 +128,25 @@ public:
void Shutdown() override {}
};
-void ExtensionSystemQt::LoadExtension(std::string extension_id, std::unique_ptr<base::DictionaryValue> manifest, const base::FilePath &directory)
+void ExtensionSystemQt::LoadExtension(std::string extension_id, const base::Value::Dict &manifest, const base::FilePath &directory)
{
int flags = Extension::REQUIRE_KEY;
std::string error;
+
scoped_refptr<const Extension> extension = Extension::Create(
directory,
- Manifest::COMPONENT,
- *manifest,
+ mojom::ManifestLocation::kComponent,
+ manifest,
flags,
&error);
if (!extension.get())
LOG(ERROR) << error;
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
- base::Bind(&InfoMap::AddExtension,
- base::Unretained(info_map()),
- base::RetainedRef(extension),
- base::Time::Now(),
- true,
- false));
extension_registry_->AddEnabled(extension.get());
NotifyExtensionLoaded(extension.get());
}
-void ExtensionSystemQt::OnExtensionRegisteredWithRequestContexts(scoped_refptr<const extensions::Extension> extension)
-{
- extension_registry_->AddReady(extension);
- if (extension_registry_->enabled_extensions().Contains(extension->id()))
- extension_registry_->TriggerOnReady(extension.get());
-}
-
// Implementation based on ExtensionService::NotifyExtensionLoaded.
void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
{
@@ -202,11 +156,7 @@ void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
// that the request context doesn't yet know about. The profile is responsible
// for ensuring its URLRequestContexts appropriately discover the loaded
// extension.
- RegisterExtensionWithRequestContexts(
- extension,
- base::Bind(&ExtensionSystemQt::OnExtensionRegisteredWithRequestContexts,
- weak_ptr_factory_.GetWeakPtr(),
- base::WrapRefCounted(extension)));
+ ActivateTaskQueueForExtension(browser_context_, extension);
// Tell renderers about the loaded extension.
renderer_helper_->OnExtensionLoaded(*extension);
@@ -220,10 +170,13 @@ void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
// know about it.
extension_registry_->TriggerOnLoaded(extension);
+#if BUILDFLAG(ENABLE_PLUGINS)
// Register plugins included with the extension.
// Implementation based on PluginManager::OnExtensionLoaded.
+ bool plugins_changed = false;
const MimeTypesHandler *handler = MimeTypesHandler::GetHandler(extension);
if (handler && handler->HasPlugin()) {
+ plugins_changed = true;
content::WebPluginInfo info;
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
info.name = base::UTF8ToUTF16(extension->name());
@@ -245,6 +198,13 @@ void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
plugin_service->RefreshPlugins();
plugin_service->RegisterInternalPlugin(info, true);
}
+ if (plugins_changed)
+ content::PluginService::GetInstance()->PurgePluginListCache(browser_context_, false);
+#endif // BUILDFLAG(ENABLE_PLUGINS)
+
+ extension_registry_->AddReady(extension);
+ if (extension_registry_->enabled_extensions().Contains(extension->id()))
+ extension_registry_->TriggerOnReady(extension);
}
bool ExtensionSystemQt::FinishDelayedInstallationIfReady(const std::string &extension_id, bool install_immediately)
@@ -269,11 +229,6 @@ ExtensionService *ExtensionSystemQt::extension_service()
return nullptr;
}
-RuntimeData *ExtensionSystemQt::runtime_data()
-{
- return runtime_data_.get();
-}
-
ManagementPolicy *ExtensionSystemQt::management_policy()
{
return nullptr;
@@ -294,16 +249,14 @@ StateStore *ExtensionSystemQt::rules_store()
return nullptr;
}
-scoped_refptr<ValueStoreFactory> ExtensionSystemQt::store_factory()
+StateStore *ExtensionSystemQt::dynamic_user_scripts_store()
{
- return store_factory_;
+ return nullptr;
}
-InfoMap *ExtensionSystemQt::info_map()
+scoped_refptr<value_store::ValueStoreFactory> ExtensionSystemQt::store_factory()
{
- if (!info_map_.get())
- info_map_ = new InfoMap;
- return info_map_.get();
+ return store_factory_;
}
QuotaService *ExtensionSystemQt::quota_service()
@@ -313,7 +266,7 @@ QuotaService *ExtensionSystemQt::quota_service()
AppSorting *ExtensionSystemQt::app_sorting()
{
- return app_sorting_.get();
+ return nullptr;
}
ContentVerifier *ExtensionSystemQt::content_verifier()
@@ -326,7 +279,7 @@ ContentVerifier *ExtensionSystemQt::content_verifier()
ExtensionSystemQt::ExtensionSystemQt(content::BrowserContext *browserContext)
: browser_context_(browserContext)
- , store_factory_(new ValueStoreFactoryImpl(browserContext->GetPath()))
+ , store_factory_(new value_store::ValueStoreFactoryImpl(browserContext->GetPath()))
, extension_registry_(ExtensionRegistry::Get(browserContext))
, renderer_helper_(extensions::RendererStartupHelperFactory::GetForBrowserContext(browserContext))
, initialized_(false)
@@ -345,13 +298,9 @@ void ExtensionSystemQt::Init(bool extensions_enabled)
initialized_ = true;
- service_worker_manager_.reset(new ServiceWorkerManager(browser_context_));
- runtime_data_.reset(new RuntimeData(extension_registry_));
- quota_service_.reset(new QuotaService);
- app_sorting_.reset(new NullAppSorting);
-
- user_script_manager_ =
- std::make_unique<UserScriptManager>(browser_context_);
+ service_worker_manager_ = std::make_unique<ServiceWorkerManager>(browser_context_);
+ user_script_manager_ = std::make_unique<UserScriptManager>(browser_context_);
+ quota_service_ = std::make_unique<QuotaService>();
// Make the chrome://extension-icon/ resource available.
// content::URLDataSource::Add(browser_context_, new ExtensionIconSource(browser_context_));
@@ -360,27 +309,31 @@ void ExtensionSystemQt::Init(bool extensions_enabled)
// Inform the rest of the extensions system to start.
ready_.Signal();
+#if BUILDFLAG(ENABLE_PDF)
{
- std::string pdf_manifest = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_PDF_MANIFEST).as_string();
+ std::string pdf_manifest = ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_PDF_MANIFEST);
base::ReplaceFirstSubstringAfterOffset(&pdf_manifest, 0, "<NAME>", "chromium-pdf");
- std::unique_ptr<base::DictionaryValue> pdfManifestDict = ParseManifest(pdf_manifest);
+ auto pdfManifestDict = ParseManifest(pdf_manifest);
+ CHECK(pdfManifestDict);
base::FilePath path;
base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &path);
path = path.Append(base::FilePath(FILE_PATH_LITERAL("pdf")));
- std::string id = GenerateId(pdfManifestDict.get(), path);
- LoadExtension(id, std::move(pdfManifestDict), path);
+ std::string id = GenerateId(pdfManifestDict.value(), path);
+ LoadExtension(id, pdfManifestDict.value(), path);
}
+#endif // BUILDFLAG(ENABLE_PDF)
#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
{
- std::string hangout_manifest = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_HANGOUT_SERVICES_MANIFEST).as_string();
- std::unique_ptr<base::DictionaryValue> hangoutManifestDict = ParseManifest(hangout_manifest);
+ std::string hangout_manifest = ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_HANGOUT_SERVICES_MANIFEST);
+ auto hangoutManifestDict = ParseManifest(hangout_manifest);
+ CHECK(hangoutManifestDict);
base::FilePath path;
base::PathService::Get(base::DIR_QT_LIBRARY_DATA, &path);
path = path.Append(base::FilePath(FILE_PATH_LITERAL("hangout_services")));
- std::string id = GenerateId(hangoutManifestDict.get(), path);
- LoadExtension(id, std::move(hangoutManifestDict), path);
+ std::string id = GenerateId(hangoutManifestDict.value(), path);
+ LoadExtension(id, hangoutManifestDict.value(), path);
}
#endif // BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
}
@@ -390,8 +343,6 @@ void ExtensionSystemQt::InitForRegularProfile(bool extensions_enabled)
{
if (initialized_)
return; // Already initialized.
- // The InfoMap needs to be created before the ProcessManager.
- info_map();
Init(extensions_enabled);
}
@@ -401,30 +352,6 @@ std::unique_ptr<ExtensionSet> ExtensionSystemQt::GetDependentExtensions(const Ex
return base::WrapUnique(new ExtensionSet());
}
-void ExtensionSystemQt::RegisterExtensionWithRequestContexts(const Extension *extension,
- base::OnceClosure callback)
-{
- base::Time install_time = base::Time::Now();
-
- bool incognito_enabled = false;
- bool notifications_disabled = false;
-
- base::PostTaskAndReply(
- FROM_HERE, {BrowserThread::IO},
- base::Bind(&InfoMap::AddExtension, info_map(),
- base::RetainedRef(extension), install_time, incognito_enabled,
- notifications_disabled),
- std::move(callback));
-}
-
-void ExtensionSystemQt::UnregisterExtensionWithRequestContexts(const std::string &extension_id,
- const UnloadedExtensionReason reason)
-{
- base::PostTask(
- FROM_HERE, {BrowserThread::IO},
- base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason));
-}
-
bool ExtensionSystemQt::is_ready() const
{
return ready_.is_signaled();
diff --git a/src/core/extensions/extension_system_qt.h b/src/core/extensions/extension_system_qt.h
index 2ae92581a..c213671a7 100644
--- a/src/core/extensions/extension_system_qt.h
+++ b/src/core/extensions/extension_system_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -50,12 +14,15 @@
#include <string>
#include "base/one_shot_event.h"
-#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_set.h"
+namespace value_store {
+class ValueStoreFactory;
+}
+
namespace extensions {
class ExtensionRegistry;
@@ -63,8 +30,6 @@ class InfoMap;
class RendererStartupHelper;
class ServiceWorkerManager;
class StateStoreNotificationObserver;
-class ValueStoreFactory;
-class ValueStoreFactoryImpl;
// The ExtensionSystem for ProfileImpl and OffTheRecordProfileImpl.
// Implementation details: non-shared services are owned by
@@ -86,23 +51,16 @@ public:
// ExtensionSystem implementation:
void InitForRegularProfile(bool extensions_enabled) override;
ExtensionService *extension_service() override;
- RuntimeData *runtime_data() override;
ManagementPolicy *management_policy() override;
ServiceWorkerManager *service_worker_manager() override;
UserScriptManager *user_script_manager() override;
StateStore *state_store() override;
StateStore *rules_store() override;
- scoped_refptr<ValueStoreFactory> store_factory() override;
- InfoMap *info_map() override;
+ StateStore *dynamic_user_scripts_store() override;
+ scoped_refptr<value_store::ValueStoreFactory> store_factory() override;
QuotaService *quota_service() override;
AppSorting *app_sorting() override;
- void RegisterExtensionWithRequestContexts(const Extension *extension,
- base::OnceClosure callback) override;
-
- void UnregisterExtensionWithRequestContexts(const std::string &extension_id,
- const UnloadedExtensionReason reason) override;
-
ContentVerifier *content_verifier() override;
std::unique_ptr<ExtensionSet> GetDependentExtensions(const Extension *extension) override;
@@ -113,37 +71,28 @@ public:
const base::OneShotEvent &ready() const override { return ready_; }
bool is_ready() const override;
- void PerformActionBasedOnOmahaAttributes(const std::string &, const base::Value &) override { /* fixme? */}
+ void PerformActionBasedOnOmahaAttributes(const std::string &, const base::Value::Dict &) override { /* fixme? */}
private:
- void OnExtensionRegisteredWithRequestContexts(scoped_refptr<const extensions::Extension> extension);
-
void NotifyExtensionLoaded(const Extension *extension);
- void LoadExtension(std::string extension_id, std::unique_ptr<base::DictionaryValue> manifest, const base::FilePath &directory);
- // The services that are shared between normal and incognito profiles.
-
- // Data to be accessed on the IO thread. Must outlive process_manager_.
- scoped_refptr<InfoMap> info_map_;
+ void LoadExtension(std::string extension_id, const base::Value::Dict &manifest, const base::FilePath &directory);
+ // The services that are shared between normal and incognito profiles.
std::unique_ptr<ServiceWorkerManager> service_worker_manager_;
- std::unique_ptr<RuntimeData> runtime_data_;
std::unique_ptr<QuotaService> quota_service_;
- std::unique_ptr<AppSorting> app_sorting_;
std::unique_ptr<UserScriptManager> user_script_manager_;
-
// For verifying the contents of extensions read from disk.
scoped_refptr<ContentVerifier> content_verifier_;
base::OneShotEvent ready_;
content::BrowserContext *browser_context_;
- scoped_refptr<ValueStoreFactory> store_factory_;
+ scoped_refptr<value_store::ValueStoreFactory> store_factory_;
ExtensionRegistry *extension_registry_;
extensions::RendererStartupHelper *renderer_helper_;
bool initialized_;
base::WeakPtrFactory<ExtensionSystemQt> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(ExtensionSystemQt);
};
} // namespace extensions
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp
index 0959806f6..a33954a20 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.cpp
+++ b/src/core/extensions/extension_web_contents_observer_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -43,14 +7,13 @@
#include "extension_web_contents_observer_qt.h"
-#include "components/guest_view/browser/guest_view_base.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
-#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/manifest.h"
+#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "render_widget_host_view_qt.h"
@@ -58,6 +21,7 @@ namespace extensions {
ExtensionWebContentsObserverQt::ExtensionWebContentsObserverQt(content::WebContents *web_contents)
: ExtensionWebContentsObserver(web_contents)
+ , content::WebContentsUserData<ExtensionWebContentsObserverQt>(*web_contents)
{
}
@@ -77,6 +41,8 @@ void ExtensionWebContentsObserverQt::CreateForWebContents(content::WebContents *
void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost *render_frame_host)
{
ExtensionWebContentsObserver::RenderFrameCreated(render_frame_host);
+ QtWebEngineCore::RenderWidgetHostViewQt::registerInputEventObserver(web_contents(),
+ render_frame_host);
const Extension *extension = GetExtensionFromFrame(render_frame_host, false);
if (!extension)
@@ -86,19 +52,9 @@ void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost
auto *policy = content::ChildProcessSecurityPolicy::GetInstance();
if (extension->is_extension() && Manifest::IsComponentLocation(extension->location()))
- policy->GrantRequestOrigin(process_id, url::Origin::Create(GURL(content::kChromeUIResourcesURL)));
+ policy->GrantRequestOrigin(process_id, url::Origin::Create(GURL(blink::kChromeUIResourcesURL)));
}
-void ExtensionWebContentsObserverQt::RenderViewReady()
-{
- if (web_contents()->IsInnerWebContentsForGuest()) {
- content::RenderWidgetHost *render_widget_host = web_contents()->GetRenderViewHost()->GetWidget();
- content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents());
- QtWebEngineCore::RenderWidgetHostViewQt *parent_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView());
- parent_rwhv->setGuest(static_cast<content::RenderWidgetHostImpl *>(render_widget_host));
- }
-}
-
-WEB_CONTENTS_USER_DATA_KEY_IMPL(ExtensionWebContentsObserverQt)
+WEB_CONTENTS_USER_DATA_KEY_IMPL(ExtensionWebContentsObserverQt);
} // namespace extensions
diff --git a/src/core/extensions/extension_web_contents_observer_qt.h b/src/core/extensions/extension_web_contents_observer_qt.h
index 346e94d4a..ff50b28e2 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.h
+++ b/src/core/extensions/extension_web_contents_observer_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -61,12 +25,10 @@ public:
// content::WebContentsObserver overrides.
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
- void RenderViewReady() override;
private:
friend class content::WebContentsUserData<ExtensionWebContentsObserverQt>;
WEB_CONTENTS_USER_DATA_KEY_DECL();
- DISALLOW_COPY_AND_ASSIGN(ExtensionWebContentsObserverQt);
};
} // namespace extensions
diff --git a/src/core/extensions/extensions_api_client_qt.cpp b/src/core/extensions/extensions_api_client_qt.cpp
index 925fd10da..678c252cc 100644
--- a/src/core/extensions/extensions_api_client_qt.cpp
+++ b/src/core/extensions/extensions_api_client_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2015 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
@@ -43,15 +7,21 @@
// found in the LICENSE file.
#include "extensions_api_client_qt.h"
+#include "file_system_delegate_qt.h"
#include "messaging_delegate_qt.h"
#include <memory>
-#include "components/pdf/browser/pdf_web_contents_helper.h"
+
#include "extension_web_contents_observer_qt.h"
#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
#include "mime_handler_view_guest_delegate_qt.h"
+#include "pdf/buildflags.h"
+#include "printing/buildflags/buildflags.h"
+
+#if BUILDFLAG(ENABLE_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW)
#include "printing/print_view_manager_qt.h"
+#endif
namespace extensions {
@@ -66,9 +36,16 @@ AppViewGuestDelegate *ExtensionsAPIClientQt::CreateAppViewGuestDelegate() const
return nullptr;
}
-std::unique_ptr<guest_view::GuestViewManagerDelegate> ExtensionsAPIClientQt::CreateGuestViewManagerDelegate(content::BrowserContext *context) const
+FileSystemDelegate *ExtensionsAPIClientQt::GetFileSystemDelegate()
+{
+ if (!m_fileSystemDelegate)
+ m_fileSystemDelegate = std::make_unique<FileSystemDelegateQt>();
+ return m_fileSystemDelegate.get();
+}
+
+std::unique_ptr<guest_view::GuestViewManagerDelegate> ExtensionsAPIClientQt::CreateGuestViewManagerDelegate() const
{
- return std::make_unique<extensions::ExtensionsGuestViewManagerDelegate>(context);
+ return std::make_unique<extensions::ExtensionsGuestViewManagerDelegate>();
}
std::unique_ptr<MimeHandlerViewGuestDelegate> ExtensionsAPIClientQt::CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const
@@ -79,7 +56,9 @@ std::unique_ptr<MimeHandlerViewGuestDelegate> ExtensionsAPIClientQt::CreateMimeH
void ExtensionsAPIClientQt::AttachWebContentsHelpers(content::WebContents *web_contents) const
{
// PrefsTabHelper::CreateForWebContents(web_contents);
+#if BUILDFLAG(ENABLE_PRINTING) && BUILDFLAG(ENABLE_PRINT_PREVIEW)
QtWebEngineCore::PrintViewManagerQt::CreateForWebContents(web_contents);
+#endif
ExtensionWebContentsObserverQt::CreateForWebContents(web_contents);
}
diff --git a/src/core/extensions/extensions_api_client_qt.h b/src/core/extensions/extensions_api_client_qt.h
index b1b6356e8..e7838138c 100644
--- a/src/core/extensions/extensions_api_client_qt.h
+++ b/src/core/extensions/extensions_api_client_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2015 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
@@ -49,6 +13,7 @@
namespace extensions {
+class FileSystemDelegate;
class MessagingDelegate;
class ExtensionsAPIClientQt : public ExtensionsAPIClient
@@ -58,14 +23,16 @@ public:
// ExtensionsAPIClient implementation.
AppViewGuestDelegate *CreateAppViewGuestDelegate() const override;
+ FileSystemDelegate *GetFileSystemDelegate() override;
std::unique_ptr<guest_view::GuestViewManagerDelegate>
- CreateGuestViewManagerDelegate(content::BrowserContext *context) const override;
+ CreateGuestViewManagerDelegate() const override;
std::unique_ptr<MimeHandlerViewGuestDelegate>
CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const override;
void AttachWebContentsHelpers(content::WebContents *web_contents) const override;
MessagingDelegate *GetMessagingDelegate() override;
private:
+ std::unique_ptr<FileSystemDelegate> m_fileSystemDelegate;
std::unique_ptr<MessagingDelegate> m_messagingDelegate;
};
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
index 406facc5c..19fc6c808 100644
--- a/src/core/extensions/extensions_browser_client_qt.cpp
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2015 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
@@ -49,15 +13,15 @@
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
-#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/memory/ref_counted_memory.h"
#include "chrome/browser/extensions/api/generated_api_registration.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
+#include "extensions/browser/api/core_extensions_browser_api_provider.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/api/runtime/runtime_api_delegate.h"
-#include "extensions/browser/core_extensions_browser_api_provider.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_host_delegate.h"
#include "extensions/browser/extension_protocols.h"
@@ -67,6 +31,7 @@
#include "extensions/common/file_util.h"
#include "net/base/mime_util.h"
#include "qtwebengine/browser/extensions/api/generated_api_registration.h"
+#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/zlib/google/compression_utils.h"
@@ -114,7 +79,7 @@ scoped_refptr<base::RefCountedMemory> GetResource(int resource_id, const std::st
base::StringPiece input(reinterpret_cast<const char *>(bytes->front()), bytes->size());
std::string temp_str = ui::ReplaceTemplateExpressions(input, *replacements);
DCHECK(!temp_str.empty());
- return base::RefCountedString::TakeString(&temp_str);
+ return base::MakeRefCounted<base::RefCountedString>(std::move(temp_str));
}
return bytes;
}
@@ -128,12 +93,12 @@ public:
mojo::PendingReceiver<network::mojom::URLLoader> loader,
mojo::PendingRemote<network::mojom::URLLoaderClient> client_info,
const base::FilePath &filename, int resource_id,
- const std::string &content_security_policy, bool send_cors_header)
+ scoped_refptr<net::HttpResponseHeaders> headers)
{
// Owns itself. Will live as long as its URLLoader and URLLoaderClientPtr
// bindings are alive - essentially until either the client gives up or all
// file data has been sent to it.
- auto *bundle_loader = new ResourceBundleFileLoader(content_security_policy, send_cors_header);
+ auto *bundle_loader = new ResourceBundleFileLoader(std::move(headers));
bundle_loader->Start(request, std::move(loader), std::move(client_info), filename, resource_id);
}
@@ -141,7 +106,7 @@ public:
void FollowRedirect(const std::vector<std::string> &removed_headers,
const net::HttpRequestHeaders &modified_headers,
const net::HttpRequestHeaders &modified_cors_exempt_headers,
- const base::Optional<GURL> &new_url) override
+ const absl::optional<GURL> &new_url) override
{
NOTREACHED() << "No redirects for local file loads.";
}
@@ -152,9 +117,9 @@ public:
void ResumeReadingBodyFromNet() override {}
private:
- ResourceBundleFileLoader(const std::string &content_security_policy, bool send_cors_header)
+ ResourceBundleFileLoader(scoped_refptr<net::HttpResponseHeaders> headers)
+ : response_headers_(std::move(headers))
{
- response_headers_ = extensions::BuildHttpHeaders(content_security_policy, send_cors_header, base::Time());
}
~ResourceBundleFileLoader() override = default;
@@ -172,8 +137,8 @@ private:
auto data = GetResource(resource_id, request.url.host());
std::string *read_mime_type = new std::string;
- base::PostTaskAndReplyWithResult(
- FROM_HERE, { base::ThreadPool(), base::MayBlock() },
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, { base::MayBlock() },
base::BindOnce(&net::GetMimeTypeFromFile, filename, base::Unretained(read_mime_type)),
base::BindOnce(&ResourceBundleFileLoader::OnMimeTypeRead, weak_factory_.GetWeakPtr(), std::move(data),
base::Owned(read_mime_type)));
@@ -201,8 +166,7 @@ private:
if (!head->mime_type.empty()) {
head->headers->AddHeader(net::HttpRequestHeaders::kContentType, head->mime_type.c_str());
}
- client_->OnReceiveResponse(std::move(head));
- client_->OnStartLoadingResponseBody(std::move(consumer_handle));
+ client_->OnReceiveResponse(std::move(head), std::move(consumer_handle), absl::nullopt);
uint32_t write_size = data->size();
MojoResult result = producer_handle->WriteData(data->front(), &write_size, MOJO_WRITE_DATA_FLAG_NONE);
@@ -243,8 +207,6 @@ private:
mojo::Remote<network::mojom::URLLoaderClient> client_;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
base::WeakPtrFactory<ResourceBundleFileLoader> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(ResourceBundleFileLoader);
};
} // namespace
@@ -264,8 +226,6 @@ public:
api::ChromeGeneratedFunctionRegistry::RegisterAll(registry);
}
-private:
- DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsBrowserAPIProvider);
};
class QtWebEngineExtensionsBrowserAPIProvider : public ExtensionsBrowserAPIProvider
@@ -279,9 +239,6 @@ public:
// Generated APIs from QtWebEngine.
api::QtWebEngineGeneratedFunctionRegistry::RegisterAll(registry);
}
-
-private:
- DISALLOW_COPY_AND_ASSIGN(QtWebEngineExtensionsBrowserAPIProvider);
};
ExtensionsBrowserClientQt::ExtensionsBrowserClientQt()
@@ -307,7 +264,7 @@ bool ExtensionsBrowserClientQt::AreExtensionsDisabled(const base::CommandLine &c
return false;
}
-bool ExtensionsBrowserClientQt::IsValidContext(BrowserContext *context)
+bool ExtensionsBrowserClientQt::IsValidContext(void *)
{
return true;
}
@@ -334,6 +291,30 @@ BrowserContext *ExtensionsBrowserClientQt::GetOriginalContext(BrowserContext *co
return context;
}
+content::BrowserContext* ExtensionsBrowserClientQt::GetContextRedirectedToOriginal(content::BrowserContext *context, bool)
+{
+ // like in ShellExtensionsBrowserClient:
+ return context;
+}
+
+content::BrowserContext* ExtensionsBrowserClientQt::GetContextOwnInstance(content::BrowserContext *context, bool)
+{
+ // like in ShellExtensionsBrowserClient:
+ return context;
+}
+
+content::BrowserContext* ExtensionsBrowserClientQt::GetContextForOriginalOnly(content::BrowserContext *context, bool)
+{
+ // like in ShellExtensionsBrowserClient:
+ return context;
+}
+
+bool ExtensionsBrowserClientQt::AreExtensionsDisabledForContext(content::BrowserContext*)
+{
+ // like in ShellExtensionsBrowserClient:
+ return false;
+}
+
bool ExtensionsBrowserClientQt::IsGuestSession(BrowserContext *context) const
{
return context->IsOffTheRecord();
@@ -387,12 +368,11 @@ void ExtensionsBrowserClientQt::LoadResourceFromResourceBundle(const network::Re
mojo::PendingReceiver<network::mojom::URLLoader> loader,
const base::FilePath &resource_relative_path,
int resource_id,
- const std::string &content_security_policy,
- mojo::PendingRemote<network::mojom::URLLoaderClient> client,
- bool send_cors_header)
+ scoped_refptr<net::HttpResponseHeaders> headers,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client)
{
ResourceBundleFileLoader::CreateAndStart(request, std::move(loader), std::move(client), resource_relative_path,
- resource_id, content_security_policy, send_cors_header);
+ resource_id, headers);
}
@@ -490,7 +470,8 @@ const ComponentExtensionResourceManager *ExtensionsBrowserClientQt::GetComponent
void ExtensionsBrowserClientQt::BroadcastEventToRenderers(events::HistogramValue histogram_value,
const std::string &event_name,
- std::unique_ptr<base::ListValue> args, bool dispatch_to_off_the_record_profiles)
+ base::Value::List args,
+ bool dispatch_to_off_the_record_profiles)
{
NOTIMPLEMENTED();
// TODO : do the event routing
@@ -543,7 +524,6 @@ ExtensionWebContentsObserver *ExtensionsBrowserClientQt::GetExtensionWebContents
KioskDelegate *ExtensionsBrowserClientQt::GetKioskDelegate()
{
- NOTREACHED();
return nullptr;
}
@@ -557,4 +537,10 @@ void ExtensionsBrowserClientQt::SetAPIClientForTest(ExtensionsAPIClient *api_cli
api_client_.reset(api_client);
}
+media_device_salt::MediaDeviceSaltService *ExtensionsBrowserClientQt::GetMediaDeviceSaltService(content::BrowserContext *context)
+{
+ // Not needed for QWE
+ return nullptr;
+}
+
} // namespace extensions
diff --git a/src/core/extensions/extensions_browser_client_qt.h b/src/core/extensions/extensions_browser_client_qt.h
index 7c00adcad..bcc8f142b 100644
--- a/src/core/extensions/extensions_browser_client_qt.h
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2015 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
@@ -45,7 +9,6 @@
#ifndef EXTENSIONS_BROWSER_CLIENT_QT_H_
#define EXTENSIONS_BROWSER_CLIENT_QT_H_
-#include "base/compiler_specific.h"
#include "extensions/browser/extensions_browser_client.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -66,12 +29,15 @@ public:
bool IsShuttingDown() override;
bool AreExtensionsDisabled(const base::CommandLine &command_line,
content::BrowserContext *context) override;
- bool IsValidContext(content::BrowserContext *context) override;
+ bool IsValidContext(void*) override;
bool IsSameContext(content::BrowserContext *first,
content::BrowserContext *second) override;
bool HasOffTheRecordContext(content::BrowserContext *context) override;
content::BrowserContext *GetOffTheRecordContext(content::BrowserContext *context) override;
content::BrowserContext *GetOriginalContext(content::BrowserContext *context) override;
+ content::BrowserContext *GetContextRedirectedToOriginal(content::BrowserContext*, bool) override;
+ content::BrowserContext *GetContextOwnInstance(content::BrowserContext*, bool) override;
+ content::BrowserContext *GetContextForOriginalOnly(content::BrowserContext*, bool) override;
bool IsGuestSession(content::BrowserContext *context) const override;
bool IsExtensionIncognitoEnabled(const std::string &extension_id, content::BrowserContext *context) const override;
bool CanExtensionCrossIncognito(const Extension *extension, content::BrowserContext *context) const override;
@@ -102,7 +68,7 @@ public:
GetComponentExtensionResourceManager() override;
void BroadcastEventToRenderers(events::HistogramValue histogram_value,
const std::string &event_name,
- std::unique_ptr<base::ListValue> args,
+ base::Value::List args,
bool dispatch_to_off_the_record_profiles) override;
ExtensionCache *GetExtensionCache() override;
bool IsBackgroundUpdateAllowed() override;
@@ -127,9 +93,8 @@ public:
mojo::PendingReceiver<network::mojom::URLLoader> loader,
const base::FilePath &resource_relative_path,
int resource_id,
- const std::string &content_security_policy,
- mojo::PendingRemote<network::mojom::URLLoaderClient> client,
- bool send_cors_header) override;
+ scoped_refptr<net::HttpResponseHeaders> headers,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client) override;
// Returns the locale used by the application.
std::string GetApplicationLocale() override;
@@ -139,6 +104,10 @@ public:
// Sets the API client.
void SetAPIClientForTest(ExtensionsAPIClient *api_client);
+ bool AreExtensionsDisabledForContext(content::BrowserContext*) override;
+
+ media_device_salt::MediaDeviceSaltService *GetMediaDeviceSaltService(content::BrowserContext *context) override;
+
private:
// Support for extension APIs.
std::unique_ptr<ExtensionsAPIClient> api_client_;
@@ -147,8 +116,6 @@ private:
std::unique_ptr<ComponentExtensionResourceManager> resource_manager_;
//scoped_refptr<EventRouterForwarder> event_router_forwarder_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionsBrowserClientQt);
};
} // namespace extensions
diff --git a/src/core/extensions/file_system_delegate_qt.cpp b/src/core/extensions/file_system_delegate_qt.cpp
new file mode 100644
index 000000000..7c1c5bbd8
--- /dev/null
+++ b/src/core/extensions/file_system_delegate_qt.cpp
@@ -0,0 +1,146 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "file_system_delegate_qt.h"
+
+#include "select_file_dialog_factory_qt.h"
+#include "type_conversion.h"
+
+#include "base/files/file_path.h"
+#include "base/files/file_path.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback.h"
+#include "base/memory/ref_counted.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents.h"
+#include "extensions/browser/api/file_system/file_system_delegate.h"
+#include "extensions/browser/extension_function.h"
+#include "ui/shell_dialogs/selected_file_info.h"
+
+#include <QStandardPaths>
+
+namespace extensions {
+
+FileEntryPickerQt::FileEntryPickerQt(
+ content::WebContents *web_contents,
+ const base::FilePath &suggested_name,
+ const ui::SelectFileDialog::FileTypeInfo *file_type_info,
+ ui::SelectFileDialog::Type picker_type,
+ FileSystemDelegate::FilesSelectedCallback files_selected_callback,
+ base::OnceClosure file_selection_canceled_callback)
+ : m_filesSelectedCallback(std::move(files_selected_callback))
+ , m_fileSelectionCanceledCallback(std::move(file_selection_canceled_callback))
+{
+ const GURL caller = web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
+ m_selectFileDialog = ui::SelectFileDialog::Create(
+ this, std::make_unique<QtWebEngineCore::SelectFilePolicyQt>(web_contents));
+ m_selectFileDialog->SelectFile(
+ picker_type, std::u16string(), suggested_name, file_type_info, 0,
+ base::FilePath::StringType(), nullptr, nullptr, &caller);
+}
+
+FileEntryPickerQt::~FileEntryPickerQt() = default;
+
+void FileEntryPickerQt::FileSelected(const base::FilePath &path,
+ int index,
+ void *params)
+{
+ MultiFilesSelected({path}, params);
+}
+
+void FileEntryPickerQt::FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file,
+ int index,
+ void *params)
+{
+ FileSelected(file.file_path, index, params);
+}
+
+void FileEntryPickerQt::MultiFilesSelected(const std::vector<base::FilePath>& files,
+ void* params)
+{
+ Q_UNUSED(params);
+ std::move(m_filesSelectedCallback).Run(files);
+ delete this;
+}
+
+void FileEntryPickerQt::MultiFilesSelectedWithExtraInfo(
+ const std::vector<ui::SelectedFileInfo> &files,
+ void *params)
+{
+ std::vector<base::FilePath> paths;
+ for (const auto& file : files)
+ paths.push_back(file.file_path);
+ MultiFilesSelected(paths, params);
+}
+
+void FileEntryPickerQt::FileSelectionCanceled(void *params)
+{
+ std::move(m_fileSelectionCanceledCallback).Run();
+ delete this;
+}
+
+FileSystemDelegateQt::FileSystemDelegateQt()
+{
+}
+
+base::FilePath FileSystemDelegateQt::GetDefaultDirectory()
+{
+ return QtWebEngineCore::toFilePath(
+ QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
+}
+
+base::FilePath FileSystemDelegateQt::GetManagedSaveAsDirectory(
+ content::BrowserContext *browser_context,
+ const Extension &extension)
+{
+ Q_UNUSED(browser_context);
+ Q_UNUSED(extension);
+ return base::FilePath();
+}
+
+bool FileSystemDelegateQt::ShowSelectFileDialog(
+ scoped_refptr<ExtensionFunction> extension_function,
+ ui::SelectFileDialog::Type type,
+ const base::FilePath &default_path,
+ const ui::SelectFileDialog::FileTypeInfo *file_type_info,
+ FileSystemDelegate::FilesSelectedCallback files_selected_callback,
+ base::OnceClosure file_selection_canceled_callback)
+{
+ content::WebContents *web_contents = extension_function->GetSenderWebContents();
+ if (!web_contents)
+ return false;
+
+ new FileEntryPickerQt(web_contents, default_path, file_type_info, type,
+ std::move(files_selected_callback),
+ std::move(file_selection_canceled_callback));
+ return true;
+}
+
+void FileSystemDelegateQt::ConfirmSensitiveDirectoryAccess(
+ bool has_write_permission,
+ const std::u16string &app_name,
+ content::WebContents *web_contents,
+ base::OnceClosure on_accept,
+ base::OnceClosure on_cancel)
+{
+ Q_UNUSED(has_write_permission);
+ Q_UNUSED(app_name);
+ Q_UNUSED(web_contents);
+ Q_UNUSED(on_accept);
+ std::move(on_cancel).Run();
+}
+
+int FileSystemDelegateQt::GetDescriptionIdForAcceptType(const std::string &accept_type)
+{
+ Q_UNUSED(accept_type);
+ return 0;
+}
+
+SavedFilesServiceInterface *FileSystemDelegateQt::GetSavedFilesService(
+ content::BrowserContext *browser_context)
+{
+ Q_UNUSED(browser_context);
+ return nullptr;
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/file_system_delegate_qt.h b/src/core/extensions/file_system_delegate_qt.h
new file mode 100644
index 000000000..1e9d87c38
--- /dev/null
+++ b/src/core/extensions/file_system_delegate_qt.h
@@ -0,0 +1,89 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FILE_SYSTEM_DELEGATE_QT_H
+#define FILE_SYSTEM_DELEGATE_QT_H
+
+#include "extensions/browser/api/file_system/file_system_delegate.h"
+
+#include "base/files/file_path.h"
+#include "base/functional/callback.h"
+#include "base/memory/ref_counted.h"
+#include "extensions/browser/extension_function.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
+
+#include <memory>
+#include <vector>
+
+namespace content {
+class BrowserContext;
+} // namespace content
+
+namespace extensions {
+
+class FileEntryPickerQt : public ui::SelectFileDialog::Listener {
+public:
+ FileEntryPickerQt(
+ content::WebContents *web_contents,
+ const base::FilePath &suggested_name,
+ const ui::SelectFileDialog::FileTypeInfo *file_type_info,
+ ui::SelectFileDialog::Type picker_type,
+ FileSystemDelegate::FilesSelectedCallback files_selected_callback,
+ base::OnceClosure file_selection_canceled_callback);
+
+ FileEntryPickerQt(const FileEntryPickerQt &) = delete;
+ FileEntryPickerQt &operator=(const FileEntryPickerQt &) = delete;
+
+private:
+ ~FileEntryPickerQt() override;
+
+ // ui::SelectFileDialog::Listener implementation.
+ void FileSelected(const base::FilePath &path,
+ int index,
+ void *params) override;
+ void FileSelectedWithExtraInfo(const ui::SelectedFileInfo &file,
+ int index,
+ void *params) override;
+ void MultiFilesSelected(const std::vector<base::FilePath> &files,
+ void *params) override;
+ void MultiFilesSelectedWithExtraInfo(
+ const std::vector<ui::SelectedFileInfo> &files,
+ void *params) override;
+ void FileSelectionCanceled(void *params) override;
+
+ FileSystemDelegate::FilesSelectedCallback m_filesSelectedCallback;
+ base::OnceClosure m_fileSelectionCanceledCallback;
+ scoped_refptr<ui::SelectFileDialog> m_selectFileDialog;
+};
+
+class FileSystemDelegateQt : public FileSystemDelegate
+{
+public:
+ FileSystemDelegateQt();
+
+ // FileSystemDelegate implementation
+ virtual base::FilePath GetDefaultDirectory() override;
+ virtual base::FilePath GetManagedSaveAsDirectory(
+ content::BrowserContext *browser_context,
+ const Extension &extension) override;
+ virtual bool ShowSelectFileDialog(
+ scoped_refptr<ExtensionFunction> extension_function,
+ ui::SelectFileDialog::Type type,
+ const base::FilePath &default_path,
+ const ui::SelectFileDialog::FileTypeInfo *file_types,
+ FileSystemDelegate::FilesSelectedCallback files_selected_callback,
+ base::OnceClosure file_selection_canceled_callback) override;
+ virtual void ConfirmSensitiveDirectoryAccess(
+ bool has_write_permission,
+ const std::u16string &app_name,
+ content::WebContents *web_contents,
+ base::OnceClosure on_accept,
+ base::OnceClosure on_cancel) override;
+ virtual int GetDescriptionIdForAcceptType(const std::string &accept_type) override;
+ virtual SavedFilesServiceInterface *GetSavedFilesService(
+ content::BrowserContext *browser_context) override;
+};
+
+} // namespace extensions
+
+#endif // FILE_SYSTEM_DELEGATE_QT_H
diff --git a/src/core/extensions/messaging_delegate_qt.cpp b/src/core/extensions/messaging_delegate_qt.cpp
index c666daa09..b0089aea2 100644
--- a/src/core/extensions/messaging_delegate_qt.cpp
+++ b/src/core/extensions/messaging_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "messaging_delegate_qt.h"
@@ -47,10 +11,10 @@ MessagingDelegateQt::MessagingDelegateQt()
{
}
-std::unique_ptr<base::DictionaryValue> MessagingDelegateQt::MaybeGetTabInfo(content::WebContents *web_contents)
+absl::optional<base::Value::Dict> MessagingDelegateQt::MaybeGetTabInfo(content::WebContents *web_contents)
{
Q_UNUSED(web_contents);
- return nullptr;
+ return absl::nullopt;
}
} // namespace extensions
diff --git a/src/core/extensions/messaging_delegate_qt.h b/src/core/extensions/messaging_delegate_qt.h
index 44bfdc2d5..c3c6244f5 100644
--- a/src/core/extensions/messaging_delegate_qt.h
+++ b/src/core/extensions/messaging_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef MESSAGING_DELEGATE_QT_H
#define MESSAGING_DELEGATE_QT_H
@@ -58,7 +22,7 @@ public:
MessagingDelegateQt();
// MessagingDelegate implementation.
- std::unique_ptr<base::DictionaryValue> MaybeGetTabInfo(content::WebContents *web_contents) override;
+ absl::optional<base::Value::Dict> MaybeGetTabInfo(content::WebContents *web_contents) override;
};
} // namespace extensions
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
index 16a747929..fcea708b0 100644
--- a/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2015 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
@@ -70,8 +34,9 @@ MimeHandlerViewGuestDelegateQt::~MimeHandlerViewGuestDelegateQt()
delete m_contextMenuRequest;
}
-bool MimeHandlerViewGuestDelegateQt::HandleContextMenu(content::WebContents *web_contents, const content::ContextMenuParams &params)
+bool MimeHandlerViewGuestDelegateQt::HandleContextMenu(content::RenderFrameHost &render_frame_host, const content::ContextMenuParams &params)
{
+ content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(&render_frame_host);
content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents);
if (auto rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView())) {
if (rwhv->getTouchSelectionControllerClient()->handleContextMenu(params))
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.h b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
index c9b822aa1..bdb3c840b 100644
--- a/src/core/extensions/mime_handler_view_guest_delegate_qt.h
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Portions copyright 2015 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
@@ -65,12 +29,11 @@ public:
explicit MimeHandlerViewGuestDelegateQt(MimeHandlerViewGuest *guest);
~MimeHandlerViewGuestDelegateQt() override;
- bool HandleContextMenu(content::WebContents *web_contents,
+ bool HandleContextMenu(content::RenderFrameHost &render_frame_host,
const content::ContextMenuParams &params) override;
private:
QWebEngineContextMenuRequest *m_contextMenuRequest;
- DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewGuestDelegateQt);
};
} // namespace extensions
diff --git a/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp b/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
index 7c2fe75f0..a494e2f49 100644
--- a/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
+++ b/src/core/extensions/pdf_iframe_navigation_throttle_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on //chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
// Copyright 2017 The Chromium Authors. All rights reserved.
@@ -45,6 +9,7 @@
#include "extensions/pdf_iframe_navigation_throttle_qt.h"
+#include "base/task/sequenced_task_runner.h"
#include "chrome/grit/renderer_resources.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/download_utils.h"
@@ -54,23 +19,25 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
#include "content/public/common/webplugininfo.h"
-#include "net/base/escape.h"
+#include "base/strings/escape.h"
#include "net/http/http_response_headers.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
#include "ui/base/webui/web_ui_util.h"
-namespace extensions {
+#include "pdf_util_qt.h"
+
+#include <QtGlobal>
-constexpr char kPDFMimeType[] = "application/pdf";
+namespace extensions {
// Used to scope the posted navigation task to the lifetime of |web_contents|.
class PdfWebContentsLifetimeHelper : public content::WebContentsUserData<PdfWebContentsLifetimeHelper>
{
public:
explicit PdfWebContentsLifetimeHelper(content::WebContents *web_contents)
- : web_contents_(web_contents)
+ : content::WebContentsUserData<PdfWebContentsLifetimeHelper>(*web_contents)
{}
base::WeakPtr<PdfWebContentsLifetimeHelper> GetWeakPtr()
@@ -80,32 +47,37 @@ public:
void NavigateIFrameToPlaceholder(const content::OpenURLParams &url_params)
{
- web_contents_->OpenURL(url_params);
+ GetWebContents().OpenURL(url_params);
}
private:
friend class content::WebContentsUserData<PdfWebContentsLifetimeHelper>;
- content::WebContents* const web_contents_;
base::WeakPtrFactory<PdfWebContentsLifetimeHelper> weak_factory_{this};
WEB_CONTENTS_USER_DATA_KEY_DECL();
};
-WEB_CONTENTS_USER_DATA_KEY_IMPL(PdfWebContentsLifetimeHelper)
+WEB_CONTENTS_USER_DATA_KEY_IMPL(PdfWebContentsLifetimeHelper);
bool IsPDFPluginEnabled(content::NavigationHandle *navigation_handle, bool *is_stale)
{
content::WebContents *web_contents = navigation_handle->GetWebContents();
- int process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
- int routing_id = web_contents->GetMainFrame()->GetRoutingID();
+ Q_ASSERT(web_contents);
+
+ if (web_contents->IsInnerWebContentsForGuest())
+ web_contents = web_contents->GetOuterWebContents();
+
+ int process_id = web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
+ int routing_id = web_contents->GetPrimaryMainFrame()->GetRoutingID();
content::WebPluginInfo plugin_info;
// Will check WebEngineSettings by PluginServiceFilterQt
return content::PluginService::GetInstance()->GetPluginInfo(
- process_id, routing_id, navigation_handle->GetURL(),
- web_contents->GetMainFrame()->GetLastCommittedOrigin(), kPDFMimeType,
- false /* allow_wildcard */, is_stale, &plugin_info,
- nullptr /* actual_mime_type */);
+ process_id, routing_id,
+ navigation_handle->GetWebContents()->GetBrowserContext(),
+ navigation_handle->GetURL(),
+ QtWebEngineCore::kPDFMimeType, false /* allow_wildcard */,
+ is_stale, &plugin_info, nullptr /* actual_mime_type */);
}
std::string GetPDFPlaceholderHTML(const GURL &pdf_url)
@@ -113,12 +85,12 @@ std::string GetPDFPlaceholderHTML(const GURL &pdf_url)
std::string template_html = ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_PDF_PLUGIN_HTML);
webui::AppendWebUiCssTextDefaults(&template_html);
- base::DictionaryValue values;
- values.SetString("fileName", pdf_url.ExtractFileName());
- values.SetString("open", l10n_util::GetStringUTF8(IDS_ACCNAME_OPEN));
- values.SetString("pdfUrl", pdf_url.spec());
+ base::Value::Dict values;
+ values.Set("fileName", pdf_url.ExtractFileName());
+ values.Set("open", l10n_util::GetStringUTF8(IDS_ACCNAME_OPEN));
+ values.Set("pdfUrl", pdf_url.spec());
- return webui::GetI18nTemplateHtml(template_html, &values);
+ return webui::GetI18nTemplateHtml(template_html, std::move(values));
}
// static
@@ -147,12 +119,15 @@ content::NavigationThrottle::ThrottleCheckResult PDFIFrameNavigationThrottleQt::
std::string mime_type;
response_headers->GetMimeType(&mime_type);
- if (mime_type != kPDFMimeType)
+ if (mime_type != QtWebEngineCore::kPDFMimeType)
return content::NavigationThrottle::PROCEED;
// We MUST download responses marked as attachments rather than showing
// a placeholder.
- if (content::download_utils::MustDownload(navigation_handle()->GetURL(), response_headers, mime_type))
+ if (content::download_utils::MustDownload(navigation_handle()->GetWebContents()
+ ? navigation_handle()->GetWebContents()->GetBrowserContext()
+ : nullptr,
+ navigation_handle()->GetURL(), response_headers, mime_type))
return content::NavigationThrottle::PROCEED;
bool is_stale = false;
@@ -195,7 +170,7 @@ void PDFIFrameNavigationThrottleQt::LoadPlaceholderHTML()
{
// Prepare the params to navigate to the placeholder.
std::string html = GetPDFPlaceholderHTML(navigation_handle()->GetURL());
- GURL data_url("data:text/html," + net::EscapePath(html));
+ GURL data_url("data:text/html," + base::EscapePath(html));
content::OpenURLParams params = content::OpenURLParams::FromNavigationHandle(navigation_handle());
params.url = data_url;
params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
@@ -210,7 +185,7 @@ void PDFIFrameNavigationThrottleQt::LoadPlaceholderHTML()
PdfWebContentsLifetimeHelper::CreateForWebContents(web_contents);
PdfWebContentsLifetimeHelper *helper = PdfWebContentsLifetimeHelper::FromWebContents(web_contents);
- base::SequencedTaskRunnerHandle::Get()->PostTask(
+ base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(&PdfWebContentsLifetimeHelper::NavigateIFrameToPlaceholder,
helper->GetWeakPtr(), std::move(params)));
diff --git a/src/core/extensions/pdf_iframe_navigation_throttle_qt.h b/src/core/extensions/pdf_iframe_navigation_throttle_qt.h
index 37f5bf1d6..fdc168aec 100644
--- a/src/core/extensions/pdf_iframe_navigation_throttle_qt.h
+++ b/src/core/extensions/pdf_iframe_navigation_throttle_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on //chrome/browser/plugins/pdf_iframe_navigation_throttle.h
// Copyright 2017 The Chromium Authors. All rights reserved.
diff --git a/src/core/extensions/pdf_web_contents_helper_client_qt.h b/src/core/extensions/pdf_web_contents_helper_client_qt.h
deleted file mode 100644
index 9a37375b3..000000000
--- a/src/core/extensions/pdf_web_contents_helper_client_qt.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
-#define PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
-
-#include "base/macros.h"
-#include "components/pdf/browser/pdf_web_contents_helper_client.h"
-
-namespace extensions {
-
-class PDFWebContentsHelperClientQt : public pdf::PDFWebContentsHelperClient
-{
-public:
- PDFWebContentsHelperClientQt();
- ~PDFWebContentsHelperClientQt() override;
-
-private:
- // pdf::PDFWebContentsHelperClient:
- void UpdateContentRestrictions(content::WebContents *contents, int content_restrictions) override;
- void OnPDFHasUnsupportedFeature(content::WebContents *contents) override;
- void OnSaveURL(content::WebContents *contents) override;
-
- DISALLOW_COPY_AND_ASSIGN(PDFWebContentsHelperClientQt);
-};
-
-} // namespace extensions
-
-#endif // PDF_WEB_CONTENTS_HELPER_CLIENT_QT_H_
diff --git a/src/core/extensions/plugin_service_filter_qt.cpp b/src/core/extensions/plugin_service_filter_qt.cpp
index 778f803c3..1f6c606bc 100644
--- a/src/core/extensions/plugin_service_filter_qt.cpp
+++ b/src/core/extensions/plugin_service_filter_qt.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "extensions/plugin_service_filter_qt.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents.h"
+#include "content/public/browser/render_process_host.h"
#include "web_contents_delegate_qt.h"
#include "web_engine_settings.h"
@@ -50,16 +13,17 @@ using namespace QtWebEngineCore;
namespace extensions {
// static
-PluginServiceFilterQt *PluginServiceFilterQt::GetInstance() {
+PluginServiceFilterQt *PluginServiceFilterQt::GetInstance()
+{
return base::Singleton<PluginServiceFilterQt>::get();
}
-bool PluginServiceFilterQt::IsPluginAvailable(int render_process_id,
- int render_frame_id,
- const GURL &url,
- const url::Origin &main_frame_origin,
- content::WebPluginInfo *plugin)
+bool PluginServiceFilterQt::IsPluginAvailable(int render_process_id, int render_frame_id,
+ content::BrowserContext *browser_context,
+ const content::WebPluginInfo &plugin)
{
+ Q_UNUSED(plugin);
+ Q_UNUSED(browser_context);
content::RenderFrameHost *frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
if (!web_contents) {
diff --git a/src/core/extensions/plugin_service_filter_qt.h b/src/core/extensions/plugin_service_filter_qt.h
index ea5f082f2..d171edfde 100644
--- a/src/core/extensions/plugin_service_filter_qt.h
+++ b/src/core/extensions/plugin_service_filter_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PLUGIN_SERVICE_FILTER_QT
#define PLUGIN_SERVICE_FILTER_QT
@@ -50,11 +14,9 @@ class PluginServiceFilterQt : public content::PluginServiceFilter {
public:
static PluginServiceFilterQt* GetInstance();
- bool IsPluginAvailable(int render_process_id,
- int render_frame_id,
- const GURL &url,
- const url::Origin &main_frame_origin,
- content::WebPluginInfo *plugin) override;
+ bool IsPluginAvailable(int render_process_id, int render_frame_id,
+ content::BrowserContext *browser_context,
+ const content::WebPluginInfo &plugin) override;
bool CanLoadPlugin(int render_process_id,
const base::FilePath &path) override;
diff --git a/src/core/favicon_driver_qt.cpp b/src/core/favicon_driver_qt.cpp
index a3bbd5939..bb4a734b4 100644
--- a/src/core/favicon_driver_qt.cpp
+++ b/src/core/favicon_driver_qt.cpp
@@ -1,41 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// Based on components/favicon/content/content_favicon_driver.cc:
+// Copyright 2015 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 "favicon_driver_qt.h"
#include "type_conversion.h"
@@ -48,22 +17,14 @@
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
-#include "third_party/blink/public/common/manifest/manifest.h"
+#include "content/public/browser/page.h"
+#include "content/public/browser/render_frame_host.h"
+#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
namespace QtWebEngineCore {
namespace {
-void ExtractManifestIcons(FaviconDriverQt::ManifestDownloadCallback callback,
- const GURL &manifest_url, const blink::Manifest &manifest)
-{
- std::vector<favicon::FaviconURL> candidates;
- for (const auto &icon : manifest.icons) {
- candidates.emplace_back(icon.src, favicon_base::IconType::kWebManifestIcon, icon.sizes);
- }
- std::move(callback).Run(candidates);
-}
-
int activeHandlersCount(QWebEngineSettings *settings)
{
bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled);
@@ -79,7 +40,7 @@ FaviconStatusQt::FaviconStatusQt()
// static
void FaviconDriverQt::CreateForWebContents(content::WebContents *webContents,
- favicon::FaviconService *faviconService,
+ favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient)
{
if (FromWebContents(webContents))
@@ -91,9 +52,10 @@ void FaviconDriverQt::CreateForWebContents(content::WebContents *webContents,
}
FaviconDriverQt::FaviconDriverQt(content::WebContents *webContents,
- favicon::FaviconService *faviconService,
+ favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient)
: content::WebContentsObserver(webContents)
+ , content::WebContentsUserData<FaviconDriverQt>(*webContents)
, m_faviconService(faviconService)
, m_viewClient(viewClient)
{
@@ -163,6 +125,13 @@ GURL FaviconDriverQt::GetActiveURL()
return entry ? entry->GetURL() : GURL();
}
+GURL FaviconDriverQt::GetManifestURL(content::RenderFrameHost *rfh)
+{
+ DocumentManifestData *document_data = DocumentManifestData::GetOrCreateForCurrentDocument(rfh);
+ return document_data->has_manifest_url ? rfh->GetPage().GetManifestUrl().value_or(GURL())
+ : GURL();
+}
+
GURL FaviconDriverQt::GetFaviconURL() const
{
content::NavigationController &controller = web_contents()->GetController();
@@ -173,20 +142,62 @@ GURL FaviconDriverQt::GetFaviconURL() const
return GURL();
}
+FaviconDriverQt::DocumentManifestData::DocumentManifestData(content::RenderFrameHost *rfh)
+ : content::DocumentUserData<DocumentManifestData>(rfh)
+{
+}
+
+FaviconDriverQt::DocumentManifestData::~DocumentManifestData() = default;
+
+FaviconDriverQt::NavigationManifestData::NavigationManifestData(
+ content::NavigationHandle &navigation_handle)
+{
+}
+
+FaviconDriverQt::NavigationManifestData::~NavigationManifestData() = default;
+
+void FaviconDriverQt::OnDidDownloadManifest(ManifestDownloadCallback callback,
+ const GURL &manifest_url,
+ blink::mojom::ManifestPtr manifest)
+{
+ Q_UNUSED(manifest_url);
+
+ // ~WebContentsImpl triggers running any pending callbacks for manifests.
+ // As we're about to be destroyed ignore the request. To do otherwise may
+ // result in calling back to this and attempting to use the WebContents, which
+ // will crash.
+ if (!web_contents())
+ return;
+
+ std::vector<favicon::FaviconURL> candidates;
+ if (manifest) {
+ for (const auto &icon : manifest->icons) {
+ candidates.emplace_back(icon.src, favicon_base::IconType::kWebManifestIcon, icon.sizes);
+ }
+ }
+ std::move(callback).Run(candidates);
+}
+
int FaviconDriverQt::DownloadImage(const GURL &url, int max_image_size,
ImageDownloadCallback callback)
{
bool bypass_cache = (m_bypassCachePageURL == GetActiveURL());
m_bypassCachePageURL = GURL();
- return web_contents()->DownloadImage(url, true, /*preferred_size=*/max_image_size,
- /*max_bitmap_size=*/max_image_size, bypass_cache,
- std::move(callback));
+ const gfx::Size preferred_size(max_image_size, max_image_size);
+ return web_contents()->DownloadImage(url, true, preferred_size,
+ /*max_bitmap_size=*/max_image_size,
+ bypass_cache, std::move(callback));
}
void FaviconDriverQt::DownloadManifest(const GURL &url, ManifestDownloadCallback callback)
{
- web_contents()->GetManifest(base::BindOnce(&ExtractManifestIcons, std::move(callback)));
+ // TODO(crbug.com/1201237): This appears to be reachable from pages other
+ // than the primary page. This code should likely be refactored so that either
+ // this is unreachable from other pages, or the correct page is plumbed in
+ // here.
+ web_contents()->GetPrimaryPage().GetManifest(base::BindOnce(
+ &FaviconDriverQt::OnDidDownloadManifest, base::Unretained(this), std::move(callback)));
}
bool FaviconDriverQt::IsOffTheRecord()
@@ -243,88 +254,95 @@ void FaviconDriverQt::OnHandlerCompleted(favicon::FaviconHandler *handler)
}
void FaviconDriverQt::DidUpdateFaviconURL(
- content::RenderFrameHost *render_frame_host,
- const std::vector<blink::mojom::FaviconURLPtr> &candidates)
+ content::RenderFrameHost *rfh, const std::vector<blink::mojom::FaviconURLPtr> &candidates)
{
- Q_UNUSED(render_frame_host);
-
// Ignore the update if there is no last committed navigation entry. This can
// occur when loading an initially blank page.
content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
+
if (!entry)
return;
// We update |m_faviconUrls| even if the list is believed to be partial
// (checked below), because callers of our getter favicon_urls() expect so.
- std::vector<blink::mojom::FaviconURL> faviconUrls;
+ std::vector<blink::mojom::FaviconURLPtr> faviconUrls;
for (const auto &candidate : candidates)
- faviconUrls.push_back(*candidate);
- m_faviconUrls = faviconUrls;
+ faviconUrls.push_back(candidate.Clone());
+ m_faviconUrls = std::move(faviconUrls);
- if (!m_documentOnLoadCompleted)
+ if (!rfh->IsDocumentOnLoadCompletedInMainFrame())
return;
- OnUpdateCandidates(entry->GetURL(),
- favicon::FaviconURLsFromContentFaviconURLs(
- m_faviconUrls.value_or(std::vector<blink::mojom::FaviconURL>())),
- m_manifestUrl);
+ OnUpdateCandidates(rfh->GetLastCommittedURL(),
+ favicon::FaviconURLsFromContentFaviconURLs(candidates), GetManifestURL(rfh));
}
-void FaviconDriverQt::DidUpdateWebManifestURL(content::RenderFrameHost *target_frame,
- const base::Optional<GURL> &manifest_url)
+void FaviconDriverQt::DidUpdateWebManifestURL(content::RenderFrameHost *rfh,
+ const GURL &manifest_url)
{
- Q_UNUSED(target_frame);
+ Q_UNUSED(manifest_url);
// Ignore the update if there is no last committed navigation entry. This can
// occur when loading an initially blank page.
content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry();
- if (!entry || !m_documentOnLoadCompleted)
+ if (!entry || !rfh->IsDocumentOnLoadCompletedInMainFrame())
return;
- m_manifestUrl = manifest_url.value_or(GURL());
+ DocumentManifestData *document_data = DocumentManifestData::GetOrCreateForCurrentDocument(rfh);
+ document_data->has_manifest_url = true;
// On regular page loads, DidUpdateManifestURL() is guaranteed to be called
// before DidUpdateFaviconURL(). However, a page can update the favicons via
// javascript.
- if (m_faviconUrls.has_value()) {
- OnUpdateCandidates(entry->GetURL(),
- favicon::FaviconURLsFromContentFaviconURLs(*m_faviconUrls),
- m_manifestUrl);
+ if (!rfh->FaviconURLs().empty()) {
+ OnUpdateCandidates(rfh->GetLastCommittedURL(),
+ favicon::FaviconURLsFromContentFaviconURLs(rfh->FaviconURLs()),
+ GetManifestURL(rfh));
}
}
void FaviconDriverQt::DidStartNavigation(content::NavigationHandle *navigation_handle)
{
- if (!navigation_handle->IsInMainFrame())
+ if (!navigation_handle->IsInPrimaryMainFrame())
return;
- m_faviconUrls.reset();
- m_completedHandlersCount = 0;
- m_latestFavicon = FaviconStatusQt();
-
if (!navigation_handle->IsSameDocument()) {
- m_documentOnLoadCompleted = false;
- m_manifestUrl = GURL();
+ m_completedHandlersCount = 0;
+ m_latestFavicon = FaviconStatusQt();
+ m_viewClient->iconChanged(QUrl());
}
- m_viewClient->iconChanged(QUrl());
-
content::ReloadType reload_type = navigation_handle->GetReloadType();
if (reload_type == content::ReloadType::NONE || IsOffTheRecord())
return;
- m_bypassCachePageURL = navigation_handle->GetURL();
+ if (!navigation_handle->IsSameDocument()) {
+ NavigationManifestData *navigation_data =
+ NavigationManifestData::GetOrCreateForNavigationHandle(*navigation_handle);
+ navigation_data->has_manifest_url = false;
+ }
+
+ if (reload_type == content::ReloadType::BYPASSING_CACHE)
+ m_bypassCachePageURL = navigation_handle->GetURL();
+
SetFaviconOutOfDateForPage(navigation_handle->GetURL(),
reload_type == content::ReloadType::BYPASSING_CACHE);
}
void FaviconDriverQt::DidFinishNavigation(content::NavigationHandle *navigation_handle)
{
- if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted()
+ if (!navigation_handle->IsInPrimaryMainFrame() || !navigation_handle->HasCommitted()
|| navigation_handle->IsErrorPage()) {
return;
}
+ // Transfer in-flight navigation data to the document user data.
+ NavigationManifestData *navigation_data =
+ NavigationManifestData::GetOrCreateForNavigationHandle(*navigation_handle);
+ DocumentManifestData *document_data = DocumentManifestData::GetOrCreateForCurrentDocument(
+ navigation_handle->GetRenderFrameHost());
+ document_data->has_manifest_url = navigation_data->has_manifest_url;
+
// Wait till the user navigates to a new URL to start checking the cache
// again. The cache may be ignored for non-reload navigations (e.g.
// history.replace() in-page navigation). This is allowed to increase the
@@ -340,11 +358,6 @@ void FaviconDriverQt::DidFinishNavigation(content::NavigationHandle *navigation_
FetchFavicon(url, navigation_handle->IsSameDocument());
}
-void FaviconDriverQt::DocumentOnLoadCompletedInMainFrame()
-{
- m_documentOnLoadCompleted = true;
-}
-
void FaviconDriverQt::SetFaviconOutOfDateForPage(const GURL &url, bool force_reload)
{
if (m_faviconService) {
@@ -402,6 +415,8 @@ void FaviconDriverQt::emitIconChangedIfNeeded()
m_viewClient->iconChanged(toQt(m_latestFavicon.url));
}
-WEB_CONTENTS_USER_DATA_KEY_IMPL(FaviconDriverQt)
+NAVIGATION_HANDLE_USER_DATA_KEY_IMPL(FaviconDriverQt::NavigationManifestData);
+DOCUMENT_USER_DATA_KEY_IMPL(FaviconDriverQt::DocumentManifestData);
+WEB_CONTENTS_USER_DATA_KEY_IMPL(FaviconDriverQt);
} // namespace QtWebEngineCore
diff --git a/src/core/favicon_driver_qt.h b/src/core/favicon_driver_qt.h
index b49017946..96bd682a2 100644
--- a/src/core/favicon_driver_qt.h
+++ b/src/core/favicon_driver_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -55,7 +19,9 @@
#include "components/favicon/core/favicon_driver.h"
#include "components/favicon/core/favicon_handler.h"
+#include "content/public/browser/document_user_data.h"
#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_handle_user_data.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
@@ -65,7 +31,7 @@ class WebContents;
}
namespace favicon {
-class FaviconService;
+class CoreFaviconService;
}
namespace QtWebEngineCore {
@@ -87,7 +53,7 @@ class FaviconDriverQt : public favicon::FaviconDriver,
{
public:
static void CreateForWebContents(content::WebContents *webContents,
- favicon::FaviconService *faviconService,
+ favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient);
// FaviconDriver implementation.
@@ -96,15 +62,38 @@ public:
bool FaviconIsValid() const override;
GURL GetActiveURL() override;
+ GURL GetManifestURL(content::RenderFrameHost *rfh);
GURL GetFaviconURL() const;
protected:
- FaviconDriverQt(content::WebContents *webContent, favicon::FaviconService *faviconService,
+ FaviconDriverQt(content::WebContents *webContent, favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient);
private:
friend class content::WebContentsUserData<FaviconDriverQt>;
+ // TODO(crbug.com/1205018): these two classes are current used to ensure that
+ // we disregard manifest URL updates that arrive prior to onload firing.
+ struct DocumentManifestData : public content::DocumentUserData<DocumentManifestData>
+ {
+ explicit DocumentManifestData(content::RenderFrameHost *rfh);
+ ~DocumentManifestData() override;
+ DOCUMENT_USER_DATA_KEY_DECL();
+ bool has_manifest_url = false;
+ };
+
+ struct NavigationManifestData : public content::NavigationHandleUserData<NavigationManifestData>
+ {
+ explicit NavigationManifestData(content::NavigationHandle &navigation_handle);
+ ~NavigationManifestData() override;
+ NAVIGATION_HANDLE_USER_DATA_KEY_DECL();
+ bool has_manifest_url = false;
+ };
+
+ // Callback when a manifest is downloaded.
+ void OnDidDownloadManifest(ManifestDownloadCallback callback, const GURL &manifest_url,
+ blink::mojom::ManifestPtr manifest);
+
// FaviconHandler::Delegate implementation.
int DownloadImage(const GURL &url, int max_image_size, ImageDownloadCallback callback) override;
void DownloadManifest(const GURL &url, ManifestDownloadCallback callback) override;
@@ -119,15 +108,13 @@ private:
void OnHandlerCompleted(favicon::FaviconHandler *handler) override;
// content::WebContentsObserver implementation.
- void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host,
+ void DidUpdateFaviconURL(content::RenderFrameHost *rfh,
const std::vector<blink::mojom::FaviconURLPtr> &candidates) override;
- void DidUpdateWebManifestURL(content::RenderFrameHost *target_frame,
- const base::Optional<GURL> &manifest_url) override;
+ void DidUpdateWebManifestURL(content::RenderFrameHost *rfh, const GURL &manifest_url) override;
void DidStartNavigation(content::NavigationHandle *navigation_handle) override;
void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
- void DocumentOnLoadCompletedInMainFrame() override;
- // Informs FaviconService that the favicon for |url| is out of date. If
+ // Informs CoreFaviconService that the favicon for |url| is out of date. If
// |force_reload| is true, then discard information about favicon download
// failures.
void SetFaviconOutOfDateForPage(const GURL &url, bool force_reload);
@@ -141,26 +128,22 @@ private:
// KeyedService used by FaviconDriverImpl. It may be null during testing,
// but if it is defined, it must outlive the FaviconDriverImpl.
- favicon::FaviconService *m_faviconService;
+ raw_ptr<favicon::CoreFaviconService> m_faviconService;
WebContentsAdapterClient *m_viewClient;
- // FaviconHandlers used to download the different kind of favicons.
+ // FaviconHandlers are used to download the different kind of favicons.
std::vector<std::unique_ptr<favicon::FaviconHandler>> m_handlers;
GURL m_bypassCachePageURL;
- bool m_documentOnLoadCompleted = false;
// nullopt until the actual list is reported via DidUpdateFaviconURL().
- base::Optional<std::vector<blink::mojom::FaviconURL>> m_faviconUrls;
- // Web Manifest URL or empty URL if none.
- GURL m_manifestUrl;
+ absl::optional<std::vector<blink::mojom::FaviconURLPtr>> m_faviconUrls;
int m_completedHandlersCount = 0;
FaviconStatusQt m_latestFavicon;
WEB_CONTENTS_USER_DATA_KEY_DECL();
- DISALLOW_COPY_AND_ASSIGN(FaviconDriverQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/favicon_service_factory_qt.cpp b/src/core/favicon_service_factory_qt.cpp
index 6810927c9..dd2a1979a 100644
--- a/src/core/favicon_service_factory_qt.cpp
+++ b/src/core/favicon_service_factory_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "favicon_service_factory_qt.h"
@@ -59,12 +23,17 @@ void HistoryClientQt::OnHistoryServiceCreated(history::HistoryService *history_s
void HistoryClientQt::Shutdown() { }
-bool HistoryClientQt::CanAddURL(const GURL &url)
+static bool CanAddURL(const GURL &url)
{
Q_UNUSED(url);
return true;
}
+history::CanAddURLCallback HistoryClientQt::GetThreadSafeCanAddURLCallback() const
+{
+ return base::BindRepeating(&CanAddURL);
+}
+
void HistoryClientQt::NotifyProfileError(sql::InitStatus init_status,
const std::string &diagnostics)
{
@@ -77,6 +46,10 @@ std::unique_ptr<history::HistoryBackendClient> HistoryClientQt::CreateBackendCli
return nullptr;
}
+void HistoryClientQt::UpdateBookmarkLastUsedTime(const base::Uuid &, base::Time /*time*/)
+{
+}
+
// static
history::HistoryService *
HistoryServiceFactoryQt::GetForBrowserContext(content::BrowserContext *context)
@@ -116,7 +89,7 @@ HistoryServiceFactoryQt::BuildServiceInstanceFor(content::BrowserContext *contex
std::unique_ptr<history::HistoryService> historyService(
new history::HistoryService(std::make_unique<HistoryClientQt>(), nullptr));
- if (!historyService->Init(history::HistoryDatabaseParamsForPath(context->GetPath()))) {
+ if (!historyService->Init(history::HistoryDatabaseParamsForPath(context->GetPath(), version_info::Channel::DEFAULT))) {
return nullptr;
}
return historyService.release();
diff --git a/src/core/favicon_service_factory_qt.h b/src/core/favicon_service_factory_qt.h
index 1ba0db076..55d5f3b33 100644
--- a/src/core/favicon_service_factory_qt.h
+++ b/src/core/favicon_service_factory_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -84,9 +48,10 @@ public:
void OnHistoryServiceCreated(history::HistoryService *history_service) override;
void Shutdown() override;
- bool CanAddURL(const GURL &url) override;
+ history::CanAddURLCallback GetThreadSafeCanAddURLCallback() const override;
void NotifyProfileError(sql::InitStatus init_status, const std::string &diagnostics) override;
std::unique_ptr<history::HistoryBackendClient> CreateBackendClient() override;
+ void UpdateBookmarkLastUsedTime(const base::Uuid &, base::Time) override;
};
class HistoryServiceFactoryQt : public BrowserContextKeyedServiceFactory
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp
index 90f5dcc07..9b4521358 100644
--- a/src/core/file_picker_controller.cpp
+++ b/src/core/file_picker_controller.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "file_picker_controller.h"
#include "type_conversion.h"
@@ -114,16 +78,16 @@ void FilePickerController::accepted(const QStringList &files)
base::FilePath filePath = toFilePath(urlString).NormalizePathSeparators();
std::vector<base::FilePath::StringType> pathComponents;
// Splits the file URL into scheme, host name, path and file name.
- filePath.GetComponents(&pathComponents);
+ pathComponents = filePath.GetComponents();
QString absolutePath;
-#if !defined(OS_WIN)
+#if !defined(Q_OS_WIN)
absolutePath = "/";
#endif
QString scheme = toQt(pathComponents[0]);
if (scheme.size() > 5) {
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
// There is no slash at the end of the file scheme and it is valid on Windows: file:C:/
if (scheme.size() == 7 && scheme.at(5).isLetter() && scheme.at(6) == ':') {
absolutePath += scheme.at(5) + ":/";
@@ -131,7 +95,7 @@ void FilePickerController::accepted(const QStringList &files)
#endif
qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString));
continue;
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
}
#endif
}
@@ -140,7 +104,7 @@ void FilePickerController::accepted(const QStringList &files)
if (base::FilePath::IsSeparator(urlString.at(5).toLatin1())
&& base::FilePath::IsSeparator(urlString.at(6).toLatin1())
&& !base::FilePath::IsSeparator(urlString.at(7).toLatin1())) {
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
if (urlString.at(8) != ':' && pathComponents.size() > 2) {
absolutePath += "//";
#else
@@ -172,7 +136,7 @@ void FilePickerController::accepted(const QVariant &files)
{
QStringList stringList;
- if (files.canConvert(QMetaType::QStringList)) {
+ if (files.canConvert(QMetaType{QMetaType::QStringList})) {
stringList = files.toStringList();
} else if (files.canConvert<QList<QUrl> >()) {
const QList<QUrl> urls = files.value<QList<QUrl>>();
@@ -215,17 +179,20 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
if (d_ptr->fileDialogListener) {
QStringList files(filesList);
base::FilePath baseDir;
- if (d_ptr->mode == UploadFolder && !filesList.isEmpty()
- && QFileInfo(filesList.first()).isDir()) {
- // Enumerate the directory
- files = listRecursively(QDir(filesList.first()));
- baseDir = toFilePath(filesList.first());
+ if (d_ptr->mode == UploadFolder && !filesList.isEmpty()) {
+ if (QFileInfo(filesList.first()).isDir()) {
+ // Enumerate the directory
+ files = listRecursively(QDir(filesList.first()));
+ baseDir = toFilePath(filesList.first());
+ } else {
+ baseDir = toFilePath(filesList.first()).DirName();
+ }
}
std::vector<blink::mojom::FileChooserFileInfoPtr> chooser_files;
- for (const auto &file : qAsConst(files)) {
+ for (const auto &file : std::as_const(files)) {
chooser_files.push_back(blink::mojom::FileChooserFileInfo::NewNativeFile(
- blink::mojom::NativeFileInfo::New(toFilePath(file), base::string16())));
+ blink::mojom::NativeFileInfo::New(toFilePath(file), std::u16string())));
}
if (files.isEmpty())
@@ -234,9 +201,13 @@ void FilePickerController::filesSelectedInChooser(const QStringList &filesList)
d_ptr->fileDialogListener->FileSelected(
std::move(chooser_files), baseDir,
static_cast<blink::mojom::FileChooserParams::Mode>(d_ptr->mode));
+
+ // release the fileSelectListener manually because it blocks fullscreen requests in chromium
+ // see QTBUG-106975
+ d_ptr->fileDialogListener.reset();
} else if (d_ptr->fileSystemAccessDialogListener) {
std::vector<base::FilePath> files;
- for (const auto &file : qAsConst(filesList)) {
+ for (const auto &file : std::as_const(filesList)) {
files.push_back(toFilePath(file));
}
@@ -287,7 +258,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
const QMimeType &mimeType = mimeDatabase.mimeTypeForName(type);
if (mimeType.isValid() && !mimeType.globPatterns().isEmpty()) {
QString globs = mimeType.globPatterns().join(" ");
- acceptedGlobs.append(globs);
+ acceptedGlobs.append(mimeType.globPatterns());
nameFilters.append(mimeType.comment() + " (" + globs + ")");
}
} else if (type.endsWith("/*")) {
@@ -298,7 +269,7 @@ QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTyp
for (const QMimeType &m : allMimeTypes) {
if (m.name().startsWith(type) && !m.globPatterns().isEmpty()) {
QString globs = m.globPatterns().join(" ");
- acceptedGlobs.append(globs);
+ acceptedGlobs.append(m.globPatterns());
nameFilters.append(m.comment() + " (" + globs + ")");
}
}
diff --git a/src/core/file_picker_controller.h b/src/core/file_picker_controller.h
index ec3b5ba1d..42ffd6a2d 100644
--- a/src/core/file_picker_controller.h
+++ b/src/core/file_picker_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -58,7 +22,7 @@
namespace QtWebEngineCore {
class FilePickerControllerPrivate;
-class Q_WEBENGINECORE_PRIVATE_EXPORT FilePickerController : public QObject {
+class Q_WEBENGINECORE_EXPORT FilePickerController : public QObject {
Q_OBJECT
public:
enum FileChooserMode {
diff --git a/src/core/file_system_access/file_system_access_permission_context_factory_qt.cpp b/src/core/file_system_access/file_system_access_permission_context_factory_qt.cpp
new file mode 100644
index 000000000..51c8a8991
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_context_factory_qt.cpp
@@ -0,0 +1,61 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "file_system_access_permission_context_factory_qt.h"
+
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+#include <QtGlobal>
+
+namespace QtWebEngineCore {
+
+// static
+FileSystemAccessPermissionContextQt *
+FileSystemAccessPermissionContextFactoryQt::GetForProfile(content::BrowserContext *profile)
+{
+ return static_cast<FileSystemAccessPermissionContextQt *>(
+ GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+FileSystemAccessPermissionContextQt *
+FileSystemAccessPermissionContextFactoryQt::GetForProfileIfExists(content::BrowserContext *profile)
+{
+ return static_cast<FileSystemAccessPermissionContextQt *>(
+ GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+FileSystemAccessPermissionContextFactoryQt *
+FileSystemAccessPermissionContextFactoryQt::GetInstance()
+{
+ return base::Singleton<FileSystemAccessPermissionContextFactoryQt>::get();
+}
+
+FileSystemAccessPermissionContextFactoryQt::FileSystemAccessPermissionContextFactoryQt()
+ : BrowserContextKeyedServiceFactory("FileSystemAccessPermissionContext",
+ BrowserContextDependencyManager::GetInstance())
+{
+}
+
+FileSystemAccessPermissionContextFactoryQt::~FileSystemAccessPermissionContextFactoryQt() = default;
+
+content::BrowserContext *FileSystemAccessPermissionContextFactoryQt::GetBrowserContextToUse(
+ content::BrowserContext *context) const
+{
+ return context;
+}
+
+KeyedService *FileSystemAccessPermissionContextFactoryQt::BuildServiceInstanceFor(
+ content::BrowserContext *context) const
+{
+ return new FileSystemAccessPermissionContextQt(context);
+}
+
+void FileSystemAccessPermissionContextFactoryQt::BrowserContextShutdown(
+ content::BrowserContext *context)
+{
+ Q_UNUSED(context);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/file_system_access/file_system_access_permission_context_factory_qt.h b/src/core/file_system_access/file_system_access_permission_context_factory_qt.h
new file mode 100644
index 000000000..1d98243d6
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_context_factory_qt.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_FACTORY_QT_H
+#define FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_FACTORY_QT_H
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+#include "file_system_access_permission_context_qt.h"
+
+namespace QtWebEngineCore {
+
+class FileSystemAccessPermissionContextFactoryQt : public BrowserContextKeyedServiceFactory
+{
+public:
+ static FileSystemAccessPermissionContextQt *GetForProfile(content::BrowserContext *profile);
+ static FileSystemAccessPermissionContextQt *
+ GetForProfileIfExists(content::BrowserContext *profile);
+ static FileSystemAccessPermissionContextFactoryQt *GetInstance();
+
+private:
+ friend struct base::DefaultSingletonTraits<FileSystemAccessPermissionContextFactoryQt>;
+
+ FileSystemAccessPermissionContextFactoryQt();
+ ~FileSystemAccessPermissionContextFactoryQt() override;
+
+ // BrowserContextKeyedServiceFactory
+ content::BrowserContext *
+ GetBrowserContextToUse(content::BrowserContext *context) const override;
+ KeyedService *BuildServiceInstanceFor(content::BrowserContext *profile) const override;
+ void BrowserContextShutdown(content::BrowserContext *context) override;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_FACTORY_QT_H
diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.cpp b/src/core/file_system_access/file_system_access_permission_context_qt.cpp
new file mode 100644
index 000000000..c290aab82
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_context_qt.cpp
@@ -0,0 +1,479 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// This file is based on chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc:
+// Copyright 2019 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 "file_system_access_permission_context_qt.h"
+
+#include "base/base_paths.h"
+#include "base/path_service.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "chrome/common/chrome_paths.h"
+#include "components/content_settings/core/common/content_settings_types.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+
+#include "file_system_access_permission_grant_qt.h"
+#include "type_conversion.h"
+
+#include <QCoreApplication>
+#include <QStandardPaths>
+
+namespace QtWebEngineCore {
+
+// Sentinel used to indicate that no PathService key is specified for a path in
+// the struct below.
+constexpr const int kNoBasePathKey = -1;
+
+enum BlockType { kBlockAllChildren, kBlockNestedDirectories, kDontBlockChildren, kDontBlockAppFolder };
+
+const struct
+{
+ // base::BasePathKey value (or one of the platform specific extensions to it)
+ // for a path that should be blocked. Specify kNoBasePathKey if |path| should
+ // be used instead.
+ int base_path_key;
+
+ // Explicit path to block instead of using |base_path_key|. Set to nullptr to
+ // use |base_path_key| on its own. If both |base_path_key| and |path| are set,
+ // |path| is treated relative to the path |base_path_key| resolves to.
+ const base::FilePath::CharType *path;
+
+ // If this is set to kDontBlockChildren, only the given path and its parents
+ // are blocked. If this is set to kBlockAllChildren, all children of the given
+ // path are blocked as well. Finally if this is set to kBlockNestedDirectories
+ // access is allowed to individual files in the directory, but nested
+ // directories are still blocked.
+ // The BlockType of the nearest ancestor of a path to check is what ultimately
+ // determines if a path is blocked or not. If a blocked path is a descendent
+ // of another blocked path, then it may override the child-blocking policy of
+ // its ancestor. For example, if /home blocks all children, but
+ // /home/downloads does not, then /home/downloads/file.ext will *not* be
+ // blocked.
+ BlockType type;
+} kBlockedPaths[] = {
+ // Don't allow users to share their entire home directory, entire desktop or
+ // entire documents folder, but do allow sharing anything inside those
+ // directories not otherwise blocked.
+ { base::DIR_HOME, nullptr, kDontBlockChildren },
+ { base::DIR_USER_DESKTOP, nullptr, kDontBlockChildren },
+ { chrome::DIR_USER_DOCUMENTS, nullptr, kDontBlockChildren },
+ // Similar restrictions for the downloads directory.
+ { chrome::DIR_DEFAULT_DOWNLOADS, nullptr, kDontBlockChildren },
+ { chrome::DIR_DEFAULT_DOWNLOADS_SAFE, nullptr, kDontBlockChildren },
+ // The Chrome installation itself should not be modified by the web.
+ { base::DIR_EXE, nullptr, kBlockAllChildren },
+ { base::DIR_MODULE, nullptr, kBlockAllChildren },
+ { base::DIR_ASSETS, nullptr, kBlockAllChildren },
+ // And neither should the configuration of at least the currently running
+ // Chrome instance (note that this does not take --user-data-dir command
+ // line overrides into account).
+ { chrome::DIR_USER_DATA, nullptr, kBlockAllChildren },
+ // ~/.ssh is pretty sensitive on all platforms, so block access to that.
+ { base::DIR_HOME, FILE_PATH_LITERAL(".ssh"), kBlockAllChildren },
+ // And limit access to ~/.gnupg as well.
+ { base::DIR_HOME, FILE_PATH_LITERAL(".gnupg"), kBlockAllChildren },
+#if defined(OS_WIN)
+ // Some Windows specific directories to block, basically all apps, the
+ // operating system itself, as well as configuration data for apps.
+ { base::DIR_PROGRAM_FILES, nullptr, kBlockAllChildren },
+ { base::DIR_PROGRAM_FILESX86, nullptr, kBlockAllChildren },
+ { base::DIR_PROGRAM_FILES6432, nullptr, kBlockAllChildren },
+ { base::DIR_WINDOWS, nullptr, kBlockAllChildren },
+ { base::DIR_ROAMING_APP_DATA, nullptr, kBlockAllChildren },
+ { base::DIR_LOCAL_APP_DATA, nullptr, kBlockAllChildren },
+ // Whitelist AppData\Local\Temp to make the default location of QDir::tempPath(),
+ // QTemporaryFile and QTemporaryDir working on Windows.
+ { base::DIR_LOCAL_APP_DATA, FILE_PATH_LITERAL("Temp"), kDontBlockAppFolder },
+ { base::DIR_COMMON_APP_DATA, nullptr, kBlockAllChildren },
+ // Opening a file from an MTP device, such as a smartphone or a camera, is
+ // implemented by Windows as opening a file in the temporary internet files
+ // directory. To support that, allow opening files in that directory, but
+ // not whole directories.
+ { base::DIR_IE_INTERNET_CACHE, nullptr, kBlockNestedDirectories },
+#endif
+#if defined(OS_MAC)
+ // Similar Mac specific blocks.
+ { base::DIR_APP_DATA, nullptr, kBlockAllChildren },
+ { base::DIR_HOME, FILE_PATH_LITERAL("Library"), kBlockAllChildren },
+ // Allow access to iCloud files.
+ { base::DIR_HOME, FILE_PATH_LITERAL("Library/Mobile Documents"), kDontBlockChildren },
+#endif
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+ // On Linux also block access to devices via /dev, as well as security
+ // sensitive data in /sys and /proc.
+ { kNoBasePathKey, FILE_PATH_LITERAL("/dev"), kBlockAllChildren },
+ { kNoBasePathKey, FILE_PATH_LITERAL("/sys"), kBlockAllChildren },
+ { kNoBasePathKey, FILE_PATH_LITERAL("/proc"), kBlockAllChildren },
+ // And block all of ~/.config, matching the similar restrictions on mac
+ // and windows.
+ { base::DIR_HOME, FILE_PATH_LITERAL(".config"), kBlockAllChildren },
+ // Block ~/.dbus as well, just in case, although there probably isn't much a
+ // website can do with access to that directory and its contents.
+ { base::DIR_HOME, FILE_PATH_LITERAL(".dbus"), kBlockAllChildren },
+#endif
+ // TODO(https://crbug.com/984641): Refine this list, for example add
+ // XDG_CONFIG_HOME when it is not set ~/.config?
+};
+
+bool ShouldBlockAccessToPath(const base::FilePath &check_path, HandleType handle_type)
+{
+ DCHECK(!check_path.empty());
+ DCHECK(check_path.IsAbsolute());
+
+ base::FilePath nearest_ancestor;
+ int nearest_ancestor_path_key = kNoBasePathKey;
+ BlockType nearest_ancestor_block_type = kDontBlockChildren;
+ for (const auto &block : kBlockedPaths) {
+ base::FilePath blocked_path;
+ if (block.base_path_key != kNoBasePathKey) {
+ if (!base::PathService::Get(block.base_path_key, &blocked_path))
+ continue;
+ if (block.path)
+ blocked_path = blocked_path.Append(block.path);
+ } else {
+ DCHECK(block.path);
+ blocked_path = base::FilePath(block.path);
+ }
+
+ if (check_path == blocked_path || check_path.IsParent(blocked_path)) {
+ VLOG(1) << "Blocking access to " << check_path << " because it is a parent of "
+ << blocked_path << " (" << block.base_path_key << ")";
+ return true;
+ }
+
+ if (blocked_path.IsParent(check_path)
+ && (nearest_ancestor.empty() || nearest_ancestor.IsParent(blocked_path))) {
+ nearest_ancestor = blocked_path;
+ nearest_ancestor_path_key = block.base_path_key;
+ nearest_ancestor_block_type = block.type;
+ }
+ }
+
+ // The path we're checking is not in a potentially blocked directory, or the
+ // nearest ancestor does not block access to its children. Grant access.
+ if (nearest_ancestor.empty() || nearest_ancestor_block_type == kDontBlockChildren)
+ return false;
+
+ // The path we're checking is a file, and the nearest ancestor only blocks
+ // access to directories. Grant access.
+ if (handle_type == HandleType::kFile && nearest_ancestor_block_type == kBlockNestedDirectories)
+ return false;
+
+ if (nearest_ancestor_block_type == kDontBlockAppFolder) {
+ // Relative path from the nearest blocklisted ancestor
+ base::FilePath diff;
+ nearest_ancestor.AppendRelativePath(check_path, &diff);
+
+ auto diff_components = diff.GetComponents();
+ if (diff_components.size() > 0 && toQt(diff_components[0]).contains(QCoreApplication::applicationName())) {
+ // The relative path contains the application name. Grant access.
+ return false;
+ }
+ }
+
+ // The nearest ancestor blocks access to its children, so block access.
+ VLOG(1) << "Blocking access to " << check_path << " because it is inside " << nearest_ancestor
+ << " (" << nearest_ancestor_path_key << ")";
+ return true;
+}
+
+struct FileSystemAccessPermissionContextQt::OriginState
+{
+ // Raw pointers, owned collectively by all the handles that reference this
+ // grant. When last reference goes away this state is cleared as well by
+ // PermissionGrantDestroyed().
+ std::map<base::FilePath, FileSystemAccessPermissionGrantQt *> read_grants;
+ std::map<base::FilePath, FileSystemAccessPermissionGrantQt *> write_grants;
+};
+
+FileSystemAccessPermissionContextQt::FileSystemAccessPermissionContextQt(
+ content::BrowserContext *context)
+ : m_profile(context)
+{
+}
+
+FileSystemAccessPermissionContextQt::~FileSystemAccessPermissionContextQt() = default;
+
+scoped_refptr<content::FileSystemAccessPermissionGrant>
+FileSystemAccessPermissionContextQt::GetReadPermissionGrant(const url::Origin &origin,
+ const base::FilePath &path,
+ HandleType handle_type,
+ UserAction user_action)
+{
+ auto &origin_state = m_origins[origin];
+ auto *&existing_grant = origin_state.read_grants[path];
+ scoped_refptr<FileSystemAccessPermissionGrantQt> new_grant;
+
+ if (existing_grant && existing_grant->handleType() != handle_type) {
+ // |path| changed from being a directory to being a file or vice versa,
+ // don't just re-use the existing grant but revoke the old grant before
+ // creating a new grant.
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::DENIED);
+ existing_grant = nullptr;
+ }
+
+ if (!existing_grant) {
+ new_grant = base::MakeRefCounted<FileSystemAccessPermissionGrantQt>(
+ m_weakFactory.GetWeakPtr(), origin, path, handle_type, GrantType::kRead);
+ existing_grant = new_grant.get();
+ }
+
+ // If a parent directory is already readable this new grant should also be readable.
+ if (new_grant && AncestorHasActivePermission(origin, path, GrantType::kRead)) {
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED);
+ return existing_grant;
+ }
+
+ switch (user_action) {
+ case UserAction::kOpen:
+ case UserAction::kSave:
+ // Open and Save dialog only grant read access for individual files.
+ if (handle_type == HandleType::kDirectory)
+ break;
+ Q_FALLTHROUGH();
+ case UserAction::kDragAndDrop:
+ // Drag&drop grants read access for all handles.
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED);
+ break;
+ case UserAction::kLoadFromStorage:
+ break;
+ case UserAction::kNone:
+ Q_UNREACHABLE();
+ }
+
+ return existing_grant;
+}
+
+scoped_refptr<content::FileSystemAccessPermissionGrant>
+FileSystemAccessPermissionContextQt::GetWritePermissionGrant(const url::Origin &origin,
+ const base::FilePath &path,
+ HandleType handle_type,
+ UserAction user_action)
+{
+ auto &origin_state = m_origins[origin];
+ auto *&existing_grant = origin_state.write_grants[path];
+ scoped_refptr<FileSystemAccessPermissionGrantQt> new_grant;
+
+ if (existing_grant && existing_grant->handleType() != handle_type) {
+ // |path| changed from being a directory to being a file or vice versa,
+ // don't just re-use the existing grant but revoke the old grant before
+ // creating a new grant.
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::DENIED);
+ existing_grant = nullptr;
+ }
+
+ if (!existing_grant) {
+ new_grant = base::MakeRefCounted<FileSystemAccessPermissionGrantQt>(
+ m_weakFactory.GetWeakPtr(), origin, path, handle_type, GrantType::kWrite);
+ existing_grant = new_grant.get();
+ }
+
+ // If a parent directory is already writable this new grant should also be writable.
+ if (new_grant && AncestorHasActivePermission(origin, path, GrantType::kWrite)) {
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED);
+ return existing_grant;
+ }
+
+ switch (user_action) {
+ case UserAction::kSave:
+ // Only automatically grant write access for save dialogs.
+ existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED);
+ break;
+ case UserAction::kOpen:
+ case UserAction::kDragAndDrop:
+ case UserAction::kLoadFromStorage:
+ break;
+ case UserAction::kNone:
+ Q_UNREACHABLE();
+ }
+
+ return existing_grant;
+}
+
+void FileSystemAccessPermissionContextQt::ConfirmSensitiveEntryAccess(
+ const url::Origin &origin, PathType path_type, const base::FilePath &path,
+ HandleType handle_type, UserAction user_action,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback)
+{
+ if (path_type == PathType::kExternal) {
+ std::move(callback).Run(SensitiveEntryResult::kAllowed);
+ return;
+ }
+
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, { base::MayBlock(), base::TaskPriority::USER_VISIBLE },
+ base::BindOnce(&ShouldBlockAccessToPath, path, handle_type),
+ base::BindOnce(&FileSystemAccessPermissionContextQt::DidConfirmSensitiveDirectoryAccess,
+ m_weakFactory.GetWeakPtr(), origin, path, handle_type, user_action, frame_id,
+ std::move(callback)));
+}
+
+void FileSystemAccessPermissionContextQt::PerformAfterWriteChecks(
+ std::unique_ptr<content::FileSystemAccessWriteItem> item,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(AfterWriteCheckResult)> callback)
+{
+ Q_UNUSED(item);
+ Q_UNUSED(frame_id);
+ std::move(callback).Run(AfterWriteCheckResult::kAllow);
+}
+
+bool FileSystemAccessPermissionContextQt::CanObtainReadPermission(const url::Origin &origin)
+{
+ Q_UNUSED(origin);
+ return true;
+}
+
+bool FileSystemAccessPermissionContextQt::CanObtainWritePermission(const url::Origin &origin)
+{
+ Q_UNUSED(origin);
+ return true;
+}
+
+void FileSystemAccessPermissionContextQt::SetLastPickedDirectory(const url::Origin &origin,
+ const std::string &id,
+ const base::FilePath &path,
+ const PathType type)
+{
+ Q_UNUSED(origin);
+
+ FileSystemAccessPermissionContextQt::PathInfo info;
+ info.path = path;
+ info.type = type;
+ m_lastPickedDirectories.insert({ id, info });
+}
+
+FileSystemAccessPermissionContextQt::PathInfo
+FileSystemAccessPermissionContextQt::GetLastPickedDirectory(const url::Origin &origin,
+ const std::string &id)
+{
+ Q_UNUSED(origin);
+
+ return m_lastPickedDirectories.find(id) != m_lastPickedDirectories.end()
+ ? m_lastPickedDirectories[id]
+ : FileSystemAccessPermissionContextQt::PathInfo();
+}
+
+base::FilePath FileSystemAccessPermissionContextQt::GetWellKnownDirectoryPath(
+ blink::mojom::WellKnownDirectory directory, const url::Origin &origin)
+{
+ QStandardPaths::StandardLocation location = QStandardPaths::DocumentsLocation;
+ switch (directory) {
+ case blink::mojom::WellKnownDirectory::kDirDesktop:
+ location = QStandardPaths::DesktopLocation;
+ break;
+ case blink::mojom::WellKnownDirectory::kDirDocuments:
+ location = QStandardPaths::DocumentsLocation;
+ break;
+ case blink::mojom::WellKnownDirectory::kDirDownloads:
+ location = QStandardPaths::DownloadLocation;
+ break;
+ case blink::mojom::WellKnownDirectory::kDirMusic:
+ location = QStandardPaths::MusicLocation;
+ break;
+ case blink::mojom::WellKnownDirectory::kDirPictures:
+ location = QStandardPaths::PicturesLocation;
+ break;
+ case blink::mojom::WellKnownDirectory::kDirVideos:
+ location = QStandardPaths::MoviesLocation;
+ break;
+ }
+
+ return toFilePath(QStandardPaths::writableLocation(location));
+}
+
+void FileSystemAccessPermissionContextQt::NavigatedAwayFromOrigin(const url::Origin &origin)
+{
+ // If the last top-level WebContents for an origin is closed (or is navigated to another
+ // origin), all the permissions for that origin will be revoked.
+
+ auto it = m_origins.find(origin);
+ // If we have no permissions for the origin, there is nothing to do.
+ if (it == m_origins.end())
+ return;
+
+ std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
+ for (content::WebContentsImpl *web_contents : list) {
+ url::Origin web_contents_origin = url::Origin::Create(web_contents->GetLastCommittedURL());
+ // Found a tab for this origin, so early exit and don't revoke grants.
+ if (web_contents_origin == origin)
+ return;
+ }
+
+ OriginState &origin_state = it->second;
+ for (auto &grant : origin_state.read_grants)
+ grant.second->SetStatus(blink::mojom::PermissionStatus::ASK);
+ for (auto &grant : origin_state.write_grants)
+ grant.second->SetStatus(blink::mojom::PermissionStatus::ASK);
+}
+
+void FileSystemAccessPermissionContextQt::DidConfirmSensitiveDirectoryAccess(
+ const url::Origin &origin, const base::FilePath &path, HandleType handle_type, UserAction user_action,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback, bool should_block)
+{
+ Q_UNUSED(origin);
+ Q_UNUSED(path);
+ Q_UNUSED(handle_type);
+ Q_UNUSED(user_action);
+ Q_UNUSED(frame_id);
+
+ if (should_block)
+ std::move(callback).Run(SensitiveEntryResult::kAbort);
+ else
+ std::move(callback).Run(SensitiveEntryResult::kAllowed);
+}
+
+bool FileSystemAccessPermissionContextQt::AncestorHasActivePermission(
+ const url::Origin &origin, const base::FilePath &path, GrantType grant_type) const
+{
+ auto it = m_origins.find(origin);
+ if (it == m_origins.end())
+ return false;
+
+ const auto &relevant_grants = grant_type == GrantType::kWrite ? it->second.write_grants : it->second.read_grants;
+ if (relevant_grants.empty())
+ return false;
+
+ // Permissions are inherited from the closest ancestor.
+ for (base::FilePath parent = path.DirName(); parent != parent.DirName(); parent = parent.DirName()) {
+ auto i = relevant_grants.find(parent);
+ if (i != relevant_grants.end() && i->second && i->second->GetStatus() == blink::mojom::PermissionStatus::GRANTED)
+ return true;
+ }
+ return false;
+}
+
+std::u16string FileSystemAccessPermissionContextQt::GetPickerTitle(const blink::mojom::FilePickerOptionsPtr &)
+{
+ return {};
+}
+
+void FileSystemAccessPermissionContextQt::PermissionGrantDestroyed(
+ FileSystemAccessPermissionGrantQt *grant)
+{
+ auto it = m_origins.find(grant->origin());
+ if (it == m_origins.end())
+ return;
+
+ auto &grants =
+ grant->type() == GrantType::kRead ? it->second.read_grants : it->second.write_grants;
+ auto grant_it = grants.find(grant->path());
+
+ if (grant_it == grants.end()) {
+ return;
+ }
+ if (grant_it->second == grant)
+ grants.erase(grant_it);
+}
+
+void FileSystemAccessPermissionContextQt::NotifyEntryMoved(const url::Origin &, const base::FilePath &, const base::FilePath &)
+{
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.h b/src/core/file_system_access/file_system_access_permission_context_qt.h
new file mode 100644
index 000000000..06fbfae3f
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_context_qt.h
@@ -0,0 +1,86 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// This file is based on chrome/browser/file_system_access/chrome_file_system_access_permission_context.h:
+// Copyright 2019 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.
+
+#ifndef FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_QT_H
+#define FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_QT_H
+
+#include "base/files/file_path.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/file_system_access_permission_context.h"
+#include "content/public/browser/global_routing_id.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace QtWebEngineCore {
+class FileSystemAccessPermissionGrantQt;
+class FileSystemAccessPermissionContextQt : public content::FileSystemAccessPermissionContext,
+ public KeyedService
+{
+public:
+ explicit FileSystemAccessPermissionContextQt(content::BrowserContext *context);
+ ~FileSystemAccessPermissionContextQt() override;
+
+ enum class GrantType { kRead, kWrite };
+
+ // content::FileSystemAccessPermissionContext:
+ scoped_refptr<content::FileSystemAccessPermissionGrant>
+ GetReadPermissionGrant(const url::Origin &origin, const base::FilePath &path,
+ HandleType handle_type, UserAction user_action) override;
+ scoped_refptr<content::FileSystemAccessPermissionGrant>
+ GetWritePermissionGrant(const url::Origin &origin, const base::FilePath &path,
+ HandleType handle_type, UserAction user_action) override;
+ void ConfirmSensitiveEntryAccess(
+ const url::Origin &origin, PathType path_type, const base::FilePath &path,
+ HandleType handle_type, UserAction user_action,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback) override;
+ void PerformAfterWriteChecks(std::unique_ptr<content::FileSystemAccessWriteItem> item,
+ content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(AfterWriteCheckResult)> callback) override;
+ bool CanObtainReadPermission(const url::Origin &origin) override;
+ bool CanObtainWritePermission(const url::Origin &origin) override;
+ void SetLastPickedDirectory(const url::Origin &origin, const std::string &id,
+ const base::FilePath &path, const PathType type) override;
+ FileSystemAccessPermissionContextQt::PathInfo
+ GetLastPickedDirectory(const url::Origin &origin, const std::string &id) override;
+ base::FilePath GetWellKnownDirectoryPath(blink::mojom::WellKnownDirectory directory, const url::Origin &origin) override;
+ std::u16string GetPickerTitle(const blink::mojom::FilePickerOptionsPtr &) override;
+ void NotifyEntryMoved(const url::Origin &, const base::FilePath &, const base::FilePath &) override;
+
+ void NavigatedAwayFromOrigin(const url::Origin &origin);
+ content::BrowserContext *profile() const { return m_profile; }
+
+ void PermissionGrantDestroyed(FileSystemAccessPermissionGrantQt *);
+
+private:
+ class PermissionGrantImpl;
+
+ void DidConfirmSensitiveDirectoryAccess(
+ const url::Origin &origin, const base::FilePath &path, HandleType handle_type,
+ UserAction user_action, content::GlobalRenderFrameHostId frame_id,
+ base::OnceCallback<void(SensitiveEntryResult)> callback, bool should_block);
+ bool AncestorHasActivePermission(const url::Origin &origin,
+ const base::FilePath &path,
+ GrantType grant_type) const;
+
+ content::BrowserContext *m_profile;
+
+ // Permission state per origin.
+ struct OriginState;
+ std::map<url::Origin, OriginState> m_origins;
+
+ std::map<std::string, FileSystemAccessPermissionContextQt::PathInfo> m_lastPickedDirectories;
+
+ base::WeakPtrFactory<FileSystemAccessPermissionContextQt> m_weakFactory { this };
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FILE_SYSTEM_ACCESS_PERMISSION_CONTEXT_QT_H
diff --git a/src/core/file_system_access/file_system_access_permission_grant_qt.cpp b/src/core/file_system_access/file_system_access_permission_grant_qt.cpp
new file mode 100644
index 000000000..67fa1c8cf
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_grant_qt.cpp
@@ -0,0 +1,146 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "file_system_access_permission_grant_qt.h"
+
+#include "file_system_access_permission_request_manager_qt.h"
+
+#include "components/permissions/permission_util.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.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/browser/disallow_activation_reason.h"
+#include "url/origin.h"
+
+namespace QtWebEngineCore {
+
+FileSystemAccessPermissionGrantQt::FileSystemAccessPermissionGrantQt(
+ base::WeakPtr<FileSystemAccessPermissionContextQt> context, const url::Origin &origin,
+ const base::FilePath &path, HandleType handle_type, GrantType type)
+ : m_context(context), m_origin(origin), m_path(path), m_handleType(handle_type), m_type(type)
+{
+}
+FileSystemAccessPermissionGrantQt::~FileSystemAccessPermissionGrantQt()
+{
+ if (m_context)
+ m_context->PermissionGrantDestroyed(this);
+}
+void FileSystemAccessPermissionGrantQt::RequestPermission(
+ content::GlobalRenderFrameHostId frame_id, UserActivationState user_activation_state,
+ base::OnceCallback<void(PermissionRequestOutcome)> callback)
+{
+ // Check if a permission request has already been processed previously. This
+ // check is done first because we don't want to reset the status of a
+ // permission if it has already been granted.
+ if (GetStatus() != blink::mojom::PermissionStatus::ASK || !m_context) {
+ if (GetStatus() == blink::mojom::PermissionStatus::GRANTED)
+ SetStatus(blink::mojom::PermissionStatus::GRANTED);
+ std::move(callback).Run(PermissionRequestOutcome::kRequestAborted);
+ return;
+ }
+
+ // Otherwise, perform checks and ask the user for permission.
+
+ content::RenderFrameHost *rfh = content::RenderFrameHost::FromID(frame_id);
+ if (!rfh) {
+ // Requested from a no longer valid render frame host.
+ std::move(callback).Run(PermissionRequestOutcome::kInvalidFrame);
+ return;
+ }
+
+ // Don't show request permission UI for an inactive RenderFrameHost as the
+ // page might not distinguish properly between user denying the permission
+ // and automatic rejection, leading to an inconsistent UX once the page
+ // becomes active again.
+ // - If this is called when RenderFrameHost is in BackForwardCache, evict
+ // the document from the cache.
+ // - If this is called when RenderFrameHost is in prerendering, cancel
+ // prerendering.
+ if (rfh->IsInactiveAndDisallowActivation(
+ content::DisallowActivationReasonId::kFileSystemAccessPermissionRequest)) {
+ std::move(callback).Run(PermissionRequestOutcome::kInvalidFrame);
+ return;
+ }
+
+ if (user_activation_state == UserActivationState::kRequired
+ && !rfh->HasTransientUserActivation()) {
+ // No permission prompts without user activation.
+ std::move(callback).Run(PermissionRequestOutcome::kNoUserActivation);
+ return;
+ }
+
+ content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(rfh);
+ if (!web_contents) {
+ // Requested from a worker, or a no longer existing tab.
+ std::move(callback).Run(PermissionRequestOutcome::kInvalidFrame);
+ return;
+ }
+
+ url::Origin embedding_origin = url::Origin::Create(web_contents->GetLastCommittedURL());
+ if (embedding_origin != m_origin) {
+ // Third party iframes are not allowed to request more permissions.
+ std::move(callback).Run(PermissionRequestOutcome::kThirdPartyContext);
+ return;
+ }
+
+ auto *request_manager =
+ FileSystemAccessPermissionRequestManagerQt::FromWebContents(web_contents);
+ if (!request_manager) {
+ std::move(callback).Run(PermissionRequestOutcome::kRequestAborted);
+ return;
+ }
+
+ // Drop fullscreen mode so that the user sees the URL bar.
+ base::ScopedClosureRunner fullscreen_block = web_contents->ForSecurityDropFullscreen();
+
+ FileSystemAccessPermissionRequestManagerQt::Access access = m_type == GrantType::kRead
+ ? FileSystemAccessPermissionRequestManagerQt::Access::kRead
+ : FileSystemAccessPermissionRequestManagerQt::Access::kWrite;
+
+ // If a website wants both read and write access, code in content will
+ // request those as two separate requests. The |request_manager| will then
+ // detect this and combine the two requests into one prompt. As such this
+ // code does not have to have any way to request Access::kReadWrite.
+
+ request_manager->AddRequest(
+ { m_origin, m_path, m_handleType, access },
+ base::BindOnce(&FileSystemAccessPermissionGrantQt::OnPermissionRequestResult, this,
+ std::move(callback)),
+ std::move(fullscreen_block));
+}
+
+void FileSystemAccessPermissionGrantQt::SetStatus(blink::mojom::PermissionStatus status)
+{
+ bool should_notify = m_status != status;
+ m_status = status;
+ if (should_notify)
+ NotifyPermissionStatusChanged();
+}
+
+void FileSystemAccessPermissionGrantQt::OnPermissionRequestResult(
+ base::OnceCallback<void(PermissionRequestOutcome)> callback, permissions::PermissionAction result)
+{
+ switch (result) {
+ case permissions::PermissionAction::GRANTED:
+ SetStatus(blink::mojom::PermissionStatus::GRANTED);
+ std::move(callback).Run(PermissionRequestOutcome::kUserGranted);
+ break;
+ case permissions::PermissionAction::DENIED:
+ SetStatus(blink::mojom::PermissionStatus::DENIED);
+ std::move(callback).Run(PermissionRequestOutcome::kUserDenied);
+ break;
+ case permissions::PermissionAction::DISMISSED:
+ case permissions::PermissionAction::IGNORED:
+ std::move(callback).Run(PermissionRequestOutcome::kUserDismissed);
+ break;
+ case permissions::PermissionAction::REVOKED:
+ case permissions::PermissionAction::GRANTED_ONCE:
+ case permissions::PermissionAction::NUM:
+ NOTREACHED();
+ break;
+ }
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/file_system_access/file_system_access_permission_grant_qt.h b/src/core/file_system_access/file_system_access_permission_grant_qt.h
new file mode 100644
index 000000000..829d2b889
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_grant_qt.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FILE_SYSTEM_ACCESS_PERMISSION_GRANT_QT_H
+#define FILE_SYSTEM_ACCESS_PERMISSION_GRANT_QT_H
+
+#include "content/public/browser/file_system_access_permission_grant.h"
+#include "url/origin.h"
+#include "file_system_access_permission_context_qt.h"
+#include "content/public/browser/global_routing_id.h"
+#include "components/permissions/permission_util.h"
+
+namespace QtWebEngineCore {
+
+using HandleType = content::FileSystemAccessPermissionContext::HandleType;
+using GrantType = FileSystemAccessPermissionContextQt::GrantType;
+
+class FileSystemAccessPermissionGrantQt : public content::FileSystemAccessPermissionGrant
+{
+public:
+ FileSystemAccessPermissionGrantQt(base::WeakPtr<FileSystemAccessPermissionContextQt> context,
+ const url::Origin &origin, const base::FilePath &path,
+ HandleType handle_type, GrantType type);
+
+ // content::FileSystemAccessPermissionGrant:
+ blink::mojom::PermissionStatus GetStatus() override { return m_status; }
+ base::FilePath GetPath() override { return m_path; }
+ void RequestPermission(content::GlobalRenderFrameHostId frame_id,
+ UserActivationState user_activation_state,
+ base::OnceCallback<void(PermissionRequestOutcome)> callback) override;
+
+ const url::Origin &origin() const { return m_origin; }
+ HandleType handleType() const { return m_handleType; }
+ const base::FilePath &path() const { return m_path; }
+ GrantType type() const { return m_type; }
+
+ void SetStatus(blink::mojom::PermissionStatus status);
+
+protected:
+ ~FileSystemAccessPermissionGrantQt() override;
+
+private:
+ void OnPermissionRequestResult(base::OnceCallback<void(PermissionRequestOutcome)> callback,
+ permissions::PermissionAction result);
+
+ base::WeakPtr<FileSystemAccessPermissionContextQt> const m_context;
+ const url::Origin m_origin;
+ const base::FilePath m_path;
+ const HandleType m_handleType;
+ const GrantType m_type;
+
+ // This member should only be updated via SetStatus(), to make sure
+ // observers are properly notified about any change in status.
+ blink::mojom::PermissionStatus m_status = blink::mojom::PermissionStatus::ASK;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FILE_SYSTEM_ACCESS_PERMISSION_GRANT_QT_H
diff --git a/src/core/file_system_access/file_system_access_permission_request_controller.h b/src/core/file_system_access/file_system_access_permission_request_controller.h
new file mode 100644
index 000000000..e659f81a7
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_request_controller.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_CONTROLLER_H
+#define FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_CONTROLLER_H
+
+#include "api/qwebenginefilesystemaccessrequest.h"
+#include "request_controller.h"
+
+using HandleType = QWebEngineFileSystemAccessRequest::HandleType;
+using AccessFlags = QWebEngineFileSystemAccessRequest::AccessFlags;
+
+namespace QtWebEngineCore {
+
+class FileSystemAccessPermissionRequestController : public RequestController
+{
+public:
+ FileSystemAccessPermissionRequestController(const QUrl &origin, const QUrl &filePath,
+ HandleType handleType, AccessFlags accessType)
+ : RequestController(origin)
+ , m_filePath(filePath)
+ , m_handleType(handleType)
+ , m_accessType(accessType)
+ {
+ }
+
+ QUrl filePath() const { return m_filePath; }
+ HandleType handleType() const { return m_handleType; }
+ AccessFlags accessFlags() const { return m_accessType; }
+
+private:
+ QUrl m_filePath;
+ HandleType m_handleType;
+ AccessFlags m_accessType;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_CONTROLLER_H
diff --git a/src/core/file_system_access/file_system_access_permission_request_controller_impl.cpp b/src/core/file_system_access/file_system_access_permission_request_controller_impl.cpp
new file mode 100644
index 000000000..f77c974d0
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_request_controller_impl.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "file_system_access_permission_request_controller_impl.h"
+
+#include "components/permissions/permission_util.h"
+#include "content/public/browser/file_system_access_permission_context.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+ASSERT_ENUMS_MATCH(content::FileSystemAccessPermissionContext::HandleType::kFile,
+ QWebEngineFileSystemAccessRequest::HandleType::File);
+ASSERT_ENUMS_MATCH(content::FileSystemAccessPermissionContext::HandleType::kDirectory,
+ QWebEngineFileSystemAccessRequest::HandleType::Directory);
+
+ASSERT_ENUMS_MATCH(FileSystemAccessPermissionRequestManagerQt::Access::kRead,
+ QWebEngineFileSystemAccessRequest::AccessFlag::Read);
+ASSERT_ENUMS_MATCH(FileSystemAccessPermissionRequestManagerQt::Access::kWrite,
+ QWebEngineFileSystemAccessRequest::AccessFlag::Write);
+
+FileSystemAccessPermissionRequestControllerImpl::FileSystemAccessPermissionRequestControllerImpl(
+ const FileSystemAccessPermissionRequestManagerQt::RequestData &request,
+ base::OnceCallback<void(permissions::PermissionAction result)> callback)
+ : FileSystemAccessPermissionRequestController(
+ toQt(request.origin.GetURL()), QUrl::fromLocalFile(toQt(request.path.value())),
+ (HandleType)request.handle_type, AccessFlags((int)request.access))
+ , m_callback(std::move(callback))
+{
+}
+
+FileSystemAccessPermissionRequestControllerImpl::~FileSystemAccessPermissionRequestControllerImpl()
+{
+ if (m_callback)
+ std::move(m_callback).Run(permissions::PermissionAction::IGNORED);
+}
+
+void FileSystemAccessPermissionRequestControllerImpl::accepted()
+{
+ std::move(m_callback).Run(permissions::PermissionAction::GRANTED);
+}
+
+void FileSystemAccessPermissionRequestControllerImpl::rejected()
+{
+ std::move(m_callback).Run(permissions::PermissionAction::DENIED);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/file_system_access/file_system_access_permission_request_controller_impl.h b/src/core/file_system_access/file_system_access_permission_request_controller_impl.h
new file mode 100644
index 000000000..6cca1e549
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_request_controller_impl.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_CONTROLLER_IMPL_H
+#define FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_CONTROLLER_IMPL_H
+
+#include "file_system_access_permission_request_controller.h"
+#include "file_system_access_permission_request_manager_qt.h"
+
+namespace QtWebEngineCore {
+
+class FileSystemAccessPermissionRequestControllerImpl final
+ : public FileSystemAccessPermissionRequestController
+{
+public:
+ FileSystemAccessPermissionRequestControllerImpl(
+ const FileSystemAccessPermissionRequestManagerQt::RequestData &request,
+ base::OnceCallback<void(permissions::PermissionAction result)> callback);
+
+ ~FileSystemAccessPermissionRequestControllerImpl();
+
+protected:
+ void accepted() override;
+ void rejected() override;
+
+private:
+ base::OnceCallback<void(permissions::PermissionAction result)> m_callback;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_CONTROLLER_IMPL_H
diff --git a/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp b/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp
new file mode 100644
index 000000000..c384dc7b3
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_request_manager_qt.cpp
@@ -0,0 +1,195 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "file_system_access_permission_request_manager_qt.h"
+
+#include "components/permissions/permission_util.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
+
+#include "api/qwebenginefilesystemaccessrequest.h"
+#include "file_system_access_permission_context_factory_qt.h"
+#include "file_system_access_permission_request_controller_impl.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+
+namespace QtWebEngineCore {
+
+bool RequestsAreIdentical(const FileSystemAccessPermissionRequestManagerQt::RequestData &a,
+ const FileSystemAccessPermissionRequestManagerQt::RequestData &b)
+{
+ return a.origin == b.origin && a.path == b.path && a.handle_type == b.handle_type
+ && a.access == b.access;
+}
+
+bool RequestsAreForSamePath(const FileSystemAccessPermissionRequestManagerQt::RequestData &a,
+ const FileSystemAccessPermissionRequestManagerQt::RequestData &b)
+{
+ return a.origin == b.origin && a.path == b.path && a.handle_type == b.handle_type;
+}
+
+struct FileSystemAccessPermissionRequestManagerQt::Request
+{
+ Request(RequestData data,
+ base::OnceCallback<void(permissions::PermissionAction result)> callback,
+ base::ScopedClosureRunner fullscreen_block)
+ : data(std::move(data))
+ {
+ callbacks.push_back(std::move(callback));
+ fullscreen_blocks.push_back(std::move(fullscreen_block));
+ }
+
+ RequestData data;
+ std::vector<base::OnceCallback<void(permissions::PermissionAction result)>> callbacks;
+ std::vector<base::ScopedClosureRunner> fullscreen_blocks;
+};
+
+FileSystemAccessPermissionRequestManagerQt::~FileSystemAccessPermissionRequestManagerQt() = default;
+
+void FileSystemAccessPermissionRequestManagerQt::AddRequest(
+ RequestData data, base::OnceCallback<void(permissions::PermissionAction result)> callback,
+ base::ScopedClosureRunner fullscreen_block)
+{
+ // Check if any pending requests are identical to the new request.
+ if (m_currentRequest && RequestsAreIdentical(m_currentRequest->data, data)) {
+ m_currentRequest->callbacks.push_back(std::move(callback));
+ m_currentRequest->fullscreen_blocks.push_back(std::move(fullscreen_block));
+ return;
+ }
+ for (const auto &request : m_queuedRequests) {
+ if (RequestsAreIdentical(request->data, data)) {
+ request->callbacks.push_back(std::move(callback));
+ request->fullscreen_blocks.push_back(std::move(fullscreen_block));
+ return;
+ }
+ if (RequestsAreForSamePath(request->data, data)) {
+ // This means access levels are different. Change the existing request
+ // to kReadWrite, and add the new callback.
+ request->data.access = Access::kReadWrite;
+ request->callbacks.push_back(std::move(callback));
+ request->fullscreen_blocks.push_back(std::move(fullscreen_block));
+ return;
+ }
+ }
+
+ m_queuedRequests.push_back(std::make_unique<Request>(std::move(data), std::move(callback),
+ std::move(fullscreen_block)));
+ if (!IsShowingRequest())
+ ScheduleShowRequest();
+}
+
+FileSystemAccessPermissionRequestManagerQt::FileSystemAccessPermissionRequestManagerQt(
+ content::WebContents *web_contents)
+ : content::WebContentsObserver(web_contents)
+ , content::WebContentsUserData<FileSystemAccessPermissionRequestManagerQt>(*web_contents)
+{
+}
+
+bool FileSystemAccessPermissionRequestManagerQt::CanShowRequest() const
+{
+ // Delay showing requests until the main frame is fully loaded.
+ // ScheduleShowRequest() will be called again when that happens.
+ return web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame() && !m_queuedRequests.empty()
+ && !m_currentRequest;
+}
+
+void FileSystemAccessPermissionRequestManagerQt::ScheduleShowRequest()
+{
+ if (!CanShowRequest())
+ return;
+
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&FileSystemAccessPermissionRequestManagerQt::DequeueAndShowRequest,
+ m_weakFactory.GetWeakPtr()));
+}
+
+void FileSystemAccessPermissionRequestManagerQt::DequeueAndShowRequest()
+{
+ if (!CanShowRequest())
+ return;
+
+ m_currentRequest = std::move(m_queuedRequests.front());
+ m_queuedRequests.pop_front();
+
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(
+ static_cast<content::WebContentsImpl *>(web_contents())->GetView())
+ ->client();
+ if (!client) {
+ LOG(ERROR)
+ << "Attempt to request file system access from content missing WebContents client";
+ for (auto &callback : m_currentRequest->callbacks)
+ std::move(callback).Run(permissions::PermissionAction::DENIED);
+ return;
+ }
+
+ QWebEngineFileSystemAccessRequest request(
+ std::make_shared<FileSystemAccessPermissionRequestControllerImpl>(
+ m_currentRequest->data,
+ base::BindOnce(
+ &FileSystemAccessPermissionRequestManagerQt::OnPermissionDialogResult,
+ m_weakFactory.GetWeakPtr())));
+ client->runFileSystemAccessRequest(std::move(request));
+}
+
+void FileSystemAccessPermissionRequestManagerQt::DocumentOnLoadCompletedInPrimaryMainFrame()
+{
+ // This is scheduled because while all calls to the browser have been
+ // issued at DOMContentLoaded, they may be bouncing around in scheduled
+ // callbacks finding the UI thread still. This makes sure we allow those
+ // scheduled calls to AddRequest to complete before we show the page-load
+ // permissions bubble.
+ if (!m_queuedRequests.empty())
+ ScheduleShowRequest();
+}
+
+void FileSystemAccessPermissionRequestManagerQt::DidFinishNavigation(
+ content::NavigationHandle *navigation)
+{
+ // We only care about top-level navigations that actually committed.
+ if (!navigation->IsInMainFrame() || !navigation->HasCommitted())
+ return;
+
+ auto src_origin = url::Origin::Create(navigation->GetPreviousPrimaryMainFrameURL());
+ auto dest_origin = url::Origin::Create(navigation->GetURL());
+ if (src_origin == dest_origin)
+ return;
+
+ // Navigated away from |src_origin|, tell permission context to check if
+ // permissions need to be revoked.
+ auto *context = FileSystemAccessPermissionContextFactoryQt::GetForProfileIfExists(
+ web_contents()->GetBrowserContext());
+ if (context)
+ context->NavigatedAwayFromOrigin(src_origin);
+}
+
+void FileSystemAccessPermissionRequestManagerQt::WebContentsDestroyed()
+{
+ auto src_origin = web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin();
+
+ // Navigated away from |src_origin|, tell permission context to check if
+ // permissions need to be revoked.
+ auto *context = FileSystemAccessPermissionContextFactoryQt::GetForProfileIfExists(
+ web_contents()->GetBrowserContext());
+ if (context)
+ context->NavigatedAwayFromOrigin(src_origin);
+}
+
+void FileSystemAccessPermissionRequestManagerQt::OnPermissionDialogResult(
+ permissions::PermissionAction result)
+{
+ DCHECK(m_currentRequest);
+ for (auto &callback : m_currentRequest->callbacks)
+ std::move(callback).Run(result);
+
+ m_currentRequest = nullptr;
+ if (!m_queuedRequests.empty())
+ ScheduleShowRequest();
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(FileSystemAccessPermissionRequestManagerQt);
+
+} // namespace QtWebEngineCore
diff --git a/src/core/file_system_access/file_system_access_permission_request_manager_qt.h b/src/core/file_system_access/file_system_access_permission_request_manager_qt.h
new file mode 100644
index 000000000..840854911
--- /dev/null
+++ b/src/core/file_system_access/file_system_access_permission_request_manager_qt.h
@@ -0,0 +1,79 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_MANAGER_QT_H
+#define FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_MANAGER_QT_H
+
+#include "base/containers/circular_deque.h"
+#include "base/files/file_path.h"
+#include "base/functional/callback_helpers.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/file_system_access_permission_context.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "url/origin.h"
+
+namespace permissions {
+enum class PermissionAction;
+}
+
+namespace QtWebEngineCore {
+
+class FileSystemAccessPermissionRequestManagerQt
+ : public content::WebContentsObserver,
+ public content::WebContentsUserData<FileSystemAccessPermissionRequestManagerQt>
+{
+public:
+ ~FileSystemAccessPermissionRequestManagerQt() override;
+
+ enum class Access {
+ // Only ask for read access.
+ kRead = 0x1,
+ // Only ask for write access, assuming read access has already been granted.
+ kWrite = 0x2,
+ // Ask for both read and write access.
+ kReadWrite = 0x3
+ };
+
+ struct RequestData
+ {
+ url::Origin origin;
+ base::FilePath path;
+ content::FileSystemAccessPermissionContext::HandleType handle_type;
+ Access access;
+ };
+
+ void AddRequest(RequestData request,
+ base::OnceCallback<void(permissions::PermissionAction result)> callback,
+ base::ScopedClosureRunner fullscreen_block);
+
+private:
+ friend class content::WebContentsUserData<FileSystemAccessPermissionRequestManagerQt>;
+
+ explicit FileSystemAccessPermissionRequestManagerQt(content::WebContents *web_contents);
+
+ bool IsShowingRequest() const { return m_currentRequest != nullptr; }
+ bool CanShowRequest() const;
+ void ScheduleShowRequest();
+ void DequeueAndShowRequest();
+
+ // content::WebContentsObserver
+ void DocumentOnLoadCompletedInPrimaryMainFrame() override;
+ void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
+ void WebContentsDestroyed() override;
+
+ void OnPermissionDialogResult(permissions::PermissionAction result);
+
+ struct Request;
+ // Request currently being shown in prompt.
+ std::unique_ptr<Request> m_currentRequest;
+ // Queued up requests.
+ base::circular_deque<std::unique_ptr<Request>> m_queuedRequests;
+
+ base::WeakPtrFactory<FileSystemAccessPermissionRequestManagerQt> m_weakFactory { this };
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FILE_SYSTEM_ACCESS_PERMISSION_REQUEST_MANAGER_QT_H
diff --git a/src/core/find_text_helper.cpp b/src/core/find_text_helper.cpp
index 3f0852536..5dc12fab7 100644
--- a/src/core/find_text_helper.cpp
+++ b/src/core/find_text_helper.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "find_text_helper.h"
#include "qwebenginefindtextresult.h"
@@ -121,7 +85,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively,
m_previousFindText = findText;
m_currentFindRequestId = m_findRequestIdCounter++;
- m_webContents->Find(m_currentFindRequestId, toString16(findText), std::move(options));
+ m_webContents->Find(m_currentFindRequestId, toString16(findText), std::move(options), /*skip_delay=*/true);
}
void FindTextHelper::stopFinding()
diff --git a/src/core/find_text_helper.h b/src/core/find_text_helper.h
index f795731e3..6d2e48b63 100644
--- a/src/core/find_text_helper.h
+++ b/src/core/find_text_helper.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -73,7 +37,7 @@ namespace QtWebEngineCore {
class WebContentsAdapterClient;
-class Q_WEBENGINECORE_PRIVATE_EXPORT FindTextHelper {
+class Q_WEBENGINECORE_EXPORT FindTextHelper {
public:
FindTextHelper(content::WebContents *webContents, WebContentsAdapterClient *viewClient);
~FindTextHelper();
diff --git a/src/core/global_descriptors_qt.h b/src/core/global_descriptors_qt.h
index b9d622606..f9b08f1d6 100644
--- a/src/core/global_descriptors_qt.h
+++ b/src/core/global_descriptors_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GLOBAL_DESCRIPTORS_QT_H
#define GLOBAL_DESCRIPTORS_QT_H
diff --git a/src/core/javascript_dialog_controller.cpp b/src/core/javascript_dialog_controller.cpp
index 86f5b9795..c8a6a58bf 100644
--- a/src/core/javascript_dialog_controller.cpp
+++ b/src/core/javascript_dialog_controller.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "javascript_dialog_controller.h"
#include "javascript_dialog_controller_p.h"
@@ -45,7 +9,7 @@
namespace QtWebEngineCore {
-void JavaScriptDialogControllerPrivate::dialogFinished(bool accepted, const base::string16 &promptValue)
+void JavaScriptDialogControllerPrivate::dialogFinished(bool accepted, const std::u16string &promptValue)
{
// Clear the queue first as this could result in the engine asking us to run another dialog,
// but hold a shared pointer so the dialog does not get deleted prematurely when running in-process.
diff --git a/src/core/javascript_dialog_controller.h b/src/core/javascript_dialog_controller.h
index ba9f51944..6c1ee269f 100644
--- a/src/core/javascript_dialog_controller.h
+++ b/src/core/javascript_dialog_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -59,7 +23,7 @@ namespace QtWebEngineCore {
class JavaScriptDialogControllerPrivate;
-class Q_WEBENGINECORE_PRIVATE_EXPORT JavaScriptDialogController : public QObject {
+class Q_WEBENGINECORE_EXPORT JavaScriptDialogController : public QObject {
Q_OBJECT
public:
~JavaScriptDialogController();
diff --git a/src/core/javascript_dialog_controller_p.h b/src/core/javascript_dialog_controller_p.h
index ab7b09268..af064250b 100644
--- a/src/core/javascript_dialog_controller_p.h
+++ b/src/core/javascript_dialog_controller_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef JAVASCRIPT_DIALOG_CONTROLLER_P_H
#define JAVASCRIPT_DIALOG_CONTROLLER_P_H
@@ -51,12 +15,13 @@
// We mean it.
//
-#include "base/callback.h"
+#include "base/functional/callback.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "web_contents_adapter_client.h"
#include <QString>
+#include <QUrl>
namespace content {
class WebContents;
@@ -67,7 +32,7 @@ namespace QtWebEngineCore {
class JavaScriptDialogControllerPrivate {
public:
- void dialogFinished(bool accepted, const base::string16 &promptValue);
+ void dialogFinished(bool accepted, const std::u16string &promptValue);
JavaScriptDialogControllerPrivate(WebContentsAdapterClient::JavascriptDialogType, const QString &message, const QString &prompt
, const QString& title, const QUrl &securityOrigin
, content::JavaScriptDialogManager::DialogClosedCallback &&, content::WebContents *);
diff --git a/src/core/javascript_dialog_manager_qt.cpp b/src/core/javascript_dialog_manager_qt.cpp
index 289947237..c5ee357ad 100644
--- a/src/core/javascript_dialog_manager_qt.cpp
+++ b/src/core/javascript_dialog_manager_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "javascript_dialog_manager_qt.h"
@@ -63,8 +27,8 @@ JavaScriptDialogManagerQt *JavaScriptDialogManagerQt::GetInstance()
void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webContents,
content::RenderFrameHost *renderFrameHost,
content::JavaScriptDialogType dialog_type,
- const base::string16 &messageText,
- const base::string16 &defaultPromptText,
+ const std::u16string &messageText,
+ const std::u16string &defaultPromptText,
content::JavaScriptDialogManager::DialogClosedCallback callback,
bool *didSuppressMessage)
{
@@ -87,12 +51,12 @@ void JavaScriptDialogManagerQt::RunBeforeUnloadDialog(content::WebContents *webC
runDialogForContents(webContents, WebContentsAdapterClient::UnloadDialog, QString(), QString(), toQt(originUrl), std::move(callback));
}
-bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *contents, bool accept, const base::string16 *promptOverride)
+bool JavaScriptDialogManagerQt::HandleJavaScriptDialog(content::WebContents *contents, bool accept, const std::u16string *promptOverride)
{
QSharedPointer<JavaScriptDialogController> dialog = m_activeDialogs.value(contents);
if (!dialog)
return false;
- dialog->d->dialogFinished(accept, promptOverride ? *promptOverride : base::string16());
+ dialog->d->dialogFinished(accept, promptOverride ? *promptOverride : std::u16string());
takeDialogForContents(contents);
return true;
}
diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h
index ca7432a77..2a587afc7 100644
--- a/src/core/javascript_dialog_manager_qt.h
+++ b/src/core/javascript_dialog_manager_qt.h
@@ -1,45 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef JAVASCRIPT_DIALOG_MANAGER_QT_H
#define JAVASCRIPT_DIALOG_MANAGER_QT_H
-#include "base/callback.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "web_contents_adapter_client.h"
@@ -61,14 +24,14 @@ public:
static JavaScriptDialogManagerQt *GetInstance();
void RunJavaScriptDialog(content::WebContents *, content::RenderFrameHost *, content::JavaScriptDialogType dialog_type,
- const base::string16 &messageText, const base::string16 &defaultPromptText,
+ const std::u16string &messageText, const std::u16string &defaultPromptText,
DialogClosedCallback callback,
bool *didSuppressMessage) override;
void RunBeforeUnloadDialog(content::WebContents *web_contents,
content::RenderFrameHost *render_frame_host,
bool is_reload,
DialogClosedCallback callback) override;
- bool HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) override;
+ bool HandleJavaScriptDialog(content::WebContents *, bool accept, const std::u16string *promptOverride) override;
void CancelDialogs(content::WebContents *contents, bool /*reset_state*/) override
{
takeDialogForContents(contents);
diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp
index b5d0f21f2..dc0d80aa7 100644
--- a/src/core/location_provider_qt.cpp
+++ b/src/core/location_provider_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "location_provider_qt.h"
@@ -48,12 +12,18 @@
#include <QtCore/QThread>
#include <QtPositioning/QGeoPositionInfoSource>
-#include "base/bind.h"
+#if QT_CONFIG(permissions)
+#include <QtCore/qpermissions.h>
+#endif
+
+#include "base/functional/bind.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_thread.h"
#include "services/device/geolocation/geolocation_provider.h"
#include "services/device/geolocation/geolocation_provider_impl.h"
+#include "services/device/public/mojom/geoposition.mojom.h"
+
namespace QtWebEngineCore {
using content::BrowserThread;
@@ -73,11 +43,12 @@ private Q_SLOTS:
void error(QGeoPositionInfoSource::Error positioningError);
private:
+ void startImpl(bool highAccuracy);
LocationProviderQt *m_locationProvider;
QGeoPositionInfoSource *m_positionInfoSource;
base::WeakPtrFactory<LocationProviderQt> m_locationProviderFactory;
- void postToLocationProvider(const base::Closure &task);
+ void postToLocationProvider(base::OnceClosure task);
friend class LocationProviderQt;
};
@@ -102,6 +73,38 @@ static bool isHighAccuracySource(const QGeoPositionInfoSource *source)
void QtPositioningHelper::start(bool highAccuracy)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // New Qt permissions API from 6.5.0
+#if QT_CONFIG(permissions)
+ QLocationPermission locationPermission;
+ locationPermission.setAvailability(QLocationPermission::WhenInUse);
+
+ QLocationPermission::Accuracy accuracy = highAccuracy ? QLocationPermission::Precise
+ : QLocationPermission::Approximate;
+ locationPermission.setAccuracy(accuracy);
+
+ switch (qApp->checkPermission(locationPermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(locationPermission, this,
+ [this, &highAccuracy](const QPermission &permission) {
+ if (permission.status() == Qt::PermissionStatus::Granted)
+ this->startImpl(highAccuracy);
+ });
+
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Failed to initialize location provider: The user does not have the right "
+ "permissions or has denied the permission request.");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break; // Proceed
+ }
+#endif
+ startImpl(highAccuracy);
+}
+
+void QtPositioningHelper::startImpl(bool highAccuracy){
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!m_positionInfoSource)
m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(this);
if (!m_positionInfoSource) {
@@ -160,64 +163,64 @@ void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos)
if (!pos.isValid())
return;
Q_ASSERT(m_positionInfoSource->error() == QGeoPositionInfoSource::NoError);
- device::mojom::Geoposition newPos;
- newPos.error_code = device::mojom::Geoposition::ErrorCode::NONE;
- newPos.error_message.clear();
+ auto newPos = device::mojom::Geoposition::New();
- newPos.timestamp = toTime(pos.timestamp());
- newPos.latitude = pos.coordinate().latitude();
- newPos.longitude = pos.coordinate().longitude();
+ newPos->timestamp = toTime(pos.timestamp());
+ newPos->latitude = pos.coordinate().latitude();
+ newPos->longitude = pos.coordinate().longitude();
const double altitude = pos.coordinate().altitude();
if (!qIsNaN(altitude))
- newPos.altitude = altitude;
+ newPos->altitude = altitude;
// Chromium's geoposition needs a valid (as in >=0.) accuracy field.
// try and get an accuracy estimate from QGeoPositionInfo.
// If we don't have any accuracy info, 100m seems a pesimistic enough default.
if (!pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) && !pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy))
- newPos.accuracy = 100;
+ newPos->accuracy = 100;
else {
const double vAccuracy = pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) ? pos.attribute(QGeoPositionInfo::VerticalAccuracy) : 0;
const double hAccuracy = pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) ? pos.attribute(QGeoPositionInfo::HorizontalAccuracy) : 0;
- newPos.accuracy = sqrt(vAccuracy * vAccuracy + hAccuracy * hAccuracy);
+ newPos->accuracy = sqrt(vAccuracy * vAccuracy + hAccuracy * hAccuracy);
}
// And now the "nice to have" fields (-1 means invalid).
- newPos.speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1;
- newPos.heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1;
+ newPos->speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1;
+ newPos->heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1;
+ auto newResult = device::mojom::GeopositionResult::NewPosition(std::move(newPos));
if (m_locationProvider)
- postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos));
+ postToLocationProvider(base::BindOnce(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), std::move(newResult)));
}
void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError)
{
Q_ASSERT(positioningError != QGeoPositionInfoSource::NoError);
- device::mojom::Geoposition newPos;
+ auto newError = device::mojom::GeopositionError::New();
switch (positioningError) {
case QGeoPositionInfoSource::AccessError:
- newPos.error_code = device::mojom::Geoposition::ErrorCode::PERMISSION_DENIED;
+ newError->error_code = device::mojom::GeopositionErrorCode::kPermissionDenied;
break;
case QGeoPositionInfoSource::UpdateTimeoutError:
// content::Geoposition::ERROR_CODE_TIMEOUT is not handled properly in the renderer process, and the timeout
// argument used in JS never comes all the way to the browser process.
// Let's just treat it like any other error where the position is unavailable.
- newPos.error_code = device::mojom::Geoposition::ErrorCode::POSITION_UNAVAILABLE;
+ newError->error_code = device::mojom::GeopositionErrorCode::kPositionUnavailable;
break;
case QGeoPositionInfoSource::ClosedError:
case QGeoPositionInfoSource::UnknownSourceError: // position unavailable is as good as it gets in Geoposition
default:
- newPos.error_code = device::mojom::Geoposition::ErrorCode::POSITION_UNAVAILABLE;
+ newError->error_code = device::mojom::GeopositionErrorCode::kPositionUnavailable;
break;
}
+ auto newResult = device::mojom::GeopositionResult::NewError(std::move(newError));
if (m_locationProvider)
- postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos));
+ postToLocationProvider(base::BindOnce(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), std::move(newResult)));
}
-inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task)
+inline void QtPositioningHelper::postToLocationProvider(base::OnceClosure task)
{
- static_cast<device::GeolocationProviderImpl*>(device::GeolocationProvider::GetInstance())->task_runner()->PostTask(FROM_HERE, task);
+ static_cast<device::GeolocationProviderImpl*>(device::GeolocationProvider::GetInstance())->task_runner()->PostTask(FROM_HERE, std::move(task));
}
LocationProviderQt::LocationProviderQt()
@@ -262,10 +265,10 @@ void LocationProviderQt::SetUpdateCallback(const LocationProviderUpdateCallback&
m_callback = callback;
}
-void LocationProviderQt::updatePosition(const device::mojom::Geoposition &position)
+void LocationProviderQt::updatePosition(device::mojom::GeopositionResultPtr position)
{
- m_lastKnownPosition = position;
- m_callback.Run(this, position);
+ m_lastKnownPosition = std::move(position);
+ m_callback.Run(this, m_lastKnownPosition.Clone());
}
} // namespace QtWebEngineCore
diff --git a/src/core/location_provider_qt.h b/src/core/location_provider_qt.h
index db6b94e20..93e409d77 100644
--- a/src/core/location_provider_qt.h
+++ b/src/core/location_provider_qt.h
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef LOCATION_PROVIDER_QT_H
#define LOCATION_PROVIDER_QT_H
-#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtconfigmacros.h>
#include "services/device/public/cpp/geolocation/geoposition.h"
#include "services/device/public/cpp/geolocation/location_provider.h"
@@ -59,16 +23,17 @@ public:
// LocationProvider
void StartProvider(bool high_accuracy) override;
void StopProvider() override;
- const device::mojom::Geoposition& GetPosition() override { return m_lastKnownPosition; }
+ const device::mojom::GeopositionResult* GetPosition() override { return m_lastKnownPosition.get(); }
void OnPermissionGranted() override;
- void SetUpdateCallback(const LocationProviderUpdateCallback& callback) override;
+ void SetUpdateCallback(const LocationProviderUpdateCallback &callback) override;
+ void FillDiagnostics(device::mojom::GeolocationDiagnostics &) override {}
private:
friend class QtPositioningHelper;
- void updatePosition(const device::mojom::Geoposition &);
+ void updatePosition(device::mojom::GeopositionResultPtr);
- device::mojom::Geoposition m_lastKnownPosition;
+ device::mojom::GeopositionResultPtr m_lastKnownPosition;
LocationProviderUpdateCallback m_callback;
QtPositioningHelper *m_positioningHelper;
};
diff --git a/src/core/login_delegate_qt.cpp b/src/core/login_delegate_qt.cpp
index 7942c8279..3f916b797 100644
--- a/src/core/login_delegate_qt.cpp
+++ b/src/core/login_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -43,28 +7,15 @@
#include "login_delegate_qt.h"
-#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
-#include "extensions/buildflags/buildflags.h"
-#include "services/network/public/cpp/features.h"
-
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-#include "extensions/browser/info_map.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/manifest_handlers/mime_types_handler.h"
-#endif // BUILDFLAG(ENABLE_EXTENSIONS)
-
#include "net/url_request/url_request.h"
+#include "services/network/public/cpp/features.h"
#include "authentication_dialog_controller.h"
#include "authentication_dialog_controller_p.h"
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-#include "extensions/extension_system_qt.h"
-#endif // BUILDFLAG(ENABLE_EXTENSIONS)
-#include "resource_context_qt.h"
#include "type_conversion.h"
#include "web_contents_view_qt.h"
#include "web_engine_context.h"
@@ -82,8 +33,7 @@ LoginDelegateQt::LoginDelegateQt(const net::AuthChallengeInfo &authInfo,
, m_auth_required_callback(std::move(auth_required_callback))
, m_weakFactory(this)
{
- base::PostTask(
- FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&LoginDelegateQt::triggerDialog, m_weakFactory.GetWeakPtr()));
}
@@ -145,7 +95,7 @@ void LoginDelegateQt::sendAuthToRequester(bool success, const QString &user, con
if (success && web_contents())
std::move(m_auth_required_callback).Run(net::AuthCredentials(toString16(user), toString16(password)));
else
- std::move(m_auth_required_callback).Run(base::nullopt);
+ std::move(m_auth_required_callback).Run(absl::nullopt);
}
}
diff --git a/src/core/login_delegate_qt.h b/src/core/login_delegate_qt.h
index 7b8d869e1..b1bae0c0b 100644
--- a/src/core/login_delegate_qt.h
+++ b/src/core/login_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef LOGIN_DELEGATE_QT_H
#define LOGIN_DELEGATE_QT_H
diff --git a/src/core/macos_context_type_helper.h b/src/core/macos_context_type_helper.h
deleted file mode 100644
index a7b989bc3..000000000
--- a/src/core/macos_context_type_helper.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef MACOS_CONTEXT_TYPE_HELPER_H_
-#define MACOS_CONTEXT_TYPE_HELPER_H_
-bool isCurrentContextSoftware();
-void* cglContext(NSOpenGLContext*);
-#endif // MACOS_CONTEXT_TYPE_HELPER_H_
diff --git a/src/core/macos_context_type_helper.mm b/src/core/macos_context_type_helper.mm
deleted file mode 100644
index 4c9302482..000000000
--- a/src/core/macos_context_type_helper.mm
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#import <Foundation/Foundation.h>
-#import <AppKit/AppKit.h>
-
-#include "macos_context_type_helper.h"
-
-bool isCurrentContextSoftware()
-{
- int rendererID = 0;
- [NSOpenGLContext.currentContext getValues:&rendererID forParameter:NSOpenGLContextParameterCurrentRendererID];
- return (rendererID & kCGLRendererIDMatchingMask) == kCGLRendererGenericFloatID;
-}
-
-void* cglContext(NSOpenGLContext *nsOpenGLContext)
-{
- return [nsOpenGLContext CGLContextObj];
-}
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index c9256f8ac..6dc45c442 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -43,14 +7,14 @@
#include "media_capture_devices_dispatcher.h"
-#include "javascript_dialog_manager_qt.h"
#include "type_conversion.h"
#include "web_contents_delegate_qt.h"
#include "web_contents_view_qt.h"
#include "web_engine_settings.h"
-#include "base/strings/utf_string_conversions.h"
+#include "base/strings/strcat.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/desktop_streams_registry.h"
@@ -59,15 +23,14 @@
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_manager_base.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
-#include "ui/base/l10n/l10n_util.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#if QT_CONFIG(webengine_webrtc)
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#endif
-#include <QtCore/qcoreapplication.h>
-
#if defined(WEBRTC_USE_X11)
#include <dlfcn.h>
#include <X11/extensions/Xrandr.h>
@@ -90,117 +53,172 @@ const blink::MediaStreamDevice *findDeviceWithId(const blink::MediaStreamDevices
return &(*iter);
}
}
- return 0;
+ return nullptr;
}
// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
-void getDevicesForDesktopCapture(blink::MediaStreamDevices *devices,
- content::DesktopMediaID mediaId,
- bool captureAudio,
- MediaStreamType videoType,
- MediaStreamType audioType)
+media::mojom::CaptureHandlePtr CreateCaptureHandle(content::WebContents *capturer,
+ const url::Origin &capturer_origin,
+ const content::DesktopMediaID &captured_id)
{
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (capturer_origin.opaque())
+ return nullptr;
+
+ content::RenderFrameHost *const captured_rfh =
+ content::RenderFrameHost::FromID(
+ captured_id.web_contents_id.render_process_id,
+ captured_id.web_contents_id.main_render_frame_id);
+ if (!captured_rfh || !captured_rfh->IsActive())
+ return nullptr;
+
+ content::WebContents *const captured = content::WebContents::FromRenderFrameHost(captured_rfh);
+ if (!captured)
+ return nullptr;
+
+ const auto &captured_config = captured->GetCaptureHandleConfig();
+ if (!captured_config.all_origins_permitted &&
+ std::none_of(captured_config.permitted_origins.begin(),
+ captured_config.permitted_origins.end(),
+ [capturer_origin](const url::Origin& permitted_origin) {
+ return capturer_origin.IsSameOriginWith(permitted_origin);
+ }))
+ {
+ return nullptr;
+ }
- // Add selected desktop source to the list.
- devices->push_back(blink::MediaStreamDevice(videoType, mediaId.ToString(), mediaId.ToString()));
- if (captureAudio) {
- if (mediaId.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
- devices->push_back(
- blink::MediaStreamDevice(audioType, mediaId.ToString(), "Tab audio"));
- } else {
- // Use the special loopback device ID for system audio capture.
- devices->push_back(blink::MediaStreamDevice(
- audioType,
- media::AudioDeviceDescription::kLoopbackInputDeviceId,
- "System Audio"));
+ // Observing CaptureHandle when either the capturing or the captured party
+ // is incognito is disallowed, except for self-capture.
+ if (capturer->GetPrimaryMainFrame() != captured->GetPrimaryMainFrame()) {
+ if (capturer->GetBrowserContext()->IsOffTheRecord() ||
+ captured->GetBrowserContext()->IsOffTheRecord()) {
+ return nullptr;
}
}
+
+ if (!captured_config.expose_origin && captured_config.capture_handle.empty())
+ return nullptr;
+
+ auto result = media::mojom::CaptureHandle::New();
+ if (captured_config.expose_origin)
+ result->origin = captured->GetPrimaryMainFrame()->GetLastCommittedOrigin();
+
+ result->capture_handle = captured_config.capture_handle;
+
+ return result;
}
-content::DesktopMediaID getDefaultScreenId()
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+media::mojom::DisplayMediaInformationPtr DesktopMediaIDToDisplayMediaInformation(content::WebContents *capturer,
+ const url::Origin &capturer_origin,
+ const content::DesktopMediaID &media_id)
{
-#if QT_CONFIG(webengine_webrtc)
- // Source id patterns are different across platforms.
- // On Linux and macOS, the source ids are randomish numbers assigned by the OS.
- // On Windows, the screens are enumerated consecutively in increasing order from 0.
-
- // In order to provide a correct screen id, we query for the available screen ids, and
- // select the first one as the main display id.
-#if !defined(WEBRTC_USE_X11)
- // The code is based on the file
- // chrome/browser/media/webrtc/native_desktop_media_list.cc.
- webrtc::DesktopCaptureOptions options =
- webrtc::DesktopCaptureOptions::CreateDefault();
- options.set_disable_effects(false);
- std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
- webrtc::DesktopCapturer::CreateScreenCapturer(options));
-
- if (screen_capturer) {
- webrtc::DesktopCapturer::SourceList screens;
- if (screen_capturer->GetSourceList(&screens)) {
- if (screens.size() > 0) {
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, screens[0].id);
- }
- }
- }
+ media::mojom::DisplayCaptureSurfaceType display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
+ bool logical_surface = true;
+ media::mojom::CursorCaptureType cursor = media::mojom::CursorCaptureType::NEVER;
+#if defined(USE_AURA)
+ const bool uses_aura = (media_id.window_id != content::DesktopMediaID::kNullId ? true : false);
#else
- // This is a workaround to avoid thread issues with DesktopCapturer [1]. Unfortunately,
- // creating a DesktopCapturer is not thread safe on X11 due to the use of webrtc::XErrorTrap.
- // Can be removed if https://crbug.com/2022 and/or https://crbug.com/570852 are fixed.
- // The code is based on the file
- // third_party/webrtc/modules/desktop_capture/linux/screen_capturer_x11.cc.
- //
- // [1]: webrtc::InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread
- Display *display = XOpenDisplay(nullptr);
- if (!display) {
- qWarning("Unable to open display.");
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ const bool uses_aura = false;
+#endif // defined(USE_AURA)
+
+ media::mojom::CaptureHandlePtr capture_handle;
+ switch (media_id.type) {
+ case content::DesktopMediaID::TYPE_SCREEN:
+ display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
+ cursor = uses_aura ? media::mojom::CursorCaptureType::MOTION
+ : media::mojom::CursorCaptureType::ALWAYS;
+ break;
+ case content::DesktopMediaID::TYPE_WINDOW:
+ display_surface = media::mojom::DisplayCaptureSurfaceType::WINDOW;
+ cursor = uses_aura ? media::mojom::CursorCaptureType::MOTION
+ : media::mojom::CursorCaptureType::ALWAYS;
+ break;
+ case content::DesktopMediaID::TYPE_WEB_CONTENTS:
+ display_surface = media::mojom::DisplayCaptureSurfaceType::BROWSER;
+ cursor = media::mojom::CursorCaptureType::MOTION;
+ capture_handle = CreateCaptureHandle(capturer, capturer_origin, media_id);
+ break;
+ case content::DesktopMediaID::TYPE_NONE:
+ break;
}
- int randrEventBase = 0;
- int errorBaseIgnored = 0;
- if (!XRRQueryExtension(display, &randrEventBase, &errorBaseIgnored)) {
- qWarning("X server does not support XRandR.");
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
- }
+ return media::mojom::DisplayMediaInformation::New(display_surface, logical_surface, cursor, std::move(capture_handle));
+}
- int majorVersion = 0;
- int minorVersion = 0;
- if (!XRRQueryVersion(display, &majorVersion, &minorVersion)) {
- qWarning("X server does not support XRandR.");
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
- }
- if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 5)) {
- qWarning("XRandR entension is older than v1.5.");
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+std::string DeviceNamePrefix(content::WebContents *web_contents,
+ blink::mojom::MediaStreamType requested_stream_type,
+ const content::DesktopMediaID &media_id)
+{
+ if (!web_contents || requested_stream_type != blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB) {
+ return std::string();
}
- typedef XRRMonitorInfo *(*GetMonitorsFunc)(Display *, Window, Bool, int *);
- GetMonitorsFunc getMonitors = reinterpret_cast<GetMonitorsFunc>(dlsym(RTLD_DEFAULT, "XRRGetMonitors"));
- typedef void (*FreeMonitorsFunc)(XRRMonitorInfo*);
- FreeMonitorsFunc freeMonitors = reinterpret_cast<FreeMonitorsFunc>(dlsym(RTLD_DEFAULT, "XRRFreeMonitors"));
- if (!getMonitors && !freeMonitors) {
- qWarning("Unable to link XRandR monitor functions.");
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ // Note that all of these must still be checked, as the explicit-selection
+ // dialog for DISPLAY_VIDEO_CAPTURE_THIS_TAB could still return something
+ // other than the current tab - be it a screen, window, or another tab.
+ if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS &&
+ web_contents->GetPrimaryMainFrame()->GetProcess()->GetID() ==
+ media_id.web_contents_id.render_process_id &&
+ web_contents->GetPrimaryMainFrame()->GetRoutingID() ==
+ media_id.web_contents_id.main_render_frame_id) {
+ return "current-";
}
- Window rootWindow = RootWindow(display, DefaultScreen(display));
- if (rootWindow == BadValue) {
- qWarning("Unable to get the root window.");
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ return std::string();
+}
+
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+std::string DeviceName(content::WebContents *web_contents,
+ blink::mojom::MediaStreamType requested_stream_type,
+ const content::DesktopMediaID &media_id)
+{
+ const std::string prefix =
+ DeviceNamePrefix(web_contents, requested_stream_type, media_id);
+ if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
+ return base::StrCat({prefix, content::kWebContentsCaptureScheme,
+ base::UnguessableToken::Create().ToString()});
+ } else {
+ // TODO(crbug.com/1252682): MediaStreamTrack.label leaks internal state for
+ // screen/window
+ return base::StrCat({prefix, media_id.ToString()});
}
+}
+
+// Based on chrome/browser/media/webrtc/desktop_capture_devices_util.cc:
+void getDevicesForDesktopCapture(const content::MediaStreamRequest &request,
+ content::WebContents *web_contents,
+ content::DesktopMediaID mediaId,
+ bool captureAudio,
+ bool disableLocalEcho,
+ blink::mojom::StreamDevices &out_devices)
+{
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- int numMonitors = 0;
- XRRMonitorInfo *monitors = getMonitors(display, rootWindow, true, &numMonitors);
- auto cleanup = qScopeGuard([&] () { freeMonitors(monitors); });
- if (numMonitors > 0)
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, monitors[0].name);
-#endif // !defined(WEBRTC_USE_X11)
-#endif // QT_CONFIG(webengine_webrtc)
+ // Add selected desktop source to the list.
+ blink::MediaStreamDevice device(request.video_type, mediaId.ToString(),
+ DeviceName(web_contents, request.video_type, mediaId));
+ device.display_media_info = DesktopMediaIDToDisplayMediaInformation(
+ web_contents, url::Origin::Create(request.security_origin), mediaId);
+ out_devices.video_device = device;
+
+ if (captureAudio) {
+ DCHECK_NE(request.audio_type, blink::mojom::MediaStreamType::NO_SERVICE);
- return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0);
+ if (mediaId.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
+ content::WebContentsMediaCaptureId web_id = mediaId.web_contents_id;
+ web_id.disable_local_echo = disableLocalEcho;
+ out_devices.audio_device = blink::MediaStreamDevice(request.audio_type, web_id.ToString(), "Tab audio");
+ } else {
+ // Use the special loopback device ID for system audio capture.
+ out_devices.audio_device = blink::MediaStreamDevice(
+ request.audio_type, (disableLocalEcho
+ ? media::AudioDeviceDescription::kLoopbackWithMuteDeviceId
+ : media::AudioDeviceDescription::kLoopbackInputDeviceId),
+ "System Audio");
+ }
+ }
}
WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const content::MediaStreamRequest &request)
@@ -241,11 +259,12 @@ WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const co
class MediaStreamUIQt : public content::MediaStreamUI
{
public:
- MediaStreamUIQt(content::WebContents *webContents, const blink::MediaStreamDevices &devices)
+ MediaStreamUIQt(content::WebContents *webContents, const blink::mojom::StreamDevices &devices)
: m_delegate(static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->AsWeakPtr())
, m_devices(devices)
{
- DCHECK(!m_devices.empty());
+ DCHECK(m_devices.audio_device.has_value() ||
+ m_devices.video_device.has_value());
}
~MediaStreamUIQt() override
@@ -256,7 +275,7 @@ public:
}
private:
- gfx::NativeViewId OnStarted(base::OnceClosure stop, SourceCallback source,
+ gfx::NativeViewId OnStarted(base::RepeatingClosure stop, SourceCallback source,
const std::string& label,
std::vector<content::DesktopMediaID> screen_capture_ids,
StateChangeCallback state_change) override
@@ -278,21 +297,19 @@ private:
Q_UNUSED(label);
Q_UNUSED(media_id);
}
-
+ void OnDeviceStoppedForSourceChange(const std::string&, const content::DesktopMediaID&, const content::DesktopMediaID&) override
+ {}
base::WeakPtr<WebContentsDelegateQt> m_delegate;
- const blink::MediaStreamDevices m_devices;
+ const blink::mojom::StreamDevices m_devices;
bool m_started = false;
- base::OnceClosure m_onStop; // currently unused
-
- DISALLOW_COPY_AND_ASSIGN(MediaStreamUIQt);
+ base::RepeatingClosure m_onStop; // currently unused
};
-
} // namespace
-MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest(const content::MediaStreamRequest &request,
- const RepeatingMediaResponseCallback &callback)
- : request(request)
- , callback(callback)
+MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest(
+ const content::MediaStreamRequest &request, content::MediaResponseCallback callback,
+ content::DesktopMediaID id)
+ : request(request), callback(std::move(callback)), mediaId(id)
{
}
@@ -304,13 +321,13 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- blink::MediaStreamDevices devices;
+ blink::mojom::StreamDevicesSet deviceSet;
auto it = m_pendingRequests.find(webContents);
if (it == m_pendingRequests.end() || it->second.empty())
return;
RequestsQueue &queue(it->second);
- content::MediaStreamRequest &request = queue.front().request;
+ content::MediaStreamRequest &request = queue.front()->request;
const QUrl requestSecurityOrigin(toQt(request.security_origin));
bool securityOriginsMatch = (requestSecurityOrigin.host() == securityOrigin.host()
@@ -328,43 +345,48 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
bool desktopVideoRequested = finalFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture);
if (securityOriginsMatch) {
+ content::DesktopMediaID &id = queue.front()->mediaId;
+
if (microphoneRequested || webcamRequested) {
switch (request.request_type) {
case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY:
- getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices);
+ getDefaultDevices("", "", microphoneRequested, webcamRequested, deviceSet);
break;
case blink::MEDIA_DEVICE_ACCESS:
case blink::MEDIA_DEVICE_UPDATE:
case blink::MEDIA_GENERATE_STREAM:
+ case blink::MEDIA_GET_OPEN_DEVICE:
getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id,
- microphoneRequested, webcamRequested, &devices);
+ microphoneRequested, webcamRequested, deviceSet);
break;
}
- } else if (desktopVideoRequested) {
+ } else if (desktopVideoRequested && !id.is_null()) {
+ deviceSet.stream_devices.emplace_back(blink::mojom::StreamDevices::New());
bool captureAudio = desktopAudioRequested && m_loopbackAudioSupported;
- getDevicesForDesktopCapture(&devices, getDefaultScreenId(), captureAudio,
- request.video_type, request.audio_type);
+ blink::mojom::StreamDevices &stream_devices = *deviceSet.stream_devices[0];
+ getDevicesForDesktopCapture(request, webContents, id, captureAudio,
+ request.disable_local_echo, stream_devices);
}
}
- content::MediaResponseCallback callback = std::move(queue.front().callback);
+ content::MediaResponseCallback callback = std::move(queue.front()->callback);
queue.pop_front();
if (!queue.empty()) {
// Post a task to process next queued request. It has to be done
// asynchronously to make sure that calling infobar is not destroyed until
// after this function returns.
- base::PostTask(FROM_HERE, {BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest,
base::Unretained(this), webContents));
}
- if (devices.empty())
- std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE,
+ if (deviceSet.stream_devices.empty())
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::INVALID_STATE,
std::unique_ptr<content::MediaStreamUI>());
else
- std::move(callback).Run(devices, MediaStreamRequestResult::OK,
- std::make_unique<MediaStreamUIQt>(webContents, devices));
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::OK,
+ std::make_unique<MediaStreamUIQt>(webContents, *deviceSet.stream_devices[0]));
}
MediaCaptureDevicesDispatcher *MediaCaptureDevicesDispatcher::GetInstance()
@@ -375,7 +397,7 @@ MediaCaptureDevicesDispatcher *MediaCaptureDevicesDispatcher::GetInstance()
MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher()
: m_webContentsCollection(this)
{
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
// Currently loopback audio capture is supported only on Windows.
m_loopbackAudioSupported = true;
#endif
@@ -391,7 +413,9 @@ void MediaCaptureDevicesDispatcher::WebContentsDestroyed(content::WebContents *w
m_pendingRequests.erase(webContents);
}
-void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
+void MediaCaptureDevicesDispatcher::processMediaAccessRequest(
+ content::WebContents *webContents, const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback, content::DesktopMediaID id)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Ensure we are observing the deletion of |webContents|.
@@ -399,7 +423,7 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebConten
WebContentsAdapterClient::MediaRequestFlags flags = mediaRequestFlagsForRequest(request);
if (!flags) {
- std::move(callback).Run(blink::MediaStreamDevices(), MediaStreamRequestResult::NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(blink::mojom::StreamDevicesSet(), MediaStreamRequestResult::NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -410,8 +434,8 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebConten
const bool screenCaptureEnabled = adapterClient->webEngineSettings()->testAttribute(
QWebEngineSettings::ScreenCaptureEnabled);
const bool originIsSecure = network::IsUrlPotentiallyTrustworthy(request.security_origin);
- if (!screenCaptureEnabled || !originIsSecure) {
- std::move(callback).Run(blink::MediaStreamDevices(), MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ if (!screenCaptureEnabled || !originIsSecure || (id.is_null() && request.requested_video_device_id.empty())) {
+ std::move(callback).Run(blink::mojom::StreamDevicesSet(), MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -422,33 +446,31 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(content::WebConten
}
}
- enqueueMediaAccessRequest(webContents, request, std::move(callback));
+ enqueueMediaAccessRequest(webContents, request, std::move(callback), id);
// We might not require this approval for pepper requests.
adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), flags);
}
void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
{
- blink::MediaStreamDevices devices;
+ blink::mojom::StreamDevicesSet deviceSet;
content::WebContents *const web_contents_for_stream = content::WebContents::FromRenderFrameHost(
content::RenderFrameHost::FromID(request.render_process_id, request.render_frame_id));
- content::RenderFrameHost *const main_frame = web_contents_for_stream ? web_contents_for_stream->GetMainFrame() : NULL;
+ content::RenderFrameHost *const main_frame = web_contents_for_stream ? web_contents_for_stream->GetPrimaryMainFrame() : nullptr;
content::DesktopMediaID mediaId;
if (main_frame) {
- // The extension name that the stream is registered with.
- std::string originalExtensionName;
// Resolve DesktopMediaID for the specified device id.
mediaId = content::DesktopStreamsRegistry::GetInstance()->RequestMediaForStreamId(
request.requested_video_device_id, main_frame->GetProcess()->GetID(),
main_frame->GetRoutingID(), url::Origin::Create(request.security_origin),
- &originalExtensionName, content::kRegistryStreamTypeDesktop);
+ content::kRegistryStreamTypeDesktop);
}
// Received invalid device id.
if (mediaId.type == content::DesktopMediaID::TYPE_NONE) {
- std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::INVALID_STATE, std::unique_ptr<content::MediaStreamUI>());
return;
}
@@ -458,24 +480,26 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
bool audioSupported = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && m_loopbackAudioSupported);
bool captureAudio = (audioRequested && audioSupported);
- getDevicesForDesktopCapture(&devices, mediaId, captureAudio, request.video_type, request.audio_type);
+ deviceSet.stream_devices.emplace_back(blink::mojom::StreamDevices::New());
+ blink::mojom::StreamDevices &stream_devices = *deviceSet.stream_devices[0];
+ getDevicesForDesktopCapture(request, webContents, mediaId, captureAudio, request.disable_local_echo, stream_devices);
- if (devices.empty())
- std::move(callback).Run(devices, MediaStreamRequestResult::INVALID_STATE,
+ if (deviceSet.stream_devices.empty())
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::INVALID_STATE,
std::unique_ptr<content::MediaStreamUI>());
else
- std::move(callback).Run(devices, MediaStreamRequestResult::OK,
- std::make_unique<MediaStreamUIQt>(webContents, devices));
+ std::move(callback).Run(deviceSet, MediaStreamRequestResult::OK,
+ std::make_unique<MediaStreamUIQt>(webContents, *deviceSet.stream_devices[0]));
}
-void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(content::WebContents *webContents,
- const content::MediaStreamRequest &request,
- content::MediaResponseCallback callback)
+void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(
+ content::WebContents *webContents, const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback, content::DesktopMediaID id)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RequestsQueue &queue = m_pendingRequests[webContents];
- queue.push_back(PendingAccessRequest(request, base::AdaptCallbackForRepeating(std::move(callback))));
+ queue.push_back(std::make_unique<PendingAccessRequest>(request, std::move(callback), id));
}
void MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest(content::WebContents *webContents)
@@ -487,25 +511,27 @@ void MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest(content::WebConte
return;
RequestsQueue &queue(it->second);
- content::MediaStreamRequest &request = queue.front().request;
+ content::MediaStreamRequest &request = queue.front()->request;
WebContentsAdapterClient *adapterClient = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents)->GetView())->client();
adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), mediaRequestFlagsForRequest(request));
}
void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId,
- bool audio, bool video, blink::MediaStreamDevices *devices)
+ bool audio, bool video, blink::mojom::StreamDevicesSet &devicesSet)
{
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(audio || video);
+ devicesSet.stream_devices.emplace_back(blink::mojom::StreamDevices::New());
+ blink::mojom::StreamDevices& devices = *devicesSet.stream_devices[0];
if (audio) {
const blink::MediaStreamDevices &audioDevices = content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices();
const blink::MediaStreamDevice *device = findDeviceWithId(audioDevices, audioDeviceId);
if (!device && !audioDevices.empty())
device = &audioDevices.front();
if (device)
- devices->push_back(*device);
+ devices.audio_device = *device;
}
if (video) {
@@ -514,14 +540,14 @@ void MediaCaptureDevicesDispatcher::getDefaultDevices(const std::string &audioDe
if (!device && !videoDevices.empty())
device = &videoDevices.front();
if (device)
- devices->push_back(*device);
+ devices.video_device = *device;
}
}
void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(int render_process_id, int render_frame_id, int page_request_id, const GURL &security_origin, blink::mojom::MediaStreamType stream_type, content::MediaRequestState state)
{
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- base::PostTask(FROM_HERE, {BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&MediaCaptureDevicesDispatcher::updateMediaRequestStateOnUIThread,
base::Unretained(this), render_process_id, render_frame_id,
page_request_id, security_origin, stream_type, state));
@@ -541,9 +567,9 @@ void MediaCaptureDevicesDispatcher::updateMediaRequestStateOnUIThread(int render
for (auto &pair : m_pendingRequests) {
RequestsQueue &queue = pair.second;
for (auto it = queue.begin(); it != queue.end(); ++it) {
- if (it->request.render_process_id == render_process_id
- && it->request.render_frame_id == render_frame_id
- && it->request.page_request_id == page_request_id) {
+ if ((*it)->request.render_process_id == render_process_id
+ && (*it)->request.render_frame_id == render_frame_id
+ && (*it)->request.page_request_id == page_request_id) {
queue.erase(it);
return;
}
diff --git a/src/core/media_capture_devices_dispatcher.h b/src/core/media_capture_devices_dispatcher.h
index d2633cb83..2b6bb98d8 100644
--- a/src/core/media_capture_devices_dispatcher.h
+++ b/src/core/media_capture_devices_dispatcher.h
@@ -1,59 +1,18 @@
-/****************************************************************************
-**
-** Copyright (c) 2012 The Chromium Authors. All rights reserved.
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef MEDIA_CAPTURE_DEVICES_DISPATCHER_H
#define MEDIA_CAPTURE_DEVICES_DISPATCHER_H
-#include <deque>
-#include <list>
-#include <map>
-
#include "web_contents_adapter_client.h"
-#include "base/callback.h"
#include "base/containers/circular_deque.h"
+#include "base/containers/flat_map.h"
#include "base/memory/singleton.h"
-#include "base/observer_list.h"
#include "chrome/browser/tab_contents/web_contents_collection.h"
#include "content/public/browser/media_observer.h"
-#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/browser/media_stream_request.h"
namespace QtWebEngineCore {
@@ -65,13 +24,14 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver,
public:
static MediaCaptureDevicesDispatcher *GetInstance();
- void processMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &, content::MediaResponseCallback);
+ void processMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &,
+ content::MediaResponseCallback, content::DesktopMediaID);
// Called back from our WebContentsAdapter to grant the requested permission.
void handleMediaAccessPermissionResponse(content::WebContents *, const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags);
private:
- void getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId, bool audio, bool video, blink::MediaStreamDevices *);
+ void getDefaultDevices(const std::string &audioDeviceId, const std::string &videoDeviceId, bool audio, bool video, blink::mojom::StreamDevicesSet &devices);
// Overridden from content::MediaObserver:
void OnAudioCaptureDevicesChanged() override {}
@@ -92,20 +52,17 @@ private:
friend struct base::DefaultSingletonTraits<MediaCaptureDevicesDispatcher>;
- typedef base::RepeatingCallback<void(const blink::MediaStreamDevices &devices,
- blink::mojom::MediaStreamRequestResult result,
- std::unique_ptr<content::MediaStreamUI> ui)>
- RepeatingMediaResponseCallback;
-
struct PendingAccessRequest {
- PendingAccessRequest(const content::MediaStreamRequest &request, const RepeatingMediaResponseCallback &callback);
+ PendingAccessRequest(const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback, content::DesktopMediaID id);
~PendingAccessRequest();
content::MediaStreamRequest request;
- RepeatingMediaResponseCallback callback;
+ content::MediaResponseCallback callback;
+ content::DesktopMediaID mediaId;
};
- typedef base::circular_deque<PendingAccessRequest> RequestsQueue;
- typedef std::map<content::WebContents *, RequestsQueue> RequestsQueues;
+ typedef base::circular_deque<std::unique_ptr<PendingAccessRequest>> RequestsQueue;
+ typedef base::flat_map<content::WebContents *, RequestsQueue> RequestsQueues;
MediaCaptureDevicesDispatcher();
virtual ~MediaCaptureDevicesDispatcher();
@@ -114,8 +71,10 @@ private:
void WebContentsDestroyed(content::WebContents *webContents) override;
// Helpers for ProcessMediaAccessRequest().
+ void handleRequest(content::WebContents *, const content::MediaStreamRequest &, content::MediaResponseCallback);
void processDesktopCaptureAccessRequest(content::WebContents *, const content::MediaStreamRequest &, content::MediaResponseCallback);
- void enqueueMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &, content::MediaResponseCallback);
+ void enqueueMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &,
+ content::MediaResponseCallback, content::DesktopMediaID);
void ProcessQueuedAccessRequest(content::WebContents *);
// Called by the MediaObserver() functions, executed on UI thread.
@@ -127,8 +86,6 @@ private:
WebContentsCollection m_webContentsCollection;
bool m_loopbackAudioSupported = false;
-
- DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher);
};
} // namespace QtWebEngineCore
diff --git a/src/core/native_web_keyboard_event_qt.cpp b/src/core/native_web_keyboard_event_qt.cpp
index c90b3c9e8..9a5576fbb 100644
--- a/src/core/native_web_keyboard_event_qt.cpp
+++ b/src/core/native_web_keyboard_event_qt.cpp
@@ -1,97 +1,77 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// 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.Chromium file.
-#include "content/public/browser/native_web_keyboard_event.h"
-#include <QKeyEvent>
+#include <QtCore/qglobal.h>
-namespace {
+#if !defined(Q_OS_MACOS)
+#include "native_web_keyboard_event_qt.h"
+
+#include <QtGui/QKeyEvent>
+
+namespace QtWebEngineCore {
+gfx::NativeEvent ToNativeEvent(QKeyEvent *keyEvent)
+{
+ return reinterpret_cast<gfx::NativeEvent>(keyEvent);
+}
+QKeyEvent *ToKeyEvent(gfx::NativeEvent nativeEvent)
+{
+ return reinterpret_cast<QKeyEvent *>(nativeEvent);
+}
+} // namespace QtWebEngineCore
+
+namespace {
// We need to copy |os_event| in NativeWebKeyboardEvent because it is
// queued in RenderWidgetHost and may be passed and used
// RenderViewHostDelegate::HandledKeybardEvent after the original aura
// event is destroyed.
-gfx::NativeEvent CopyEvent(gfx::NativeEvent event)
+gfx::NativeEvent CopyEvent(gfx::NativeEvent nativeEvent)
{
- if (!event)
+ if (!nativeEvent)
return nullptr;
- QKeyEvent *keyEvent = reinterpret_cast<QKeyEvent *>(event);
- return reinterpret_cast<gfx::NativeEvent>(keyEvent->clone());
+ QKeyEvent *keyEvent = QtWebEngineCore::ToKeyEvent(nativeEvent);
+ return QtWebEngineCore::ToNativeEvent(keyEvent->clone());
}
-void DestroyEvent(gfx::NativeEvent event)
+void DestroyEvent(gfx::NativeEvent nativeEvent)
{
- delete reinterpret_cast<QKeyEvent*>(event);
+ delete QtWebEngineCore::ToKeyEvent(nativeEvent);
}
+} // namespace
-} // namespace
-
-using blink::WebKeyboardEvent;
namespace content {
-NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebKeyboardEvent const&, gfx::NativeView)
- : os_event(0)
- , skip_in_browser(false)
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const blink::WebKeyboardEvent &web_event, gfx::NativeView)
+ : blink::WebKeyboardEvent(web_event)
+ , os_event(nullptr)
+ , skip_if_unhandled(false)
{
}
-NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type, int, base::TimeTicks)
- : os_event(0)
- , skip_in_browser(false)
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type, int modifiers,
+ base::TimeTicks timestamp)
+ : blink::WebKeyboardEvent(type, modifiers, timestamp)
+ , os_event(nullptr)
+ , skip_if_unhandled(false)
{
}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
- : os_event(CopyEvent(native_event)),
- skip_in_browser(false)
+ : os_event(CopyEvent(native_event))
+ , skip_if_unhandled(false)
{
}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& other)
- : WebKeyboardEvent(other),
- os_event(CopyEvent(other.os_event)),
- skip_in_browser(other.skip_in_browser)
+ : blink::WebKeyboardEvent(other)
+ , os_event(CopyEvent(other.os_event))
+ , skip_if_unhandled(other.skip_if_unhandled)
{
}
@@ -99,10 +79,10 @@ NativeWebKeyboardEvent &NativeWebKeyboardEvent::operator=(const NativeWebKeyboar
{
if (this == &other)
return *this;
- WebKeyboardEvent::operator=(other);
+ blink::WebKeyboardEvent::operator=(other);
DestroyEvent(os_event);
os_event = CopyEvent(other.os_event);
- skip_in_browser = other.skip_in_browser;
+ skip_if_unhandled = other.skip_if_unhandled;
return *this;
}
@@ -111,3 +91,4 @@ NativeWebKeyboardEvent::~NativeWebKeyboardEvent() {
}
} // namespace content
+#endif // !defined(Q_OS_MACOS)
diff --git a/src/core/native_web_keyboard_event_qt.h b/src/core/native_web_keyboard_event_qt.h
new file mode 100644
index 000000000..13179d07a
--- /dev/null
+++ b/src/core/native_web_keyboard_event_qt.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef NATIVE_WEB_KEYBOARD_EVENT_QT_H
+#define NATIVE_WEB_KEYBOARD_EVENT_QT_H
+
+#include <QtCore/qglobal.h>
+
+#include "content/public/common/input/native_web_keyboard_event.h"
+
+QT_FORWARD_DECLARE_CLASS(QKeyEvent)
+
+namespace QtWebEngineCore {
+
+gfx::NativeEvent ToNativeEvent(QKeyEvent *keyEvent);
+QKeyEvent *ToKeyEvent(gfx::NativeEvent event);
+
+} // namespace QtWebEngineCore
+
+#endif // NATIVE_WEB_KEYBOARD_EVENT_QT_H
diff --git a/src/core/native_web_keyboard_event_qt_mac.mm b/src/core/native_web_keyboard_event_qt_mac.mm
new file mode 100644
index 000000000..0f5b12db4
--- /dev/null
+++ b/src/core/native_web_keyboard_event_qt_mac.mm
@@ -0,0 +1,155 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// Copyright 2011 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE.Chromium file.
+
+// This is a workaround to be able to include Qt headers without
+// "redefinition of 'NSString' as different kind of symbol" errors.
+// TODO: Remove this when namespace ambiguity issues are fixed properly,
+// see get_forward_declaration_macro() in cmake/Functions.cmake
+#undef Q_FORWARD_DECLARE_OBJC_CLASS
+
+#include "native_web_keyboard_event_qt.h"
+
+#include <AppKit/AppKit.h>
+
+#include "base/apple/owned_objc.h"
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/private/qapplekeymapper_p.h>
+
+namespace QtWebEngineCore {
+
+base::apple::OwnedNSEvent ToNativeEvent(QKeyEvent *keyEvent)
+{
+ NSEventType type;
+ switch (keyEvent->type()) {
+ case QEvent::KeyPress:
+ type = NSEventTypeKeyDown;
+ break;
+ case QEvent::KeyRelease:
+ type = NSEventTypeKeyUp;
+ break;
+ default:
+ Q_UNREACHABLE();
+ return base::apple::OwnedNSEvent();
+ }
+
+ NSString *text = keyEvent->text().toNSString();
+ if (text.length == 0) {
+ Qt::Key key = static_cast<Qt::Key>(keyEvent->key());
+ QChar cocoaKey = QAppleKeyMapper::toCocoaKey(key);
+ text = QStringView(&cocoaKey, 1).toNSString();
+ }
+
+ return base::apple::OwnedNSEvent([NSEvent
+ keyEventWithType:type
+ location:NSZeroPoint
+ modifierFlags:QAppleKeyMapper::toCocoaModifiers(keyEvent->modifiers())
+ timestamp:keyEvent->timestamp() / 1000
+ windowNumber:0
+ context:nil
+ characters:text
+ charactersIgnoringModifiers:text
+ isARepeat:keyEvent->isAutoRepeat()
+ keyCode:keyEvent->nativeVirtualKey()
+ ]);
+}
+
+// Based on qtbase/src/plugins/platforms/cocoa/qnsview_keys.mm (KeyEvent::KeyEvent())
+QKeyEvent *ToKeyEvent(base::apple::OwnedNSEvent event)
+{
+ NSEvent *nsevent = event.Get();
+
+ QEvent::Type type = QEvent::None;
+ switch (nsevent.type) {
+ case NSEventTypeKeyDown:
+ type = QEvent::KeyPress;
+ break;
+ case NSEventTypeKeyUp:
+ type = QEvent::KeyRelease;
+ break;
+ default:
+ Q_UNREACHABLE();
+ return nullptr;
+ }
+
+ // Scan codes are hardware dependent codes for each key. There is no way to get these
+ // from Carbon or Cocoa, so leave it 0, as documented in QKeyEvent::nativeScanCode().
+ quint32 nativeScanCode = 0;
+ quint32 nativeVirtualKey = nsevent.keyCode;
+
+ NSEventModifierFlags nativeModifiers = nsevent.modifierFlags;
+ Qt::KeyboardModifiers modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers);
+
+ NSString *charactersIgnoringModifiers = nsevent.charactersIgnoringModifiers;
+ NSString *characters = nsevent.characters;
+
+ // If a dead key occurs as a result of pressing a key combination then
+ // characters will have 0 length, but charactersIgnoringModifiers will
+ // have a valid character in it. This enables key combinations such as
+ // ALT+E to be used as a shortcut with an English keyboard even though
+ // pressing ALT+E will give a dead key while doing normal text input.
+ Qt::Key key = Qt::Key_unknown;
+ if (characters.length || charactersIgnoringModifiers.length) {
+ QChar character = QChar::ReplacementCharacter;
+ if (nativeModifiers & (NSEventModifierFlagControl | NSEventModifierFlagOption)
+ && charactersIgnoringModifiers.length)
+ character = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ else if (characters.length)
+ character = QChar([characters characterAtIndex:0]);
+ key = QAppleKeyMapper::fromCocoaKey(character);
+ }
+
+ QString text = QString::fromNSString(characters);
+ bool autorep = nsevent.ARepeat;
+
+ return new QKeyEvent(type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
+ text, autorep);
+}
+
+} // namespace QtWebEngineCore
+
+namespace content {
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const blink::WebKeyboardEvent &web_event, gfx::NativeView)
+ : blink::WebKeyboardEvent(web_event)
+ , skip_if_unhandled(false)
+{
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type, int modifiers,
+ base::TimeTicks timestamp)
+ : blink::WebKeyboardEvent(type, modifiers, timestamp)
+ , skip_if_unhandled(false)
+{
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
+ : os_event(native_event) // FIXME: Copy?
+ , skip_if_unhandled(false)
+{
+}
+
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(const NativeWebKeyboardEvent& other)
+ : blink::WebKeyboardEvent(other)
+ , os_event(other.os_event) // FIXME: Copy?
+ , skip_if_unhandled(other.skip_if_unhandled)
+{
+}
+
+NativeWebKeyboardEvent &NativeWebKeyboardEvent::operator=(const NativeWebKeyboardEvent &other)
+{
+ blink::WebKeyboardEvent::operator=(other);
+
+ os_event = other.os_event; // FIXME: Copy?
+ skip_if_unhandled = other.skip_if_unhandled;
+
+ return *this;
+}
+
+NativeWebKeyboardEvent::~NativeWebKeyboardEvent() = default;
+
+} // namespace content
diff --git a/src/core/net/client_cert_override.cpp b/src/core/net/client_cert_override.cpp
deleted file mode 100644
index 4f7ae665f..000000000
--- a/src/core/net/client_cert_override.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "client_cert_override.h"
-
-#include "base/bind.h"
-#include "base/task/post_task.h"
-#include "base/callback_forward.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "net/ssl/client_cert_store.h"
-#include "net/ssl/ssl_cert_request_info.h"
-#include "net/ssl/ssl_private_key.h"
-#include "net/cert/x509_certificate.h"
-#include "third_party/boringssl/src/include/openssl/pem.h"
-#include "third_party/boringssl/src/include/openssl/err.h"
-#include "third_party/boringssl/src/include/openssl/evp.h"
-
-#include "client_cert_store_data.h"
-#include "profile_io_data_qt.h"
-
-#include <QtNetwork/qtnetworkglobal.h>
-
-#if defined(USE_NSS_CERTS)
-#include "net/ssl/client_cert_store_nss.h"
-#endif
-
-#if defined(OS_WIN)
-#include "net/ssl/client_cert_store_win.h"
-#endif
-
-#if defined(OS_MAC)
-#include "net/ssl/client_cert_store_mac.h"
-#endif
-
-namespace {
-
-class ClientCertIdentityOverride : public net::ClientCertIdentity
-{
-public:
- ClientCertIdentityOverride(scoped_refptr<net::X509Certificate> cert, scoped_refptr<net::SSLPrivateKey> key)
- : net::ClientCertIdentity(std::move(cert)), m_key(std::move(key)) {}
- ~ClientCertIdentityOverride() override = default;
-
- void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override
- {
- std::move(private_key_callback).Run(m_key);
- }
-
-#if defined(OS_MAC)
- SecIdentityRef sec_identity_ref() const override
- {
- return nullptr;
- }
-#endif
-
-private:
- scoped_refptr<net::SSLPrivateKey> m_key;
-};
-
-} // namespace
-
-namespace QtWebEngineCore {
-
-ClientCertOverrideStore::ClientCertOverrideStore(ClientCertificateStoreData *storeData)
- : ClientCertStore()
- , m_storeData(storeData)
- , m_nativeStore(createNativeStore())
-{
-}
-
-ClientCertOverrideStore::~ClientCertOverrideStore() = default;
-
-#if QT_CONFIG(ssl)
-net::ClientCertIdentityList ClientCertOverrideStore::GetClientCertsOnUIThread(const net::SSLCertRequestInfo &cert_request_info)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- const auto &clientCertOverrideData = m_storeData->extraCerts;
- // Look for certificates in memory store
- for (int i = 0; i < clientCertOverrideData.length(); i++) {
- scoped_refptr<net::X509Certificate> cert = clientCertOverrideData[i]->certPtr;
- if (cert != NULL && cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) {
- net::ClientCertIdentityList selected_identities;
- selected_identities.push_back(std::make_unique<ClientCertIdentityOverride>(cert, clientCertOverrideData[i]->keyPtr));
- return selected_identities;
- }
- }
- return net::ClientCertIdentityList();
-}
-
-void ClientCertOverrideStore::GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback,
- net::ClientCertIdentityList &&result)
-{
- // Continue with native cert store if matching certificatse were not found in memory
- if (result.empty() && m_nativeStore)
- m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
- else
- std::move(callback).Run(std::move(result));
-}
-
-#endif // QT_CONFIG(ssl)
-
-void ClientCertOverrideStore::GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback)
-{
-#if QT_CONFIG(ssl)
- // Access the user-provided data from the UI thread, but return on whatever thread this is.
- bool ok = base::PostTaskAndReplyWithResult(
- FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&ClientCertOverrideStore::GetClientCertsOnUIThread,
- base::Unretained(this), std::cref(cert_request_info)),
- base::BindOnce(&ClientCertOverrideStore::GetClientCertsReturn,
- base::Unretained(this), std::cref(cert_request_info), std::move(callback)));
- DCHECK(ok); // callback is already moved and we can't really recover here.
-#else
- if (m_nativeStore)
- m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
- else
- std::move(callback).Run(net::ClientCertIdentityList());
-#endif // QT_CONFIG(ssl)
-}
-
-// static
-std::unique_ptr<net::ClientCertStore> ClientCertOverrideStore::createNativeStore()
-{
-#if defined(USE_NSS_CERTS)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory()));
-#elif defined(OS_WIN)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
-#elif defined(OS_MAC)
- return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
-#else
- return nullptr;
-#endif
-}
-} // namespace QtWebEngineCore
diff --git a/src/core/net/client_cert_override.h b/src/core/net/client_cert_override.h
deleted file mode 100644
index 7fd28eaeb..000000000
--- a/src/core/net/client_cert_override.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef CLIENT_CERT_OVERRIDE_P_H
-#define CLIENT_CERT_OVERRIDE_P_H
-
-#include "net/ssl/client_cert_store.h"
-#include "base/callback_forward.h"
-#include "net/cert/x509_certificate.h"
-
-namespace net {
-class SSLCertRequestInfo;
-} // namespace net
-
-namespace QtWebEngineCore {
-struct ClientCertificateStoreData;
-
-class ClientCertOverrideStore : public net::ClientCertStore
-{
-public:
- ClientCertOverrideStore(ClientCertificateStoreData *storeData);
- virtual ~ClientCertOverrideStore() override;
- void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback) override;
-private:
- static std::unique_ptr<net::ClientCertStore> createNativeStore();
- net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
- void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
- ClientCertListCallback callback,
- net::ClientCertIdentityList &&result);
- ClientCertificateStoreData *m_storeData;
- std::unique_ptr<net::ClientCertStore> m_nativeStore;
-};
-
-} // QtWebEngineCore
-
-#endif
diff --git a/src/core/net/client_cert_qt.cpp b/src/core/net/client_cert_qt.cpp
new file mode 100644
index 000000000..044e5618e
--- /dev/null
+++ b/src/core/net/client_cert_qt.cpp
@@ -0,0 +1,148 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "client_cert_qt.h"
+
+#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "crypto/crypto_buildflags.h"
+#include "net/ssl/client_cert_store.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_private_key.h"
+#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/pem.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+#include "client_cert_store_data.h"
+
+#include <QtNetwork/qtnetworkglobal.h>
+
+#if BUILDFLAG(USE_NSS_CERTS)
+#include "net/ssl/client_cert_store_nss.h"
+#endif
+
+#if defined(Q_OS_WIN)
+#include "net/ssl/client_cert_store_win.h"
+#endif
+
+#if BUILDFLAG(IS_MAC)
+#include "net/ssl/client_cert_store_mac.h"
+#endif
+
+namespace {
+
+class ClientCertIdentityQt : public net::ClientCertIdentity
+{
+public:
+ ClientCertIdentityQt(scoped_refptr<net::X509Certificate> cert, scoped_refptr<net::SSLPrivateKey> key)
+ : net::ClientCertIdentity(std::move(cert)), m_key(std::move(key)) {}
+ ~ClientCertIdentityQt() override = default;
+
+ void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override
+ {
+ std::move(private_key_callback).Run(m_key);
+ }
+
+private:
+ scoped_refptr<net::SSLPrivateKey> m_key;
+};
+
+} // namespace
+
+namespace QtWebEngineCore {
+
+ClientCertStoreQt::ClientCertStoreQt(ClientCertificateStoreData *storeData)
+ : ClientCertStore()
+ , m_storeData(storeData)
+ , m_nativeStore(createNativeStore())
+{
+}
+
+ClientCertStoreQt::~ClientCertStoreQt() = default;
+
+#if QT_CONFIG(ssl)
+net::ClientCertIdentityList ClientCertStoreQt::GetClientCertsOnUIThread(const net::SSLCertRequestInfo &cert_request_info)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ const auto &clientCertOverrideData = m_storeData->extraCerts;
+
+ // Look for certificates in memory store
+ net::ClientCertIdentityList selected_identities;
+ for (int i = 0; i < clientCertOverrideData.length(); i++) {
+ scoped_refptr<net::X509Certificate> cert = clientCertOverrideData[i]->certPtr;
+ if (cert) {
+ if (cert->HasExpired()) {
+ qWarning() << "Expired certificate" << clientCertOverrideData[i];
+ continue;
+ }
+ if (cert_request_info.cert_authorities.empty()
+ || cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) {
+ selected_identities.push_back(std::make_unique<ClientCertIdentityQt>(
+ cert, clientCertOverrideData[i]->keyPtr));
+ }
+ }
+ }
+ return selected_identities;
+}
+
+void ClientCertStoreQt::GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback,
+ net::ClientCertIdentityList &&result)
+{
+ // Continue with native cert store and append them after memory certificates
+ if (m_nativeStore) {
+ ClientCertListCallback callback2 = base::BindOnce(
+ [](ClientCertStoreQt::ClientCertListCallback callback,
+ net::ClientCertIdentityList result1, net::ClientCertIdentityList result2) {
+ while (!result2.empty()) {
+ result1.push_back(std::move(result2.back()));
+ result2.pop_back();
+ }
+ std::move(callback).Run(std::move(result1));
+ },
+ std::move(callback), std::move(result));
+ m_nativeStore->GetClientCerts(cert_request_info, std::move(callback2));
+ } else {
+ std::move(callback).Run(std::move(result));
+ }
+}
+
+#endif // QT_CONFIG(ssl)
+
+void ClientCertStoreQt::GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback)
+{
+#if QT_CONFIG(ssl)
+ // Access the user-provided data from the UI thread, but return on whatever thread this is.
+ bool ok = content::GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
+ base::BindOnce(&ClientCertStoreQt::GetClientCertsOnUIThread,
+ base::Unretained(this), std::cref(cert_request_info)),
+ base::BindOnce(&ClientCertStoreQt::GetClientCertsReturn,
+ base::Unretained(this), std::cref(cert_request_info), std::move(callback)));
+ DCHECK(ok); // callback is already moved and we can't really recover here.
+#else
+ if (m_nativeStore)
+ m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
+ else
+ std::move(callback).Run(net::ClientCertIdentityList());
+#endif // QT_CONFIG(ssl)
+}
+
+// static
+std::unique_ptr<net::ClientCertStore> ClientCertStoreQt::createNativeStore()
+{
+#if BUILDFLAG(USE_NSS_CERTS)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory()));
+#elif defined(Q_OS_WIN)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
+#elif BUILDFLAG(IS_MAC)
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
+#else
+ return nullptr;
+#endif
+}
+} // namespace QtWebEngineCore
diff --git a/src/core/net/client_cert_qt.h b/src/core/net/client_cert_qt.h
new file mode 100644
index 000000000..96579fae6
--- /dev/null
+++ b/src/core/net/client_cert_qt.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CLIENT_CERT_QT_P_H
+#define CLIENT_CERT_QT_P_H
+
+#include "base/functional/callback_forward.h"
+#include "net/cert/x509_certificate.h"
+#include "net/ssl/client_cert_store.h"
+
+namespace net {
+class SSLCertRequestInfo;
+} // namespace net
+
+namespace QtWebEngineCore {
+struct ClientCertificateStoreData;
+
+class ClientCertStoreQt : public net::ClientCertStore
+{
+public:
+ ClientCertStoreQt(ClientCertificateStoreData *storeData);
+ virtual ~ClientCertStoreQt() override;
+ void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback) override;
+private:
+ static std::unique_ptr<net::ClientCertStore> createNativeStore();
+ net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
+ void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
+ ClientCertListCallback callback,
+ net::ClientCertIdentityList &&result);
+ ClientCertificateStoreData *m_storeData;
+ std::unique_ptr<net::ClientCertStore> m_nativeStore;
+};
+
+} // QtWebEngineCore
+
+#endif
diff --git a/src/core/net/client_cert_store_data.cpp b/src/core/net/client_cert_store_data.cpp
index 314e64145..0de6885df 100644
--- a/src/core/net/client_cert_store_data.cpp
+++ b/src/core/net/client_cert_store_data.cpp
@@ -1,48 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "net/client_cert_store_data.h"
#if QT_CONFIG(ssl)
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_platform_key_util.h"
@@ -59,16 +20,16 @@
namespace {
-class SSLPlatformKeyOverride : public net::ThreadedSSLPrivateKey::Delegate
+class SSLPlatformKeyQt : public net::ThreadedSSLPrivateKey::Delegate
{
public:
- SSLPlatformKeyOverride(const QByteArray &sslKeyInBytes)
+ SSLPlatformKeyQt(const QByteArray &sslKeyInBytes)
{
m_mem = BIO_new_mem_buf(sslKeyInBytes, -1);
m_key = PEM_read_bio_PrivateKey(m_mem, nullptr, nullptr, nullptr);
}
- ~SSLPlatformKeyOverride() override
+ ~SSLPlatformKeyQt() override
{
if (m_key)
EVP_PKEY_free(m_key);
@@ -104,8 +65,8 @@ public:
std::vector<uint16_t> GetAlgorithmPreferences() override
{
- return { SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA512
- , SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA256 };
+ return net::SSLPrivateKey::DefaultAlgorithmPreferences(EVP_PKEY_id(m_key),
+ /* supports pss */ true);
}
std::string GetProviderName() override {
return "qtwebengine";
@@ -113,8 +74,6 @@ public:
private:
EVP_PKEY *m_key;
BIO *m_mem;
-
- DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyOverride);
};
scoped_refptr<net::SSLPrivateKey> wrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes)
@@ -123,7 +82,7 @@ scoped_refptr<net::SSLPrivateKey> wrapOpenSSLPrivateKey(const QByteArray &sslKey
return nullptr;
return base::MakeRefCounted<net::ThreadedSSLPrivateKey>(
- std::make_unique<SSLPlatformKeyOverride>(sslKeyInBytes),
+ std::make_unique<SSLPlatformKeyQt>(sslKeyInBytes),
net::GetSSLPlatformKeyTaskRunner());
}
@@ -138,7 +97,8 @@ void ClientCertificateStoreData::add(const QSslCertificate &certificate, const Q
Entry *data = new Entry;
data->keyPtr = wrapOpenSSLPrivateKey(sslKeyInBytes);
- data->certPtr = net::X509Certificate::CreateFromBytes(certInBytes.data(), certInBytes.length());
+ data->certPtr = net::X509Certificate::CreateFromBytes(base::make_span((const unsigned char *)certInBytes.data(),
+ (unsigned long)certInBytes.length()));
data->key = privateKey;
data->certificate = certificate;
extraCerts.append(data);
diff --git a/src/core/net/client_cert_store_data.h b/src/core/net/client_cert_store_data.h
index 4976ac936..c2e28ac18 100644
--- a/src/core/net/client_cert_store_data.h
+++ b/src/core/net/client_cert_store_data.h
@@ -1,47 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CLIENT_CERT_STORE_DATA_H
#define CLIENT_CERT_STORE_DATA_H
-#include "qtwebenginecoreglobal.h"
-#include "qtnetworkglobal.h"
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtNetwork/qtnetworkglobal.h>
#if QT_CONFIG(ssl)
#include "base/memory/ref_counted.h"
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index 2fbacd73b..d107c520c 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -1,49 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "cookie_monster_delegate_qt.h"
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "base/task/post_task.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
+#include "base/functional/bind.h"
#include "net/cookies/cookie_util.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
@@ -51,6 +11,8 @@
#include "api/qwebenginecookiestore_p.h"
#include "type_conversion.h"
+#include <QNetworkCookie>
+
namespace QtWebEngineCore {
class CookieChangeListener : public network::mojom::CookieChangeListener
@@ -67,8 +29,6 @@ public:
private:
CookieMonsterDelegateQt *m_delegate;
-
- DISALLOW_COPY_AND_ASSIGN(CookieChangeListener);
};
class CookieAccessFilter : public network::mojom::CookieRemoteAccessFilter
@@ -85,8 +45,6 @@ public:
private:
CookieMonsterDelegateQt *m_delegate;
-
- DISALLOW_COPY_AND_ASSIGN(CookieAccessFilter);
};
@@ -139,8 +97,9 @@ void CookieMonsterDelegateQt::setCookie(const QNetworkCookie &cookie, const QUrl
std::string cookie_line = cookie.toRawForm().toStdString();
net::CookieInclusionStatus inclusion;
- auto canonCookie = net::CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(), base::nullopt, &inclusion);
- if (!inclusion.IsInclude()) {
+ auto canonCookie = net::CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(),
+ absl::nullopt, absl::nullopt, true, &inclusion);
+ if (!canonCookie || !inclusion.IsInclude()) {
LOG(WARNING) << "QWebEngineCookieStore::setCookie() - Tried to set invalid cookie";
return;
}
@@ -182,7 +141,7 @@ void CookieMonsterDelegateQt::deleteAllCookies()
m_mojoCookieManager->DeleteCookies(std::move(filter), network::mojom::CookieManager::DeleteCookiesCallback());
}
-void CookieMonsterDelegateQt::setMojoCookieManager(network::mojom::CookieManagerPtrInfo cookie_manager_info)
+void CookieMonsterDelegateQt::setMojoCookieManager(mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_info)
{
if (m_mojoCookieManager.is_bound())
unsetMojoCookieManager();
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index 4359119f9..f6872323d 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -60,7 +24,7 @@
#endif
#include "base/memory/ref_counted.h"
#include "mojo/public/cpp/bindings/receiver.h"
-#include "net/cookies/cookie_change_dispatcher.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "net/cookies/cookie_store.h"
#include "services/network/public/mojom/cookie_manager.mojom-forward.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
@@ -69,21 +33,21 @@
#undef StAsH_signals
#endif
-#include <QNetworkCookie>
#include <QPointer>
+QT_FORWARD_DECLARE_CLASS(QNetworkCookie)
QT_FORWARD_DECLARE_CLASS(QWebEngineCookieStore)
namespace QtWebEngineCore {
class CookieMonsterDelegateQtPrivate;
-class Q_WEBENGINECORE_PRIVATE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt>
+class Q_WEBENGINECORE_EXPORT CookieMonsterDelegateQt : public base::RefCountedThreadSafe<CookieMonsterDelegateQt>
{
QPointer<QWebEngineCookieStore> m_client;
std::vector<std::unique_ptr<net::CookieChangeSubscription>> m_subscriptions;
- network::mojom::CookieManagerPtr m_mojoCookieManager;
+ mojo::Remote<network::mojom::CookieManager> m_mojoCookieManager;
std::unique_ptr<network::mojom::CookieChangeListener> m_listener;
std::unique_ptr<network::mojom::CookieRemoteAccessFilter> m_filter;
mojo::Receiver<network::mojom::CookieChangeListener> m_receiver;
@@ -102,7 +66,7 @@ public:
void deleteAllCookies();
void setClient(QWebEngineCookieStore *client);
- void setMojoCookieManager(network::mojom::CookieManagerPtrInfo cookie_manager_info);
+ void setMojoCookieManager(mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_info);
void unsetMojoCookieManager();
void setHasFilter(bool b);
@@ -113,6 +77,6 @@ public:
void OnCookieChanged(const net::CookieChangeInfo &change);
};
-}
+} // namespace QtWebEngineCore
#endif // COOKIE_MONSTER_DELEGATE_QT_H
diff --git a/src/core/net/custom_url_loader_factory.cpp b/src/core/net/custom_url_loader_factory.cpp
index dca69c20f..4274def99 100644
--- a/src/core/net/custom_url_loader_factory.cpp
+++ b/src/core/net/custom_url_loader_factory.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "custom_url_loader_factory.h"
#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -51,9 +14,12 @@
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
+#include "url/url_util.h"
+#include "url/url_util_qt.h"
#include "api/qwebengineurlscheme.h"
#include "net/url_request_custom_job_proxy.h"
@@ -66,6 +32,7 @@
#include <QtCore/qiodevice.h>
#include <QtCore/qmimedatabase.h>
#include <QtCore/qmimedata.h>
+#include <QtCore/qpointer.h>
#include <QtCore/qurl.h>
namespace QtWebEngineCore {
@@ -77,13 +44,13 @@ class CustomURLLoader : public network::mojom::URLLoader
{
public:
static void CreateAndStart(const network::ResourceRequest &request,
- network::mojom::URLLoaderRequest loader,
- network::mojom::URLLoaderClientPtrInfo client_info,
+ mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
QPointer<ProfileAdapter> profileAdapter)
{
// CustomURLLoader will handle its own life-cycle, and delete when
// the client lets go.
- auto *customUrlLoader = new CustomURLLoader(request, std::move(loader), std::move(client_info), profileAdapter);
+ auto *customUrlLoader = new CustomURLLoader(request, std::move(loader), std::move(client_remote), profileAdapter);
customUrlLoader->Start();
}
@@ -91,13 +58,13 @@ public:
void FollowRedirect(const std::vector<std::string> &removed_headers,
const net::HttpRequestHeaders &modified_headers,
const net::HttpRequestHeaders &modified_cors_exempt_headers, // FIXME: do something with this?
- const base::Optional<GURL> &new_url) override
+ const absl::optional<GURL> &new_url) override
{
// We can be asked for follow our own redirect
scoped_refptr<URLRequestCustomJobProxy> proxy = new URLRequestCustomJobProxy(this, m_proxy->m_scheme, m_proxy->m_profileAdapter);
m_proxy->m_client = nullptr;
// m_taskRunner->PostTask(FROM_HERE, base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
- base::PostTask(FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
m_proxy = std::move(proxy);
if (new_url)
@@ -116,14 +83,14 @@ public:
private:
CustomURLLoader(const network::ResourceRequest &request,
- network::mojom::URLLoaderRequest loader,
- network::mojom::URLLoaderClientPtrInfo client_info,
+ mojo::PendingReceiver<network::mojom::URLLoader> loader,
+ mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote,
QPointer<ProfileAdapter> profileAdapter)
// ### We can opt to run the url-loader on the UI thread instead
- : m_taskRunner(base::CreateSingleThreadTaskRunner({ content::BrowserThread::IO }))
+ : m_taskRunner(content::GetIOThreadTaskRunner({}))
, m_proxy(new URLRequestCustomJobProxy(this, request.url.scheme(), profileAdapter))
, m_receiver(this, std::move(loader))
- , m_client(std::move(client_info))
+ , m_client(std::move(client_remote))
, m_request(request)
{
DCHECK(m_taskRunner->RunsTasksInCurrentSequence());
@@ -134,6 +101,7 @@ private:
m_error = 0;
QWebEngineUrlScheme scheme = QWebEngineUrlScheme::schemeByName(QByteArray::fromStdString(request.url.scheme()));
m_corsEnabled = scheme.flags().testFlag(QWebEngineUrlScheme::CorsEnabled);
+ m_isLocal = scheme.flags().testFlag(QWebEngineUrlScheme::LocalScheme);
}
~CustomURLLoader() override = default;
@@ -147,10 +115,21 @@ private:
if (!m_request.request_initiator)
return CompleteWithFailure(net::ERR_INVALID_ARGUMENT);
- // Custom schemes are not covered by CorsURLLoader, so we need to reject CORS requests manually.
- if (!m_corsEnabled && !m_request.request_initiator->IsSameOriginWith(url::Origin::Create(m_request.url)))
- return CompleteWithFailure(network::CorsErrorStatus(network::mojom::CorsError::kCorsDisabledScheme));
+ if (m_isLocal) {
+ std::string fromScheme = m_request.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
+ const std::vector<std::string> &localSchemes = url::GetLocalSchemes();
+ bool fromLocal = base::Contains(localSchemes, fromScheme);
+ bool hasLocalAccess = fromLocal;
+ if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(fromScheme))
+ hasLocalAccess = cs->flags & (url::CustomScheme::LocalAccessAllowed | url::CustomScheme::Local);
+ if (!hasLocalAccess)
+ return CompleteWithFailure(net::ERR_ACCESS_DENIED);
+ } else if (!m_corsEnabled && !m_request.request_initiator->IsSameOriginWith(url::Origin::Create(m_request.url))) {
+ // Custom schemes are not covered by CorsURLLoader, so we need to reject CORS requests manually.
+ return CompleteWithFailure(network::CorsErrorStatus(network::mojom::CorsError::kCorsDisabledScheme));
+ }
}
+
if (mojo::CreateDataPipe(nullptr, m_pipeProducerHandle, m_pipeConsumerHandle) != MOJO_RESULT_OK)
return CompleteWithFailure(net::ERR_FAILED);
@@ -172,9 +151,11 @@ private:
m_firstBytePosition = m_byteRange.first_byte_position();
// m_taskRunner->PostTask(FROM_HERE,
- base::PostTask(FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&URLRequestCustomJobProxy::initialize, m_proxy,
- m_request.url, m_request.method, m_request.request_initiator, std::move(headers)));
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&URLRequestCustomJobProxy::initialize, m_proxy, m_request.url,
+ m_request.method, m_request.request_initiator, std::move(headers),
+ m_request.request_body));
}
void CompleteWithFailure(network::CorsErrorStatus cors_error)
@@ -225,7 +206,7 @@ private:
m_device->close();
m_device = nullptr;
// m_taskRunner->PostTask(FROM_HERE, base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
- base::PostTask(FROM_HERE, { content::BrowserThread::UI },
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&URLRequestCustomJobProxy::release, m_proxy));
if (!wait_for_loader_error || !m_receiver.is_bound())
delete this;
@@ -284,11 +265,17 @@ private:
headers += "Access-Control-Allow-Credentials: true\n";
}
}
+ for (auto it = m_additionalResponseHeaders.cbegin();
+ it != m_additionalResponseHeaders.cend(); ++it) {
+ headers += it.key().toLower().toStdString() + ": " + it.value().toLower().toStdString()
+ + "\n";
+ }
m_head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(net::HttpUtil::AssembleRawHeaders(headers));
m_head->encoded_data_length = m_head->headers->raw_headers().length();
if (!m_redirect.is_empty()) {
- m_head->content_length = m_head->encoded_body_length = -1;
+ m_head->content_length = {};
+ m_head->encoded_body_length = {};
net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =
m_request.update_first_party_url_on_redirect ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT
: net::RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL;
@@ -297,7 +284,7 @@ private:
m_request.site_for_cookies,
first_party_url_policy, m_request.referrer_policy,
m_request.referrer.spec(), net::HTTP_SEE_OTHER,
- m_redirect, base::nullopt, false /*insecure_scheme_was_upgraded*/);
+ m_redirect, absl::nullopt, false /*insecure_scheme_was_upgraded*/);
m_client->OnReceiveRedirect(redirectInfo, std::move(m_head));
m_head = nullptr;
// ### should m_request be updated with RedirectInfo? (see FollowRedirect)
@@ -307,19 +294,17 @@ private:
m_head->mime_type = m_mimeType;
m_head->charset = m_charset;
m_headerBytesRead = m_head->headers->raw_headers().length();
- m_client->OnReceiveResponse(std::move(m_head));
- m_client->OnStartLoadingResponseBody(std::move(m_pipeConsumerHandle));
+ m_client->OnReceiveResponse(std::move(m_head), std::move(m_pipeConsumerHandle), absl::nullopt);
m_head = nullptr;
- if (readAvailableData()) // May delete this
- return;
-
m_watcher = std::make_unique<mojo::SimpleWatcher>(
- FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC, m_taskRunner);
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, m_taskRunner);
m_watcher->Watch(m_pipeProducerHandle.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_WATCH_CONDITION_SATISFIED,
base::BindRepeating(&CustomURLLoader::notifyReadyWrite,
m_weakPtrFactory.GetWeakPtr()));
+
+ readAvailableData(); // May delete this
}
void notifyCanceled() override
{
@@ -358,8 +343,9 @@ private:
}
m_head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(net::HttpUtil::AssembleRawHeaders(headers));
m_head->encoded_data_length = m_head->headers->raw_headers().length();
- m_head->content_length = m_head->encoded_body_length = -1;
- m_client->OnReceiveResponse(std::move(m_head));
+ m_head->content_length = {};
+ m_head->encoded_body_length = {};
+ m_client->OnReceiveResponse(std::move(m_head), mojo::ScopedDataPipeConsumerHandle(), absl::nullopt);
CompleteWithFailure(net::Error(error));
}
void notifyReadyRead() override
@@ -387,8 +373,10 @@ private:
uint32_t bufferSize = 0;
MojoResult beginResult = m_pipeProducerHandle->BeginWriteData(
&buffer, &bufferSize, MOJO_BEGIN_WRITE_DATA_FLAG_NONE);
- if (beginResult == MOJO_RESULT_SHOULD_WAIT)
+ if (beginResult == MOJO_RESULT_SHOULD_WAIT) {
+ m_watcher->ArmOrNotify();
return false; // Wait for pipe watcher
+ }
if (beginResult != MOJO_RESULT_OK)
break;
if (m_maxBytesToRead > 0 && m_maxBytesToRead <= int64_t{std::numeric_limits<uint32_t>::max()})
@@ -400,13 +388,20 @@ private:
m_totalBytesRead += bytesRead;
m_client->OnTransferSizeUpdated(m_totalBytesRead);
- if (m_device->atEnd() || (m_maxBytesToRead > 0 && m_totalBytesRead >= m_maxBytesToRead)) {
+ const bool deviceAtEnd = m_device->atEnd();
+ if ((deviceAtEnd && !m_device->isSequential())
+ || (m_maxBytesToRead > 0 && m_totalBytesRead >= m_maxBytesToRead)) {
OnTransferComplete(MOJO_RESULT_OK);
return true; // Done with reading
}
if (readResult == 0)
return false; // Wait for readyRead
+ if (readResult < 0 && deviceAtEnd && m_device->isSequential()) {
+ // Failure on read, and sequential device claiming to be at end, so treat it as a successful end-of-data.
+ OnTransferComplete(MOJO_RESULT_OK);
+ return true; // Done with reading
+ }
if (readResult < 0)
break;
}
@@ -439,7 +434,7 @@ private:
scoped_refptr<URLRequestCustomJobProxy> m_proxy;
mojo::Receiver<network::mojom::URLLoader> m_receiver;
- network::mojom::URLLoaderClientPtr m_client;
+ mojo::Remote<network::mojom::URLLoaderClient> m_client;
mojo::ScopedDataPipeProducerHandle m_pipeProducerHandle;
mojo::ScopedDataPipeConsumerHandle m_pipeConsumerHandle;
std::unique_ptr<mojo::SimpleWatcher> m_watcher;
@@ -452,16 +447,15 @@ private:
qint64 m_headerBytesRead = 0;
qint64 m_totalBytesRead = 0;
bool m_corsEnabled;
+ bool m_isLocal;
base::WeakPtrFactory<CustomURLLoader> m_weakPtrFactory{this};
-
- DISALLOW_COPY_AND_ASSIGN(CustomURLLoader);
};
class CustomURLLoaderFactory : public network::mojom::URLLoaderFactory {
public:
CustomURLLoaderFactory(ProfileAdapter *profileAdapter, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
- : m_taskRunner(base::CreateSequencedTaskRunner({ content::BrowserThread::IO }))
+ : m_taskRunner(content::GetIOThreadTaskRunner({}))
, m_profileAdapter(profileAdapter)
{
m_receivers.set_disconnect_handler(base::BindRepeating(
@@ -472,7 +466,6 @@ public:
// network::mojom::URLLoaderFactory:
void CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader,
- int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest &request,
@@ -480,7 +473,6 @@ public:
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- Q_UNUSED(routing_id);
Q_UNUSED(request_id);
Q_UNUSED(options);
Q_UNUSED(traffic_annotation);
@@ -513,7 +505,6 @@ public:
const scoped_refptr<base::SequencedTaskRunner> m_taskRunner;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_receivers;
QPointer<ProfileAdapter> m_profileAdapter;
- DISALLOW_COPY_AND_ASSIGN(CustomURLLoaderFactory);
};
} // namespace
diff --git a/src/core/net/custom_url_loader_factory.h b/src/core/net/custom_url_loader_factory.h
index a9eecbd1c..fb0c74627 100644
--- a/src/core/net/custom_url_loader_factory.h
+++ b/src/core/net/custom_url_loader_factory.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index d66e69ef4..159fa28ca 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
// Copyright 2018 The Chromium Authors. All rights reserved.
@@ -44,9 +8,8 @@
#include "plugin_response_interceptor_url_loader_throttle.h"
-#include "base/bind.h"
-#include "base/guid.h"
-#include "base/task/post_task.h"
+#include "base/functional/bind.h"
+#include "base/uuid.h"
#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -64,14 +27,58 @@
#include "web_engine_settings.h"
#include <string>
+#include <tuple>
+
+namespace {
+void ClearAllButFrameAncestors(network::mojom::URLResponseHead *response_head)
+{
+ response_head->headers->RemoveHeader("Content-Security-Policy");
+ response_head->headers->RemoveHeader("Content-Security-Policy-Report-Only");
+
+ if (!response_head->parsed_headers)
+ return;
+
+ std::vector<network::mojom::ContentSecurityPolicyPtr> &csp =
+ response_head->parsed_headers->content_security_policy;
+ std::vector<network::mojom::ContentSecurityPolicyPtr> cleared;
+
+ for (auto &policy : csp) {
+ auto frame_ancestors = policy->directives.find(network::mojom::CSPDirectiveName::FrameAncestors);
+ if (frame_ancestors == policy->directives.end())
+ continue;
+
+ auto cleared_policy = network::mojom::ContentSecurityPolicy::New();
+ cleared_policy->self_origin = std::move(policy->self_origin);
+ cleared_policy->header = std::move(policy->header);
+ cleared_policy->header->header_value = "";
+ cleared_policy->directives[network::mojom::CSPDirectiveName::FrameAncestors] = std::move(frame_ancestors->second);
+
+ auto raw_frame_ancestors = policy->raw_directives.find(network::mojom::CSPDirectiveName::FrameAncestors);
+ DCHECK(raw_frame_ancestors != policy->raw_directives.end());
+
+ cleared_policy->header->header_value = "frame-ancestors " + raw_frame_ancestors->second;
+ response_head->headers->AddHeader(
+ cleared_policy->header->type == network::mojom::ContentSecurityPolicyType::kEnforce
+ ? "Content-Security-Policy"
+ : "Content-Security-Policy-Report-Only",
+ cleared_policy->header->header_value);
+ cleared_policy->raw_directives[network::mojom::CSPDirectiveName::FrameAncestors] =
+ std::move(raw_frame_ancestors->second);
+
+ cleared.push_back(std::move(cleared_policy));
+ }
+
+ csp.swap(cleared);
+}
+} // namespace
+
namespace QtWebEngineCore {
PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
- content::BrowserContext *browser_context,
network::mojom::RequestDestination request_destination,
int frame_tree_node_id)
- : m_browser_context(browser_context), m_request_destination(request_destination), m_frame_tree_node_id(frame_tree_node_id)
+ : m_request_destination(request_destination), m_frame_tree_node_id(frame_tree_node_id)
{}
void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL &response_url,
@@ -79,13 +86,16 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
bool *defer)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (content::download_utils::MustDownload(response_url, response_head->headers.get(), response_head->mime_type))
- return;
content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(m_frame_tree_node_id);
if (!web_contents)
return;
+ if (content::download_utils::MustDownload(
+ web_contents->GetBrowserContext(),
+ response_url, response_head->headers.get(), response_head->mime_type))
+ return;
+
std::string extension_id;
if (response_head->mime_type == "application/pdf")
extension_id = extension_misc::kPdfExtensionId;
@@ -109,16 +119,16 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
// Content-Security-Policy, and does not currently respect the policy anyway.
// Ignore CSP served on a PDF response. https://crbug.com/271452
if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
- response_head->headers->RemoveHeader("Content-Security-Policy");
+ ClearAllButFrameAncestors(response_head);
MimeTypesHandler::ReportUsedHandler(extension_id);
- std::string view_id = base::GenerateGUID();
+ std::string view_id = base::Uuid::GenerateRandomV4().AsLowercaseString();
// The string passed down to the original client with the response body.
std::string payload = view_id;
mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader;
- ignore_result(dummy_new_loader.InitWithNewPipeAndPassReceiver());
+ std::ignore = dummy_new_loader.InitWithNewPipeAndPassReceiver();
mojo::Remote<network::mojom::URLLoaderClient> new_client;
mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver =
new_client.BindNewPipeAndPassReceiver();
@@ -143,18 +153,17 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
producer_handle->WriteData(
payload.c_str(), &len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
-
- new_client->OnStartLoadingResponseBody(std::move(consumer_handle));
-
network::URLLoaderCompletionStatus status(net::OK);
status.decoded_body_length = len;
new_client->OnComplete(status);
mojo::PendingRemote<network::mojom::URLLoader> original_loader;
mojo::PendingReceiver<network::mojom::URLLoaderClient> original_client;
+ mojo::ScopedDataPipeConsumerHandle body = std::move(consumer_handle);
delegate_->InterceptResponse(std::move(dummy_new_loader),
- std::move(new_client_receiver), &original_loader,
- &original_client);
+ std::move(new_client_receiver),
+ &original_loader, &original_client,
+ &body);
// Make a deep copy of URLResponseHead before passing it cross-thread.
auto deep_copied_response = response_head->Clone();
@@ -167,11 +176,12 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
auto transferrable_loader = blink::mojom::TransferrableURLLoader::New();
transferrable_loader->url = GURL(
extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
- base::GenerateGUID());
+ base::Uuid::GenerateRandomV4().AsLowercaseString());
transferrable_loader->url_loader = std::move(original_loader);
transferrable_loader->url_loader_client = std::move(original_client);
transferrable_loader->head = std::move(deep_copied_response);
transferrable_loader->head->intercepted_by_plugin = true;
+ transferrable_loader->body = std::move(body);
bool embedded = m_request_destination !=
network::mojom::RequestDestination::kDocument;
@@ -180,7 +190,6 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
base::BindOnce(
&extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
extension_id, view_id, embedded, m_frame_tree_node_id,
- -1 /* render_process_id */, -1 /* render_frame_id */,
std::move(transferrable_loader), response_url));
}
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.h b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
index 0e10b2124..fb3918c45 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.h
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
#define PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
-#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
@@ -54,8 +17,7 @@ namespace QtWebEngineCore {
class PluginResponseInterceptorURLLoaderThrottle : public blink::URLLoaderThrottle
{
public:
- PluginResponseInterceptorURLLoaderThrottle(content::BrowserContext *browser_context,
- network::mojom::RequestDestination request_destination,
+ PluginResponseInterceptorURLLoaderThrottle(network::mojom::RequestDestination request_destination,
int frame_tree_node_id);
~PluginResponseInterceptorURLLoaderThrottle() override = default;
@@ -67,14 +29,11 @@ private:
// layer chance to initialize its browser side state.
void ResumeLoad();
- content::BrowserContext *m_browser_context = nullptr;
const network::mojom::RequestDestination m_request_destination;
const int m_frame_tree_node_id;
base::WeakPtrFactory<PluginResponseInterceptorURLLoaderThrottle>
weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(PluginResponseInterceptorURLLoaderThrottle);
};
} // namespace QtWebEngineCore
diff --git a/src/core/net/proxy_config_monitor.cpp b/src/core/net/proxy_config_monitor.cpp
index de0211f2f..8315b7bf2 100644
--- a/src/core/net/proxy_config_monitor.cpp
+++ b/src/core/net/proxy_config_monitor.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// originally based on chrome/browser/net/proxy_config_monitor.cc
// Copyright 2017 The Chromium Authors. All rights reserved.
@@ -46,14 +10,11 @@
#include "proxy_config_monitor.h"
#include "proxy_config_service_qt.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
-#include "build/build_config.h"
-#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "content/public/browser/browser_task_traits.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "net/proxy_resolution/proxy_resolution_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include <utility>
@@ -64,9 +25,7 @@ ProxyConfigMonitor::ProxyConfigMonitor(PrefService *prefs)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- proxy_config_service_.reset(
- new ProxyConfigServiceQt(
- prefs, base::CreateSingleThreadTaskRunner({ BrowserThread::UI })));
+ proxy_config_service_.reset(new ProxyConfigServiceQt(prefs, content::GetUIThreadTaskRunner({})));
proxy_config_service_->AddObserver(this);
}
diff --git a/src/core/net/proxy_config_monitor.h b/src/core/net/proxy_config_monitor.h
index fda6a6fb9..585e4b7ed 100644
--- a/src/core/net/proxy_config_monitor.h
+++ b/src/core/net/proxy_config_monitor.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// originally based on chrome/browser/net/proxy_config_monitor.h
// Copyright 2017 The Chromium Authors. All rights reserved.
@@ -46,17 +10,11 @@
#define PROXY_CONFIG_MONITOR_H
#include <memory>
-#include <string>
-#include "base/macros.h"
-#include "build/buildflag.h"
-#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "services/network/public/mojom/network_context.mojom-forward.h"
-#include "services/network/public/mojom/network_service.mojom-forward.h"
-#include "services/network/public/mojom/proxy_config.mojom-forward.h"
#include "services/network/public/mojom/proxy_config_with_annotation.mojom.h"
namespace net {
@@ -96,8 +54,6 @@ private:
mojo::ReceiverSet<network::mojom::ProxyConfigPollerClient> poller_receiver_set_;
mojo::RemoteSet<network::mojom::ProxyConfigClient> proxy_config_client_set_;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyConfigMonitor);
};
-#endif // !PROXY_CONFIG_MONITOR_H
+#endif // PROXY_CONFIG_MONITOR_H
diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
index bc934c960..fcce08550 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//================ Based on ChromeProxyConfigService =======================
@@ -45,23 +9,22 @@
#include "proxy_config_service_qt.h"
-#include "base/bind.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/proxy_resolution/configured_proxy_resolution_service.h"
+#include "net/base/proxy_server.h"
-using content::BrowserThread;
+#include <QNetworkProxy>
net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy)
{
- net::HostPortPair hostPortPair(qtProxy.hostName().toStdString(), qtProxy.port());
+ std::string host = qtProxy.hostName().toStdString();
+ uint16_t port = qtProxy.port();
switch (qtProxy.type()) {
case QNetworkProxy::Socks5Proxy:
- return net::ProxyServer(net::ProxyServer::SCHEME_SOCKS5, hostPortPair);
+ return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_SOCKS5, host, port);
case QNetworkProxy::HttpProxy:
case QNetworkProxy::HttpCachingProxy:
case QNetworkProxy::FtpCachingProxy:
- return net::ProxyServer(net::ProxyServer::SCHEME_HTTP, hostPortPair);
+ return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTP, host, port);
case QNetworkProxy::NoProxy:
case QNetworkProxy::DefaultProxy:
return net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair());
@@ -71,8 +34,8 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
}
ProxyConfigServiceQt::ProxyConfigServiceQt(PrefService *prefService,
- const scoped_refptr<base::SingleThreadTaskRunner> &taskRunner)
- : m_baseService(net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(taskRunner))
+ const scoped_refptr<base::SequencedTaskRunner> &taskRunner)
+ : m_baseService(net::ProxyConfigService::CreateSystemProxyConfigService(taskRunner))
, m_usesSystemConfiguration(false)
, m_registeredObserver(false)
, m_prefState(prefService
diff --git a/src/core/net/proxy_config_service_qt.h b/src/core/net/proxy_config_service_qt.h
index c0928bc03..49c9877a5 100644
--- a/src/core/net/proxy_config_service_qt.h
+++ b/src/core/net/proxy_config_service_qt.h
@@ -1,49 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PROXY_CONFIG_SERVICE_QT_H
#define PROXY_CONFIG_SERVICE_QT_H
-#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
-#include "base/single_thread_task_runner.h"
-
+#include "base/task/sequenced_task_runner.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
@@ -61,7 +23,7 @@ public:
static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
explicit ProxyConfigServiceQt(PrefService *prefService,
- const scoped_refptr<base::SingleThreadTaskRunner> &taskRunner);
+ const scoped_refptr<base::SequencedTaskRunner> &taskRunner);
~ProxyConfigServiceQt() override;
// ProxyConfigService implementation:
@@ -97,8 +59,6 @@ private:
ProxyPrefs::ConfigState m_prefState;
SEQUENCE_CHECKER(m_sequenceChecker);
-
- DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
};
#endif // PROXY_CONFIG_SERVICE_QT_H
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index f86c0e997..d4d5cc4ab 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.cpp
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// originally based on android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc:
// Copyright 2019 The Chromium Authors. All rights reserved.
@@ -46,12 +10,10 @@
#include "api/qwebenginecookiestore.h"
#include "api/qwebenginecookiestore_p.h"
-#include "profile_adapter.h"
-#include "profile_qt.h"
+#include "profile_io_data_qt.h"
#include "type_conversion.h"
#include "base/memory/ptr_util.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
@@ -61,18 +23,14 @@ namespace QtWebEngineCore {
// static
void ProxyingRestrictedCookieManagerQt::CreateAndBind(ProfileIODataQt *profileIoData,
mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
- bool is_service_worker,
- int process_id,
- int frame_id,
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
+ content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread,
profileIoData,
std::move(underlying_rcm),
- is_service_worker, process_id, frame_id,
std::move(receiver)));
}
@@ -80,31 +38,21 @@ void ProxyingRestrictedCookieManagerQt::CreateAndBind(ProfileIODataQt *profileIo
// static
void ProxyingRestrictedCookieManagerQt::CreateAndBindOnIoThread(ProfileIODataQt *profileIoData,
mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
- bool is_service_worker,
- int process_id,
- int frame_id,
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
auto wrapper = base::WrapUnique(new ProxyingRestrictedCookieManagerQt(
profileIoData->getWeakPtrOnIOThread(),
- std::move(underlying_rcm),
- is_service_worker, process_id, frame_id));
+ std::move(underlying_rcm)));
mojo::MakeSelfOwnedReceiver(std::move(wrapper), std::move(receiver));
}
ProxyingRestrictedCookieManagerQt::ProxyingRestrictedCookieManagerQt(
base::WeakPtr<ProfileIODataQt> profileIoData,
- mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlyingRestrictedCookieManager,
- bool is_service_worker,
- int32_t process_id,
- int32_t frame_id)
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlyingRestrictedCookieManager)
: m_profileIoData(std::move(profileIoData))
, underlying_restricted_cookie_manager_(std::move(underlyingRestrictedCookieManager))
- , is_service_worker_(is_service_worker)
- , process_id_(process_id)
- , frame_id_(frame_id)
, weak_factory_(this)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -117,14 +65,15 @@ ProxyingRestrictedCookieManagerQt::~ProxyingRestrictedCookieManagerQt()
void ProxyingRestrictedCookieManagerQt::GetAllForUrl(const GURL &url,
const net::SiteForCookies &site_for_cookies,
- const url::Origin &top_frame_origin,
+ const url::Origin &top_frame_origin, bool has_storage_access,
network::mojom::CookieManagerGetOptionsPtr options,
GetAllForUrlCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (allowCookies(url, site_for_cookies)) {
- underlying_restricted_cookie_manager_->GetAllForUrl(url, site_for_cookies, top_frame_origin, std::move(options), std::move(callback));
+ underlying_restricted_cookie_manager_->GetAllForUrl(url, site_for_cookies, top_frame_origin, has_storage_access,
+ std::move(options), std::move(callback));
} else {
std::move(callback).Run(std::vector<net::CookieWithAccessResult>());
}
@@ -134,12 +83,15 @@ void ProxyingRestrictedCookieManagerQt::SetCanonicalCookie(const net::CanonicalC
const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ net::CookieInclusionStatus status,
SetCanonicalCookieCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (allowCookies(url, site_for_cookies)) {
- underlying_restricted_cookie_manager_->SetCanonicalCookie(cookie, url, site_for_cookies, top_frame_origin, std::move(callback));
+ underlying_restricted_cookie_manager_->SetCanonicalCookie(cookie, url, site_for_cookies, top_frame_origin,
+ has_storage_access, status, std::move(callback));
} else {
std::move(callback).Run(false);
}
@@ -148,45 +100,52 @@ void ProxyingRestrictedCookieManagerQt::SetCanonicalCookie(const net::CanonicalC
void ProxyingRestrictedCookieManagerQt::AddChangeListener(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
mojo::PendingRemote<network::mojom::CookieChangeListener> listener,
AddChangeListenerCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- underlying_restricted_cookie_manager_->AddChangeListener(url, site_for_cookies, top_frame_origin, std::move(listener), std::move(callback));
+ underlying_restricted_cookie_manager_->AddChangeListener(url, site_for_cookies, top_frame_origin, has_storage_access,
+ std::move(listener), std::move(callback));
}
void ProxyingRestrictedCookieManagerQt::SetCookieFromString(const GURL &url,
const net::SiteForCookies &site_for_cookies,
- const url::Origin &top_frame_origin,
+ const url::Origin &top_frame_origin, bool has_storage_access,
const std::string &cookie,
SetCookieFromStringCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (allowCookies(url, site_for_cookies)) {
- underlying_restricted_cookie_manager_->SetCookieFromString(url, site_for_cookies, top_frame_origin, cookie, std::move(callback));
+ underlying_restricted_cookie_manager_->SetCookieFromString(url, site_for_cookies, top_frame_origin, has_storage_access,
+ cookie, std::move(callback));
} else {
- std::move(callback).Run();
+ std::move(callback).Run(false, false); // FIXME: is true, true in aw_proxying_restricted_cookie_manager.cc though..
}
}
void ProxyingRestrictedCookieManagerQt::GetCookiesString(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access, bool get_version_shared_memory,
GetCookiesStringCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (allowCookies(url, site_for_cookies)) {
- underlying_restricted_cookie_manager_->GetCookiesString(url, site_for_cookies, top_frame_origin, std::move(callback));
+ underlying_restricted_cookie_manager_->GetCookiesString(url, site_for_cookies, top_frame_origin,
+ has_storage_access, get_version_shared_memory,
+ std::move(callback));
} else {
- std::move(callback).Run("");
+ std::move(callback).Run(network::mojom::kInvalidCookieVersion, base::ReadOnlySharedMemoryRegion(), "");
}
}
void ProxyingRestrictedCookieManagerQt::CookiesEnabledFor(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin & /*top_frame_origin*/,
+ bool /*has_storage_access*/,
CookiesEnabledForCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.h b/src/core/net/proxying_restricted_cookie_manager_qt.h
index 3d4765b3b..faf0545c3 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.h
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
#define PROXYING_RESTRICTED_COOKIE_MANAGER_QT_H
-#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/restricted_cookie_manager.mojom.h"
@@ -56,9 +19,6 @@ public:
// Expects to be called on the UI thread.
static void CreateAndBind(ProfileIODataQt *profileIoData,
mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
- bool is_service_worker,
- int process_id,
- int frame_id,
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver);
~ProxyingRestrictedCookieManagerQt() override;
@@ -67,30 +27,38 @@ public:
void GetAllForUrl(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
network::mojom::CookieManagerGetOptionsPtr options,
GetAllForUrlCallback callback) override;
+
void SetCanonicalCookie(const net::CanonicalCookie& cookie,
const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
+ net::CookieInclusionStatus status,
SetCanonicalCookieCallback callback) override;
void AddChangeListener(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
mojo::PendingRemote<network::mojom::CookieChangeListener> listener,
AddChangeListenerCallback callback) override;
void SetCookieFromString(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
const std::string &cookie,
SetCookieFromStringCallback callback) override;
void GetCookiesString(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access, bool get_version_shared_memory,
GetCookiesStringCallback callback) override;
void CookiesEnabledFor(const GURL &url,
const net::SiteForCookies &site_for_cookies,
const url::Origin &top_frame_origin,
+ bool has_storage_access,
CookiesEnabledForCallback callback) override;
// Internal:
@@ -98,28 +66,17 @@ public:
private:
ProxyingRestrictedCookieManagerQt(base::WeakPtr<ProfileIODataQt> profileIoData,
- mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
- bool is_service_worker,
- int32_t process_id,
- int32_t frame_id);
+ mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm);
static void CreateAndBindOnIoThread(ProfileIODataQt *profileIoData,
mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
- bool is_service_worker,
- int process_id,
- int frame_id,
mojo::PendingReceiver<network::mojom::RestrictedCookieManager> receiver);
base::WeakPtr<ProfileIODataQt> m_profileIoData;
mojo::Remote<network::mojom::RestrictedCookieManager> underlying_restricted_cookie_manager_;
- bool is_service_worker_;
- int process_id_;
- int frame_id_;
base::WeakPtrFactory<ProxyingRestrictedCookieManagerQt> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyingRestrictedCookieManagerQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 6505e5505..3a83ed7ea 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -1,71 +1,48 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "proxying_url_loader_factory_qt.h"
#include <utility>
-#include "base/bind.h"
-#include "base/task/post_task.h"
+#include "base/functional/bind.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
+#include "net/base/filename_util.h"
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/early_hints.mojom.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
#include "url/url_util.h"
+#include "url/url_util_qt.h"
#include "api/qwebengineurlrequestinfo_p.h"
#include "type_conversion.h"
#include "web_contents_adapter.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
-
-#include <QVariant>
+#include "net/resource_request_body_qt.h"
// originally based on aw_proxying_url_loader_factory.cc:
// Copyright 2018 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.
+namespace {
+ network::mojom::URLResponseHeadPtr createResponse(const network::ResourceRequest &request) {
+ const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
+ network::mojom::URLResponseHeadPtr response = network::mojom::URLResponseHead::New();
+ response->response_type = network::cors::CalculateResponseType(
+ request.mode, disable_web_security || (
+ request.request_initiator && request.request_initiator->IsSameOriginWith(url::Origin::Create(request.url))));
+
+ return response;
+ }
+}
+
namespace QtWebEngineCore {
ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, blink::mojom::ResourceType::kMainFrame)
@@ -104,6 +81,18 @@ static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::N
return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
}
+static QHash<QByteArray, QByteArray> toQt(const net::HttpRequestHeaders &headers)
+{
+ const auto vector = headers.GetHeaderVector();
+ QHash<QByteArray, QByteArray> hash;
+
+ for (const auto &header : vector) {
+ hash.insert(QByteArray::fromStdString(header.key), QByteArray::fromStdString(header.value));
+ }
+
+ return hash;
+}
+
// Handles intercepted, in-progress requests/responses, so that they can be
// controlled and modified accordingly.
class InterceptedRequest : public network::mojom::URLLoader
@@ -111,7 +100,7 @@ class InterceptedRequest : public network::mojom::URLLoader
{
public:
InterceptedRequest(ProfileAdapter *profile_adapter,
- int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
+ int frame_tree_node_id, int32_t request_id, uint32_t options,
const network::ResourceRequest &request,
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
mojo::PendingReceiver<network::mojom::URLLoader> loader,
@@ -122,25 +111,22 @@ public:
void Restart();
// network::mojom::URLLoaderClient
- void OnReceiveResponse(network::mojom::URLResponseHeadPtr head) override;
+ void OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle, absl::optional<mojo_base::BigBuffer>) override;
void OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head) override;
void OnUploadProgress(int64_t current_position, int64_t total_size, OnUploadProgressCallback callback) override;
- void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
- void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus &status) override;
+ void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr) override {}
// network::mojom::URLLoader
void FollowRedirect(const std::vector<std::string> &removed_headers,
const net::HttpRequestHeaders &modified_headers,
const net::HttpRequestHeaders &modified_cors_exempt_headers,
- const base::Optional<GURL> &new_url) override;
+ const absl::optional<GURL> &new_url) override;
void SetPriority(net::RequestPriority priority, int32_t intra_priority_value) override;
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
- static inline void cleanup(QWebEngineUrlRequestInfo *info) { delete info; }
-
private:
void InterceptOnUIThread();
void ContinueAfterIntercept();
@@ -163,22 +149,33 @@ private:
QWebEngineUrlRequestInterceptor* getPageInterceptor();
QPointer<ProfileAdapter> profile_adapter_;
- const int process_id_;
- const uint64_t request_id_;
- const int32_t routing_id_;
+ const int frame_tree_node_id_;
+ const int32_t request_id_;
const uint32_t options_;
- bool allowed_cors_ = true;
+ bool allow_local_ = false;
+ bool allow_remote_ = true;
+ bool local_access_ = false;
+ bool remote_access_ = true;
+
+ bool loader_error_seen_ = false;
// If the |target_loader_| called OnComplete with an error this stores it.
// That way the destructor can send it to OnReceivedError if safe browsing
// error didn't occur.
int error_status_ = net::OK;
network::ResourceRequest request_;
+ ResourceRequestBody request_body_;
network::mojom::URLResponseHeadPtr current_response_;
const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
- QScopedPointer<QWebEngineUrlRequestInfo, InterceptedRequest> request_info_;
+ struct RequestInfoDeleter
+ {
+ void operator()(QWebEngineUrlRequestInfo *ptr) const
+ { delete ptr; }
+ };
+
+ std::unique_ptr<QWebEngineUrlRequestInfo, RequestInfoDeleter> request_info_;
mojo::Receiver<network::mojom::URLLoader> proxied_loader_receiver_;
mojo::Remote<network::mojom::URLLoaderClient> target_client_;
@@ -187,22 +184,21 @@ private:
mojo::Remote<network::mojom::URLLoaderFactory> target_factory_;
base::WeakPtrFactory<InterceptedRequest> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(InterceptedRequest);
};
InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter,
- int process_id, uint64_t request_id, int32_t routing_id, uint32_t options,
+ int frame_tree_node_id, int32_t request_id, uint32_t options,
const network::ResourceRequest &request,
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation,
mojo::PendingReceiver<network::mojom::URLLoader> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory)
: profile_adapter_(profile_adapter)
- , process_id_(process_id)
+ , frame_tree_node_id_(frame_tree_node_id)
, request_id_(request_id)
- , routing_id_(routing_id)
, options_(options)
, request_(request)
+ , request_body_(ResourceRequestBody(request_.request_body.get()))
, traffic_annotation_(traffic_annotation)
, proxied_loader_receiver_(this, std::move(loader_receiver))
, target_client_(std::move(client))
@@ -210,11 +206,7 @@ InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter,
, weak_factory_(this)
{
const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
- current_response_ = network::mojom::URLResponseHead::New();
- current_response_->response_type = network::cors::CalculateResponseType(
- request_.mode,
- disable_web_security || (
- request_.request_initiator && request_.request_initiator->IsSameOriginWith(url::Origin::Create(request_.url))));
+ current_response_ = createResponse(request_);
// If there is a client error, clean up the request.
target_client_.set_disconnect_handler(
base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, base::Unretained(this)));
@@ -222,22 +214,20 @@ InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter,
base::BindOnce(&InterceptedRequest::OnURLLoaderError, base::Unretained(this)));
if (!disable_web_security && request_.request_initiator) {
const std::vector<std::string> &localSchemes = url::GetLocalSchemes();
- std::string fromScheme = request_.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
- if (base::Contains(localSchemes, fromScheme)) {
+ const std::string fromScheme = request_.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
+ const std::string toScheme = request_.url.scheme();
+ const bool fromLocal = base::Contains(localSchemes, fromScheme);
+ const bool toLocal = base::Contains(localSchemes, toScheme);
+ bool hasLocalAccess = false;
+ local_access_ = toLocal;
+ remote_access_ = !toLocal && (toScheme != "data") && (toScheme != "qrc");
+ if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(fromScheme))
+ hasLocalAccess = cs->flags & url::CustomScheme::LocalAccessAllowed;
+ if (fromLocal || toLocal) {
content::WebContents *wc = webContents();
- std::string toScheme = request_.url.scheme();
// local schemes must have universal access, or be accessing something local and have local access.
- if (fromScheme != toScheme) {
- // note allow_file_access_from_file_urls maps to LocalContentCanAccessFileUrls in our API
- // and allow_universal_access_from_file_urls to LocalContentCanAccessRemoteUrls, so we are
- // using them as proxies for our API here.
- if (toScheme == "file")
- allowed_cors_ = wc && wc->GetOrCreateWebPreferences().allow_file_access_from_file_urls;
- else if (!base::Contains(localSchemes, toScheme))
- allowed_cors_ = wc && wc->GetOrCreateWebPreferences().allow_universal_access_from_file_urls;
- else
- allowed_cors_ = true; // We should think about this for future patches
- }
+ allow_local_ = hasLocalAccess || (fromLocal && wc && wc->GetOrCreateWebPreferences().allow_file_access_from_file_urls);
+ allow_remote_ = !fromLocal || (wc && wc->GetOrCreateWebPreferences().allow_remote_access_from_local_urls);
}
}
}
@@ -249,12 +239,9 @@ InterceptedRequest::~InterceptedRequest()
content::WebContents* InterceptedRequest::webContents()
{
- if (process_id_) {
- content::RenderFrameHost *frameHost = content::RenderFrameHost::FromID(process_id_, request_.render_frame_id);
- return content::WebContents::FromRenderFrameHost(frameHost);
- }
-
- return content::WebContents::FromFrameTreeNodeId(request_.render_frame_id);
+ if (frame_tree_node_id_ == content::RenderFrameHost::kNoFrameTreeNodeId)
+ return nullptr;
+ return content::WebContents::FromFrameTreeNodeId(frame_tree_node_id_);
}
QWebEngineUrlRequestInterceptor* InterceptedRequest::getProfileInterceptor()
@@ -276,12 +263,48 @@ void InterceptedRequest::Restart()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- // This is a CORS check on the from URL, the normal check on the to URL is applied later
- if (!allowed_cors_ && current_response_->response_type == network::mojom::FetchResponseType::kCors) {
- target_client_->OnComplete(network::URLLoaderCompletionStatus(
- network::CorsErrorStatus(network::mojom::CorsError::kCorsDisabledScheme)));
- delete this;
- return;
+ bool granted_special_access = false;
+ auto navigationType = toQt(pageTransitionToNavigationType(ui::PageTransition(request_.transition_type)));
+ switch (navigationType) {
+ case QWebEngineUrlRequestInfo::NavigationTypeLink:
+ case QWebEngineUrlRequestInfo::NavigationTypeTyped:
+ if (blink::mojom::ResourceType(request_.resource_type) == blink::mojom::ResourceType::kMainFrame && request_.has_user_gesture)
+ granted_special_access = true; // allow normal explicit navigation
+ break;
+ case QWebEngineUrlRequestInfo::NavigationTypeBackForward:
+ case QWebEngineUrlRequestInfo::NavigationTypeReload:
+ if (blink::mojom::ResourceType(request_.resource_type) == blink::mojom::ResourceType::kMainFrame)
+ granted_special_access = true;
+ break;
+ default:
+ break;
+ }
+
+ // Check if non-local access is allowed
+ if (!allow_remote_ && remote_access_) {
+ if (!granted_special_access) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_NETWORK_ACCESS_DENIED));
+ delete this;
+ return;
+ }
+ }
+
+ // Check if local access is allowed
+ if (!allow_local_ && local_access_) {
+ // Check for specifically granted file access:
+ if (auto *frame_tree = content::FrameTreeNode::GloballyFindByID(frame_tree_node_id_)) {
+ const int renderer_id = frame_tree->current_frame_host()->GetProcess()->GetID();
+ base::FilePath file_path;
+ if (net::FileURLToFilePath(request_.url, &file_path)) {
+ if (content::ChildProcessSecurityPolicy::GetInstance()->CanReadFile(renderer_id, file_path))
+ granted_special_access = true;
+ }
+ }
+ if (!granted_special_access) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
+ delete this;
+ return;
+ }
}
// MEMO since all codepatch leading to Restart scheduled and executed as asynchronous tasks in main thread,
@@ -294,7 +317,6 @@ void InterceptedRequest::Restart()
}
auto resourceType = toQt(blink::mojom::ResourceType(request_.resource_type));
- auto navigationType = toQt(pageTransitionToNavigationType(ui::PageTransition(request_.transition_type)));
const QUrl originalUrl = toQt(request_.url);
const QUrl initiator = request_.request_initiator.has_value() ? toQt(request_.request_initiator->GetURL()) : QUrl();
@@ -306,8 +328,14 @@ void InterceptedRequest::Restart()
else
firstPartyUrl = toQt(request_.site_for_cookies.first_party_url()); // m_topDocumentUrl can be empty for the main-frame.
- auto info = new QWebEngineUrlRequestInfoPrivate(resourceType, navigationType, originalUrl, firstPartyUrl,
- initiator, QByteArray::fromStdString(request_.method));
+ QHash<QByteArray, QByteArray> headers = toQt(request_.headers);
+
+ if (!request_.referrer.is_empty())
+ headers.insert("Referer", toQt(request_.referrer).toEncoded());
+
+ auto info = new QWebEngineUrlRequestInfoPrivate(
+ resourceType, navigationType, originalUrl, firstPartyUrl, initiator,
+ QByteArray::fromStdString(request_.method), &request_body_, headers);
Q_ASSERT(!request_info_);
request_info_.reset(new QWebEngineUrlRequestInfo(info));
@@ -333,22 +361,21 @@ void InterceptedRequest::ContinueAfterIntercept()
if (request_info_) {
// cleanup in scope because of delete this and it's not needed else where after
- decltype(request_info_) scoped_request_info(request_info_.take());
+ const auto scoped_request_info = std::move(request_info_);
QWebEngineUrlRequestInfoPrivate &info = *scoped_request_info->d_ptr;
+ for (auto header = info.extraHeaders.constBegin(); header != info.extraHeaders.constEnd(); ++header) {
+ std::string h = header.key().toStdString();
+ if (base::EqualsCaseInsensitiveASCII(h, "referer"))
+ request_.referrer = GURL(header.value().toStdString());
+ else
+ request_.headers.SetHeader(h, header.value().toStdString());
+ }
+
if (info.changed) {
if (info.shouldBlockRequest)
return SendErrorAndCompleteImmediately(net::ERR_BLOCKED_BY_CLIENT);
- for (auto header = info.extraHeaders.constBegin(); header != info.extraHeaders.constEnd(); ++header) {
- std::string h = header.key().toStdString();
- if (base::LowerCaseEqualsASCII(h, "referer")) {
- request_.referrer = GURL(header.value().toStdString());
- } else {
- request_.headers.SetHeader(h, header.value().toStdString());
- }
- }
-
if (info.shouldRedirectRequest) {
net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy =
request_.update_first_party_url_on_redirect ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT
@@ -356,11 +383,8 @@ void InterceptedRequest::ContinueAfterIntercept()
net::RedirectInfo redirectInfo = net::RedirectInfo::ComputeRedirectInfo(
request_.method, request_.url, request_.site_for_cookies,
first_party_url_policy, request_.referrer_policy, request_.referrer.spec(),
- net::HTTP_TEMPORARY_REDIRECT, toGurl(info.url), base::nullopt,
+ net::HTTP_TEMPORARY_REDIRECT, toGurl(info.url), absl::nullopt,
false /*insecure_scheme_was_upgraded*/);
-
- // FIXME: Should probably create a new header.
- current_response_->encoded_data_length = 0;
request_.method = redirectInfo.new_method;
request_.url = redirectInfo.new_url;
request_.site_for_cookies = redirectInfo.new_site_for_cookies;
@@ -368,6 +392,11 @@ void InterceptedRequest::ContinueAfterIntercept()
request_.referrer_policy = redirectInfo.new_referrer_policy;
if (request_.method == net::HttpRequestHeaders::kGetMethod)
request_.request_body = nullptr;
+ // In case of multiple sequential rediredts, current_response_ has previously been moved to target_client_
+ // so we create a new one using the redirect url.
+ if (!current_response_)
+ current_response_ = createResponse(request_);
+ current_response_->encoded_data_length = 0;
target_client_->OnReceiveRedirect(redirectInfo, std::move(current_response_));
return;
}
@@ -375,7 +404,8 @@ void InterceptedRequest::ContinueAfterIntercept()
}
if (!target_loader_ && target_factory_) {
- target_factory_->CreateLoaderAndStart(target_loader_.BindNewPipeAndPassReceiver(), routing_id_, request_id_,
+ loader_error_seen_ = false;
+ target_factory_->CreateLoaderAndStart(target_loader_.BindNewPipeAndPassReceiver(), request_id_,
options_, request_, proxied_client_receiver_.BindNewPipeAndPassRemote(),
traffic_annotation_);
}
@@ -383,11 +413,11 @@ void InterceptedRequest::ContinueAfterIntercept()
// URLLoaderClient methods.
-void InterceptedRequest::OnReceiveResponse(network::mojom::URLResponseHeadPtr head)
+void InterceptedRequest::OnReceiveResponse(network::mojom::URLResponseHeadPtr head, mojo::ScopedDataPipeConsumerHandle handle, absl::optional<mojo_base::BigBuffer> buffer)
{
current_response_ = head.Clone();
- target_client_->OnReceiveResponse(std::move(head));
+ target_client_->OnReceiveResponse(std::move(head), std::move(handle), std::move(buffer));
}
void InterceptedRequest::OnReceiveRedirect(const net::RedirectInfo &redirect_info, network::mojom::URLResponseHeadPtr head)
@@ -407,21 +437,11 @@ void InterceptedRequest::OnUploadProgress(int64_t current_position, int64_t tota
target_client_->OnUploadProgress(current_position, total_size, std::move(callback));
}
-void InterceptedRequest::OnReceiveCachedMetadata(mojo_base::BigBuffer data)
-{
- target_client_->OnReceiveCachedMetadata(std::move(data));
-}
-
void InterceptedRequest::OnTransferSizeUpdated(int32_t transfer_size_diff)
{
target_client_->OnTransferSizeUpdated(transfer_size_diff);
}
-void InterceptedRequest::OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body)
-{
- target_client_->OnStartLoadingResponseBody(std::move(body));
-}
-
void InterceptedRequest::OnComplete(const network::URLLoaderCompletionStatus &status)
{
// Only wait for the original loader to possibly have a custom error if the
@@ -435,7 +455,7 @@ void InterceptedRequest::OnComplete(const network::URLLoaderCompletionStatus &st
void InterceptedRequest::FollowRedirect(const std::vector<std::string> &removed_headers,
const net::HttpRequestHeaders &modified_headers,
const net::HttpRequestHeaders &modified_cors_exempt_headers,
- const base::Optional<GURL> &new_url)
+ const absl::optional<GURL> &new_url)
{
if (target_loader_)
target_loader_->FollowRedirect(removed_headers, modified_headers, modified_cors_exempt_headers, new_url);
@@ -480,6 +500,8 @@ void InterceptedRequest::OnURLLoaderError(uint32_t custom_reason, const std::str
// If CallOnComplete was already called, then this object is ready to be deleted.
if (!target_client_)
delete this;
+ else
+ loader_error_seen_ = true;
}
void InterceptedRequest::CallOnComplete(const network::URLLoaderCompletionStatus &status, bool wait_for_loader_error)
@@ -493,7 +515,7 @@ void InterceptedRequest::CallOnComplete(const network::URLLoaderCompletionStatus
if (target_client_)
target_client_->OnComplete(status);
- if (proxied_loader_receiver_.is_bound() && wait_for_loader_error) {
+ if (proxied_loader_receiver_.is_bound() && wait_for_loader_error && !loader_error_seen_) {
// Since the original client is gone no need to continue loading the
// request.
proxied_client_receiver_.reset();
@@ -522,10 +544,10 @@ void InterceptedRequest::SendErrorAndCompleteImmediately(int error_code)
delete this;
}
-ProxyingURLLoaderFactoryQt::ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int process_id,
+ProxyingURLLoaderFactoryQt::ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int frame_tree_node_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_info)
- : m_profileAdapter(adapter), m_processId(process_id), m_weakFactory(this)
+ : m_profileAdapter(adapter), m_frameTreeNodeId(frame_tree_node_id), m_weakFactory(this)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (target_factory_info) {
@@ -543,8 +565,8 @@ ProxyingURLLoaderFactoryQt::~ProxyingURLLoaderFactoryQt()
m_weakFactory.InvalidateWeakPtrs();
}
-void ProxyingURLLoaderFactoryQt::CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader, int32_t routing_id,
- int32_t request_id, uint32_t options, const network::ResourceRequest &request,
+void ProxyingURLLoaderFactoryQt::CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader, int32_t request_id,
+ uint32_t options, const network::ResourceRequest &request,
mojo::PendingRemote<network::mojom::URLLoaderClient> url_loader_client,
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation)
{
@@ -554,7 +576,7 @@ void ProxyingURLLoaderFactoryQt::CreateLoaderAndStart(mojo::PendingReceiver<netw
m_targetFactory->Clone(target_factory_clone.InitWithNewPipeAndPassReceiver());
// Will manage its own lifetime
- InterceptedRequest *req = new InterceptedRequest(m_profileAdapter, m_processId, request_id, routing_id, options,
+ InterceptedRequest *req = new InterceptedRequest(m_profileAdapter, m_frameTreeNodeId, request_id, options,
request, traffic_annotation, std::move(loader),
std::move(url_loader_client), std::move(target_factory_clone));
req->Restart();
diff --git a/src/core/net/proxying_url_loader_factory_qt.h b/src/core/net/proxying_url_loader_factory_qt.h
index 5345e3220..904a40c2d 100644
--- a/src/core/net/proxying_url_loader_factory_qt.h
+++ b/src/core/net/proxying_url_loader_factory_qt.h
@@ -1,51 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PROXYING_URL_LOADER_FACTORY_QT_H_
#define PROXYING_URL_LOADER_FACTORY_QT_H_
-#include "base/callback.h"
-#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -55,6 +16,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+namespace network {
+struct ResourceRequest;
+}
+
namespace QtWebEngineCore {
class ProfileAdapter;
@@ -62,14 +27,14 @@ class ProfileAdapter;
class ProxyingURLLoaderFactoryQt : public network::mojom::URLLoaderFactory
{
public:
- ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int processId,
+ ProxyingURLLoaderFactoryQt(ProfileAdapter *adapter, int frameTreeNodeId,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_target_factory_remote);
~ProxyingURLLoaderFactoryQt() override;
void CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> loader,
- int32_t routing_id, int32_t request_id,
+ int32_t request_id,
uint32_t options, const network::ResourceRequest &request,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
const net::MutableNetworkTrafficAnnotationTag &traffic_annotation) override;
@@ -81,12 +46,10 @@ private:
void OnProxyBindingError();
QPointer<ProfileAdapter> m_profileAdapter;
- int m_processId;
+ int m_frameTreeNodeId;
mojo::ReceiverSet<network::mojom::URLLoaderFactory> m_proxyReceivers;
mojo::Remote<network::mojom::URLLoaderFactory> m_targetFactory;
base::WeakPtrFactory<ProxyingURLLoaderFactoryQt> m_weakFactory;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyingURLLoaderFactoryQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp
index 73bf24f1d..a8b4e4388 100644
--- a/src/core/net/qrc_url_scheme_handler.cpp
+++ b/src/core/net/qrc_url_scheme_handler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qrc_url_scheme_handler.h"
@@ -46,6 +10,8 @@
#include <QMimeDatabase>
#include <QMimeType>
+#include <memory>
+
namespace QtWebEngineCore {
void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
@@ -58,7 +24,7 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
QUrl requestUrl = job->requestUrl();
QString requestPath = requestUrl.path();
- QScopedPointer<QFile> file(new QFile(':' + requestPath, job));
+ auto file = std::make_unique<QFile>(':' + requestPath, job);
if (!file->exists() || file->size() == 0) {
qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath));
job->fail(QWebEngineUrlRequestJob::UrlNotFound);
@@ -67,7 +33,10 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
QFileInfo fileInfo(*file);
QMimeDatabase mimeDatabase;
QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
- job->reply(mimeType.name().toUtf8(), file.take());
+ if (mimeType.name() == QStringLiteral("application/x-extension-html"))
+ job->reply("text/html", file.release());
+ else
+ job->reply(mimeType.name().toUtf8(), file.release());
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/qrc_url_scheme_handler.h b/src/core/net/qrc_url_scheme_handler.h
index 586147cdf..96155b05b 100644
--- a/src/core/net/qrc_url_scheme_handler.h
+++ b/src/core/net/qrc_url_scheme_handler.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRC_URL_SCHEME_HANDLER_H
#define QRC_URL_SCHEME_HANDLER_H
diff --git a/src/core/net/resource_request_body_qt.cpp b/src/core/net/resource_request_body_qt.cpp
new file mode 100644
index 000000000..d0d54784d
--- /dev/null
+++ b/src/core/net/resource_request_body_qt.cpp
@@ -0,0 +1,181 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "resource_request_body_qt.h"
+#include "type_conversion.h"
+
+#include "services/network/public/cpp/resource_request_body.h"
+#include "services/network/public/mojom/data_pipe_getter.mojom.h"
+#include "services/network/public/mojom/url_request.mojom-shared.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace QtWebEngineCore {
+
+ResourceRequestBody::ResourceRequestBody(network::ResourceRequestBody *requestBody, QObject *parent)
+ : QIODevice(parent)
+ , m_requestBody(requestBody)
+ , m_dataElementsIdx(0)
+ , m_dataElementBytesIdx(0)
+ , m_dataElementFileIdx(0)
+{};
+
+ResourceRequestBody::~ResourceRequestBody(){};
+
+qint64 ResourceRequestBody::readData(char *data, qint64 maxSize)
+{
+ if (!m_requestBody)
+ return -1;
+
+ const std::size_t dataElementsSize = m_requestBody->elements()->size();
+ if (m_dataElementsIdx == dataElementsSize)
+ return -1;
+
+ qint64 bytesRead = 0;
+ const std::vector<network::DataElement> *elements = m_requestBody->elements();
+ while (bytesRead < maxSize && m_dataElementsIdx < dataElementsSize) {
+ const network::DataElement &currentDataElement = elements->at(m_dataElementsIdx);
+
+ switch (currentDataElement.type()) {
+ case network::mojom::DataElementDataView::Tag::kBytes: {
+ readDataElementBytes(currentDataElement.As<network::DataElementBytes>().bytes(),
+ bytesRead, maxSize, &data);
+ break;
+ }
+ case network::mojom::DataElementDataView::Tag::kFile: {
+ const network::DataElementFile file = currentDataElement.As<network::DataElementFile>();
+ const qint64 offset = file.offset();
+ const qint64 length = file.length();
+ readDataElementFile(file.path(), offset, length, bytesRead, maxSize, &data);
+ break;
+ }
+ case network::mojom::DataElementDataView::Tag::kDataPipe: {
+ mojo::Remote<network::mojom::DataPipeGetter> pipeGetter;
+ pipeGetter.Bind(
+ currentDataElement.As<network::DataElementDataPipe>().CloneDataPipeGetter());
+ const mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> consumerHandle =
+ getConsumerHandleFromPipeGetter(pipeGetter);
+ readDataElementPipe(consumerHandle, bytesRead, maxSize, &data);
+ break;
+ }
+ case network::mojom::DataElementDataView::Tag::kChunkedDataPipe: {
+ setErrorString(QStringLiteral("Chunked data pipe is used in request body upload, which "
+ "is currently not supported"));
+ // Nothing should come before or after DataElementChunkedDataPipe
+ return -1;
+ }
+ }
+
+ if (bytesRead == maxSize || m_dataElementsIdx == dataElementsSize)
+ break;
+ }
+
+ return bytesRead;
+}
+
+// We don't want to write, ever
+qint64 ResourceRequestBody::writeData(const char *data, qint64 maxSize)
+{
+ return -1;
+}
+
+bool ResourceRequestBody::isSequential() const
+{
+ return true;
+}
+
+void ResourceRequestBody::readDataElementBytes(const std::vector<uint8_t> &dataElement,
+ qint64 &bytesRead, const qint64 &maxSize,
+ char **data)
+{
+ const std::size_t dataElementSize = dataElement.size();
+ const std::size_t bytesToRead = std::min(dataElementSize, static_cast<std::size_t>(maxSize));
+
+ std::memcpy(*data, dataElement.data(), bytesToRead);
+ *data += bytesToRead;
+ m_dataElementBytesIdx += bytesToRead;
+ bytesRead += bytesToRead;
+
+ if (m_dataElementBytesIdx == dataElementSize) {
+ m_dataElementsIdx++;
+ m_dataElementBytesIdx = 0;
+ }
+}
+
+void ResourceRequestBody::readDataElementFile(const base::FilePath &filePath, const qint64 &offset,
+ const qint64 &length, qint64 &bytesRead,
+ const qint64 &maxSize, char **data)
+{
+ QFile file(toQt(filePath.value()));
+ const qint64 realOffset = offset + m_dataElementFileIdx;
+ const std::size_t fileSize = std::min(file.size(), length) - realOffset;
+ const std::size_t bytesToRead = std::min(fileSize, static_cast<std::size_t>(maxSize));
+
+ file.open(QFile::ReadOnly);
+ file.seek(realOffset);
+
+ std::memcpy(*data, file.read(bytesToRead).data(), bytesToRead);
+ *data += bytesToRead;
+ m_dataElementFileIdx += bytesToRead;
+ bytesRead += bytesToRead;
+
+ file.close();
+
+ if (m_dataElementFileIdx == fileSize) {
+ m_dataElementsIdx++;
+ m_dataElementFileIdx = 0;
+ }
+}
+
+mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle>
+ResourceRequestBody::getConsumerHandleFromPipeGetter(
+ mojo::Remote<network::mojom::DataPipeGetter> &pipeGetter)
+{
+ mojo::ScopedHandleBase<mojo::DataPipeProducerHandle> producerHandle;
+ mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> consumerHandle;
+ mojo::CreateDataPipe(nullptr, producerHandle, consumerHandle);
+ base::WeakPtrFactory<ResourceRequestBody> weakPtrFactory{ this };
+ pipeGetter->Read(std::move(producerHandle),
+ base::BindOnce(&ResourceRequestBody::pipeGetterOnReadComplete,
+ weakPtrFactory.GetWeakPtr()));
+
+ return consumerHandle;
+}
+
+void ResourceRequestBody::readDataElementPipe(
+ const mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> &consumerHandle,
+ qint64 &bytesRead, const qint64 &maxSize, char **data)
+{
+ MojoResult result;
+ do {
+ uint32_t bytesToRead = 1;
+ result = consumerHandle->ReadData(*data, &bytesToRead, MOJO_READ_DATA_FLAG_NONE);
+
+ if (result == MOJO_RESULT_OK) {
+ *data += bytesToRead;
+ bytesRead += bytesToRead;
+ } else if (result != MOJO_RESULT_SHOULD_WAIT && result != MOJO_RESULT_FAILED_PRECONDITION) {
+ setErrorString(QString::fromLatin1("Error while reading from data pipe, skipping"
+ "remaining content of data pipe. Mojo error code: ")
+ + QString::number(result));
+ }
+ } while ((result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_OK)
+ && bytesRead < maxSize);
+
+ m_dataElementsIdx++;
+}
+
+void ResourceRequestBody::pipeGetterOnReadComplete(int32_t status, uint64_t size) { }
+
+void ResourceRequestBody::appendFilesForTest(const QString &path)
+{
+ if (!m_requestBody)
+ return;
+
+ base::FilePath filePath = toFilePath(path);
+ m_requestBody->elements_mutable()->push_back(static_cast<network::DataElement>(
+ network::DataElementFile(filePath, 0, 23, base::Time())));
+ m_requestBody->elements_mutable()->push_back(static_cast<network::DataElement>(
+ network::DataElementFile(filePath, 10, 23, base::Time())));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/resource_request_body_qt.h b/src/core/net/resource_request_body_qt.h
new file mode 100644
index 000000000..717885d7d
--- /dev/null
+++ b/src/core/net/resource_request_body_qt.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef RESOURCEREQUESTBODY_QT_H
+#define RESOURCEREQUESTBODY_QT_H
+
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtCore/QIODevice>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+
+namespace network {
+class ResourceRequestBody;
+namespace mojom {
+class DataPipeGetter;
+class ChunkedDataPipeGetter;
+}
+}
+
+namespace base {
+class FilePath;
+}
+
+namespace mojo {
+template<typename T>
+class Remote;
+template<typename T>
+class ScopedHandleBase;
+class DataPipeConsumerHandle;
+}
+
+namespace QtWebEngineCore {
+
+class Q_WEBENGINECORE_EXPORT ResourceRequestBody : public QIODevice
+{
+ Q_OBJECT
+public:
+ explicit ResourceRequestBody(network::ResourceRequestBody *requestBody,
+ QObject *parent = nullptr);
+ ~ResourceRequestBody();
+
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *data, qint64 maxSize) override;
+ bool isSequential() const override;
+
+ void appendFilesForTest(const QString &path);
+
+private:
+ network::ResourceRequestBody *const m_requestBody;
+
+ std::size_t m_dataElementsIdx;
+ std::size_t m_dataElementBytesIdx;
+ std::size_t m_dataElementFileIdx;
+
+ void readDataElementBytes(const std::vector<uint8_t> &dataElement, qint64 &bytesRead,
+ const qint64 &maxSize, char **data);
+ void readDataElementFile(const base::FilePath &filePath, const qint64 &offset,
+ const qint64 &length, qint64 &bytesRead, const qint64 &maxSize,
+ char **data);
+ mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle>
+ getConsumerHandleFromPipeGetter(mojo::Remote<network::mojom::DataPipeGetter> &pipeGetter);
+ void
+ readDataElementPipe(const mojo::ScopedHandleBase<mojo::DataPipeConsumerHandle> &consumerHandle,
+ qint64 &bytesRead, const qint64 &maxSize, char **data);
+ void pipeGetterOnReadComplete(int32_t status, uint64_t size);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // RESOURCEREQUESTBODY_QT_H
diff --git a/src/core/net/ssl_host_state_delegate_qt.cpp b/src/core/net/ssl_host_state_delegate_qt.cpp
index 3390c092a..41967f14e 100644
--- a/src/core/net/ssl_host_state_delegate_qt.cpp
+++ b/src/core/net/ssl_host_state_delegate_qt.cpp
@@ -1,47 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "base/callback.h"
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "ssl_host_state_delegate_qt.h"
-#include "type_conversion.h"
+#include "base/functional/callback.h"
namespace QtWebEngineCore {
@@ -77,7 +39,7 @@ SSLHostStateDelegateQt::SSLHostStateDelegateQt() {}
SSLHostStateDelegateQt::~SSLHostStateDelegateQt() {}
-void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, int error, content::WebContents *)
+void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509Certificate &cert, int error, content::StoragePartition *)
{
m_certPolicyforHost[host].Allow(cert, error);
}
@@ -105,7 +67,7 @@ void SSLHostStateDelegateQt::Clear(base::RepeatingCallback<bool(const std::strin
// prior to this query, otherwise false.
content::SSLHostStateDelegate::CertJudgment SSLHostStateDelegateQt::QueryPolicy(const std::string &host,
const net::X509Certificate &cert,
- int error, content::WebContents *)
+ int error, content::StoragePartition *)
{
return m_certPolicyforHost[host].Check(cert, error) ? SSLHostStateDelegate::ALLOWED : SSLHostStateDelegate::DENIED;
}
@@ -121,6 +83,16 @@ bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host,
return false;
}
+void SSLHostStateDelegateQt::AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents)
+{
+ // Intentional no-op see aw_ssl_host_state_delegate
+}
+
+bool SSLHostStateDelegateQt::IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents)
+{
+ return false;
+}
+
// Revokes all SSL certificate error allow exceptions made by the user for
// |host|.
void SSLHostStateDelegateQt::RevokeUserAllowExceptions(const std::string &host)
@@ -132,12 +104,33 @@ void SSLHostStateDelegateQt::RevokeUserAllowExceptions(const std::string &host)
// |host|. This does not mean that *all* certificate errors are allowed, just
// that there exists an exception. To see if a particular certificate and
// error combination exception is allowed, use QueryPolicy().
-bool SSLHostStateDelegateQt::HasAllowException(const std::string &host, content::WebContents *)
+bool SSLHostStateDelegateQt::HasAllowException(const std::string &host, content::StoragePartition *)
{
auto policy_iterator = m_certPolicyforHost.find(host);
return policy_iterator != m_certPolicyforHost.end() &&
policy_iterator->second.HasAllowException();
}
+bool SSLHostStateDelegateQt::HasAllowExceptionForAnyHost(content::StoragePartition *storage_partition)
+{
+ for (auto const &it : m_certPolicyforHost) {
+ if (it.second.HasAllowException()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void SSLHostStateDelegateQt::SetHttpsEnforcementForHost(const std::string &host, bool enforce,
+ content::StoragePartition *storage_partition)
+{
+ // Intentional no-op see aw_ssl_host_state_delegate
+}
+
+bool SSLHostStateDelegateQt::IsHttpsEnforcedForHost(const std::string &host, content::StoragePartition *storage_partition)
+{
+ // Intentional no-op
+ return false;
+}
} // namespace QtWebEngineCore
diff --git a/src/core/net/ssl_host_state_delegate_qt.h b/src/core/net/ssl_host_state_delegate_qt.h
index 6b407353a..0b3d7974c 100644
--- a/src/core/net/ssl_host_state_delegate_qt.h
+++ b/src/core/net/ssl_host_state_delegate_qt.h
@@ -1,47 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef SSL_HOST_STATE_DELEGATE_QT_H
#define SSL_HOST_STATE_DELEGATE_QT_H
#include "content/public/browser/ssl_host_state_delegate.h"
-#include "profile_adapter.h"
+
+#include <map>
+#include <string>
namespace QtWebEngineCore {
@@ -66,13 +32,18 @@ public:
~SSLHostStateDelegateQt();
// content::SSLHostStateDelegate implementation:
- void AllowCert(const std::string &, const net::X509Certificate &cert, int error, content::WebContents *web_contents) override;
+ void AllowCert(const std::string &, const net::X509Certificate &cert, int error, content::StoragePartition *storage_partition) override;
void Clear(base::RepeatingCallback<bool(const std::string&)> host_filter) override;
- CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert, int error, content::WebContents *web_contents) override;
+ CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert, int error, content::StoragePartition *web_contents) override;
void HostRanInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
bool DidHostRunInsecureContent(const std::string &host, int child_id, InsecureContentType content_type) override;
+ void AllowHttpForHost(const std::string &host, content::StoragePartition *web_contents) override;
+ bool IsHttpAllowedForHost(const std::string &host, content::StoragePartition *web_contents) override;
+ void SetHttpsEnforcementForHost(const std::string &host, bool enforce, content::StoragePartition *storage_partition) override;
+ bool IsHttpsEnforcedForHost(const std::string &host, content::StoragePartition *web_contents) override;
void RevokeUserAllowExceptions(const std::string &host) override;
- bool HasAllowException(const std::string &host, content::WebContents *web_contents) override;
+ bool HasAllowException(const std::string &host, content::StoragePartition *web_contents) override;
+ bool HasAllowExceptionForAnyHost(content::StoragePartition *storage_partition) override;
private:
std::map<std::string, CertPolicy> m_certPolicyforHost;
diff --git a/src/core/net/system_network_context_manager.cpp b/src/core/net/system_network_context_manager.cpp
index 46e678110..439d1066c 100644
--- a/src/core/net/system_network_context_manager.cpp
+++ b/src/core/net/system_network_context_manager.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/browser/net/system_network_context_manager.cc:
// Copyright 2017 The Chromium Authors. All rights reserved.
@@ -44,34 +8,47 @@
#include "net/system_network_context_manager.h"
-#include "base/bind.h"
#include "base/command_line.h"
+#include "base/functional/bind.h"
+#include "base/strings/string_split.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "chrome/common/chrome_switches.h"
#include "components/certificate_transparency/ct_known_logs.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_switches.h"
+#include "crypto/sha2.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "net/base/port_util.h"
#include "net/net_buildflags.h"
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/cross_thread_pending_shared_url_loader_factory.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/mojom/host_resolver.mojom.h"
-#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "services/network/public/mojom/cert_verifier_service.mojom.h"
+#include "services/network/public/mojom/network_context.mojom.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
+#include "api/qwebengineglobalsettings.h"
+#include "api/qwebengineglobalsettings_p.h"
-namespace {
+#if BUILDFLAG(IS_WIN)
+#include "chrome/browser/net/chrome_mojo_proxy_resolver_win.h"
+#include "components/os_crypt/sync/os_crypt.h"
+#include "content/public/browser/network_service_util.h"
+#endif
-// The global instance of the SystemNetworkContextmanager.
-SystemNetworkContextManager *g_system_network_context_manager = nullptr;
+ASSERT_ENUMS_MATCH(net::SecureDnsMode::kSecure, QWebEngineGlobalSettings::SecureDnsMode::SecureOnly)
+ASSERT_ENUMS_MATCH(net::SecureDnsMode::kAutomatic,
+ QWebEngineGlobalSettings::SecureDnsMode::SecureWithFallback)
+ASSERT_ENUMS_MATCH(net::SecureDnsMode::kOff, QWebEngineGlobalSettings::SecureDnsMode::SystemOnly)
+
+namespace {
network::mojom::HttpAuthStaticParamsPtr CreateHttpAuthStaticParams()
{
- network::mojom::HttpAuthStaticParamsPtr auth_static_params = network::mojom::HttpAuthStaticParams::New();
-
- auth_static_params->supported_schemes = { "basic", "digest", "ntlm", "negotiate" };
+ network::mojom::HttpAuthStaticParamsPtr auth_static_params =
+ network::mojom::HttpAuthStaticParams::New();
return auth_static_params;
}
@@ -80,6 +57,8 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams()
{
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params = network::mojom::HttpAuthDynamicParams::New();
+ auth_dynamic_params->allowed_schemes = { "basic", "digest", "ntlm", "negotiate" };
+
auto *command_line = base::CommandLine::ForCurrentProcess();
auth_dynamic_params->server_allowlist = command_line->GetSwitchValueASCII(switches::kAuthServerAllowlist);
// auth_dynamic_params->delegate_allowlist = command_line->GetSwitchValueASCII(switches::kAuthNegotiateDelegateWhitelist);
@@ -90,6 +69,11 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams()
} // namespace
+namespace QtWebEngineCore {
+
+// The global instance of the SystemNetworkContextmanager.
+SystemNetworkContextManager *g_system_network_context_manager = nullptr;
+
// SharedURLLoaderFactory backed by a SystemNetworkContextManager and its
// network context. Transparently handles crashes.
class SystemNetworkContextManager::URLLoaderFactoryForSystem : public network::SharedURLLoaderFactory
@@ -103,7 +87,6 @@ public:
// mojom::URLLoaderFactory implementation:
void CreateLoaderAndStart(mojo::PendingReceiver<network::mojom::URLLoader> receiver,
- int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest &url_request,
@@ -114,7 +97,7 @@ public:
if (!manager_)
return;
manager_->GetURLLoaderFactory()->CreateLoaderAndStart(
- std::move(receiver), routing_id, request_id, options, url_request,
+ std::move(receiver), request_id, options, url_request,
std::move(client), traffic_annotation);
}
@@ -140,8 +123,6 @@ private:
SEQUENCE_CHECKER(sequence_checker_);
SystemNetworkContextManager *manager_;
-
- DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryForSystem);
};
network::mojom::NetworkContext *SystemNetworkContextManager::GetContext()
@@ -220,18 +201,76 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(network::mojom::Networ
network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
+#if BUILDFLAG(IS_WIN)
+ if (content::IsOutOfProcessNetworkService())
+ network_service->SetEncryptionKey(OSCrypt::GetRawEncryptionKey());
+#endif
+
+ // Configure the Certificate Transparency logs.
+ std::vector<std::pair<std::string, base::Time>> disqualified_logs =
+ certificate_transparency::GetDisqualifiedLogs();
+ std::vector<network::mojom::CTLogInfoPtr> log_list_mojo;
+ for (const auto &ct_log : certificate_transparency::GetKnownLogs()) {
+ network::mojom::CTLogInfoPtr log_info = network::mojom::CTLogInfo::New();
+ log_info->public_key = std::string(ct_log.log_key, ct_log.log_key_length);
+ log_info->id = crypto::SHA256HashString(log_info->public_key);
+ log_info->name = ct_log.log_name;
+ log_info->current_operator = ct_log.current_operator;
+
+ auto it = std::lower_bound(
+ std::begin(disqualified_logs), std::end(disqualified_logs), log_info->id,
+ [](const auto& disqualified_log, const std::string& log_id) {
+ return disqualified_log.first < log_id;
+ });
+ if (it != std::end(disqualified_logs) && it->first == log_info->id)
+ log_info->disqualified_at = it->second;
+
+ for (size_t i = 0; i < ct_log.previous_operators_length; i++) {
+ const auto& op = ct_log.previous_operators[i];
+ network::mojom::PreviousOperatorEntryPtr previous_operator =
+ network::mojom::PreviousOperatorEntry::New();
+ previous_operator->name = op.name;
+ previous_operator->end_time = op.end_time;
+ log_info->previous_operators.push_back(std::move(previous_operator));
+ }
+
+ log_list_mojo.push_back(std::move(log_info));
+ }
+ network_service->UpdateCtLogList(
+ std::move(log_list_mojo),
+ certificate_transparency::GetLogListTimestamp(),
+ base::DoNothing());
+
// The system NetworkContext is created first
network_service_network_context_.reset();
network_service->CreateNetworkContext(
network_service_network_context_.BindNewPipeAndPassReceiver(),
CreateNetworkContextParams());
- // Configure the stub resolver. This must be done after the system
- // NetworkContext is created, but before anything has the chance to use it.
- // bool stub_resolver_enabled;
- // base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> dns_over_https_servers;
- // GetStubResolverConfig(local_state_, &stub_resolver_enabled, &dns_over_https_servers);
- // content::GetNetworkService()->ConfigureStubHostResolver(stub_resolver_enabled, std::move(dns_over_https_servers));
+ // Handle --explicitly-allowed-ports
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kExplicitlyAllowedPorts)) {
+ std::vector<uint16_t> explicitly_allowed_network_ports;
+ std::string switch_value =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kExplicitlyAllowedPorts);
+ const auto split = base::SplitStringPiece(switch_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto &piece : split) {
+ int port;
+ if (!base::StringToInt(piece, &port))
+ continue;
+ if (!net::IsPortValid(port))
+ continue;
+ explicitly_allowed_network_ports.push_back(static_cast<uint16_t>(port));
+ }
+
+ network_service->SetExplicitlyAllowedPorts(explicitly_allowed_network_ports);
+ }
+
+ // The network service is a singleton that can be reinstantiated for different reasons,
+ // e.g., when the network service crashes. Therefore, we configure the stub host
+ // resolver of the network service here, each time it is instantiated, with our global
+ // DNS-Over-HTTPS settings. This ensures that the global settings don't get lost
+ // on reinstantiation and are in effect upon initial instantiation.
+ QWebEngineGlobalSettingsPrivate::instance()->configureStubHostResolver();
}
void SystemNetworkContextManager::AddSSLConfigToNetworkContextParams(network::mojom::NetworkContextParams *network_context_params)
@@ -249,23 +288,28 @@ void SystemNetworkContextManager::ConfigureDefaultNetworkContextParams(network::
// respect prefs::kEnableReferrers from the appropriate pref store.
network_context_params->enable_referrers = false;
- network_context_params->proxy_resolver_factory = ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver();
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (!command_line.HasSwitch(switches::kWinHttpProxyResolver)) {
+ if (command_line.HasSwitch(switches::kSingleProcess)) {
+ LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
+ } else {
+ network_context_params->proxy_resolver_factory =
+ ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver();
+ }
+ }
+#if BUILDFLAG(IS_WIN)
+ if (command_line.HasSwitch(switches::kUseSystemProxyResolver)) {
+ network_context_params->windows_system_proxy_resolver =
+ ChromeMojoProxyResolverWin::CreateWithSelfOwnedReceiver();
+ }
+#endif
// Use the SystemNetworkContextManager to populate and update SSL
// configuration. The SystemNetworkContextManager is owned by the
// BrowserProcess itself, so will only be destroyed on shutdown, at which
// point, all NetworkContexts will be destroyed as well.
AddSSLConfigToNetworkContextParams(network_context_params);
-
- // CT is only enabled on Desktop platforms for now.
- network_context_params->enforce_chrome_ct_policy = true;
- for (const auto &ct_log : certificate_transparency::GetKnownLogs()) {
- // TODO(rsleevi): https://crbug.com/702062 - Remove this duplication.
- network::mojom::CTLogInfoPtr log_info = network::mojom::CTLogInfo::New();
- log_info->public_key = std::string(ct_log.log_key, ct_log.log_key_length);
- log_info->name = ct_log.log_name;
- network_context_params->ct_logs.push_back(std::move(log_info));
- }
}
network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetworkContextParams()
@@ -276,20 +320,40 @@ network::mojom::NetworkContextParamsPtr SystemNetworkContextManager::CreateNetwo
cert_verifier_creation_params = cert_verifier::mojom::CertVerifierCreationParams::New();
ConfigureDefaultNetworkContextParams(network_context_params.get(), cert_verifier_creation_params.get());
- network_context_params->context_name = std::string("system");
-
network_context_params->enable_referrers = false;
network_context_params->http_cache_enabled = false;
- // These are needed for PAC scripts that use FTP URLs.
-#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
- network_context_params->enable_ftp_url_support = true;
-#endif
-
proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get());
network_context_params->cert_verifier_params =
content::GetCertVerifierParams(std::move(cert_verifier_creation_params));
return network_context_params;
}
+
+bool isValidTemplates(std::string templates)
+{
+ absl::optional<net::DnsOverHttpsConfig> dnsOverHttpsConfig =
+ net::DnsOverHttpsConfig::FromString(templates);
+ return dnsOverHttpsConfig.has_value();
+}
+
+
+void configureStubHostResolver(QWebEngineGlobalSettings::SecureDnsMode dnsMode,
+ std::string dnsOverHttpsTemplates, bool insecureDnsClientEnabled,
+ bool additionalInsecureDnsTypesEnabled)
+{
+ if (content::IsNetworkServiceCreated()) {
+ network::mojom::NetworkService *networkService = content::GetNetworkService();
+ if (networkService) {
+ absl::optional<net::DnsOverHttpsConfig> dohConfig = dnsOverHttpsTemplates.empty()
+ ? net::DnsOverHttpsConfig()
+ : net::DnsOverHttpsConfig::FromString(dnsOverHttpsTemplates);
+ networkService->ConfigureStubHostResolver(insecureDnsClientEnabled,
+ net::SecureDnsMode(dnsMode), *dohConfig,
+ additionalInsecureDnsTypesEnabled);
+ }
+ }
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/net/system_network_context_manager.h b/src/core/net/system_network_context_manager.h
index a234ead94..d56bdab78 100644
--- a/src/core/net/system_network_context_manager.h
+++ b/src/core/net/system_network_context_manager.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/browser/net/system_network_context_manager.h:
// Copyright 2017 The Chromium Authors. All rights reserved.
@@ -47,11 +11,9 @@
#include <memory>
-#include "base/macros.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom-forward.h"
-#include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
-
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "net/proxy_config_monitor.h"
namespace cert_verifier {
@@ -66,6 +28,8 @@ class URLLoaderFactory;
class SharedURLLoaderFactory;
} // namespace network
+namespace QtWebEngineCore {
+
// Responsible for creating and managing access to the system NetworkContext.
// Lives on the UI thread. The NetworkContext this owns is intended for requests
// not associated with a profile. It stores no data on disk, and has no HTTP
@@ -150,8 +114,8 @@ private:
mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_;
ProxyConfigMonitor proxy_config_monitor_;
-
- DISALLOW_COPY_AND_ASSIGN(SystemNetworkContextManager);
};
+} // namespace QtWebEngineCore
+
#endif // SYSTEM_NETWORK_CONTEXT_MANAGER_H_
diff --git a/src/core/net/url_request_custom_job_delegate.cpp b/src/core/net/url_request_custom_job_delegate.cpp
index ff307bede..c877de669 100644
--- a/src/core/net/url_request_custom_job_delegate.cpp
+++ b/src/core/net/url_request_custom_job_delegate.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "url_request_custom_job_delegate.h"
#include "url_request_custom_job_proxy.h"
-#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
@@ -51,16 +14,16 @@
namespace QtWebEngineCore {
-URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
- const QUrl &url,
- const QByteArray &method,
- const QUrl &initiatorOrigin,
- const QMap<QByteArray, QByteArray> &headers)
- : m_proxy(proxy),
- m_request(url),
- m_method(method),
- m_initiatorOrigin(initiatorOrigin),
- m_requestHeaders(headers)
+URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(
+ URLRequestCustomJobProxy *proxy, const QUrl &url, const QByteArray &method,
+ const QUrl &initiatorOrigin, const QMap<QByteArray, QByteArray> &headers,
+ network::ResourceRequestBody *requestBody)
+ : m_proxy(proxy)
+ , m_request(url)
+ , m_method(method)
+ , m_initiatorOrigin(initiatorOrigin)
+ , m_requestHeaders(headers)
+ , m_resourceRequestBody(ResourceRequestBody(requestBody))
{
}
@@ -88,13 +51,25 @@ QMap<QByteArray, QByteArray> URLRequestCustomJobDelegate::requestHeaders() const
return m_requestHeaders;
}
+QIODevice *URLRequestCustomJobDelegate::requestBody()
+{
+ return &m_resourceRequestBody;
+}
+
+void URLRequestCustomJobDelegate::setAdditionalResponseHeaders(
+ const QMultiMap<QByteArray, QByteArray> &additionalResponseHeaders)
+{
+ m_additionalResponseHeaders = additionalResponseHeaders;
+}
+
void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device)
{
if (device)
QObject::connect(device, &QIODevice::readyRead, this, &URLRequestCustomJobDelegate::slotReadyRead);
m_proxy->m_ioTaskRunner->PostTask(FROM_HERE,
- base::BindOnce(&URLRequestCustomJobProxy::reply,
- m_proxy, contentType.toStdString(),device));
+ base::BindOnce(&URLRequestCustomJobProxy::reply, m_proxy,
+ contentType.toStdString(), device,
+ std::move(m_additionalResponseHeaders)));
}
void URLRequestCustomJobDelegate::slotReadyRead()
diff --git a/src/core/net/url_request_custom_job_delegate.h b/src/core/net/url_request_custom_job_delegate.h
index 93ae39e84..63db46464 100644
--- a/src/core/net/url_request_custom_job_delegate.h
+++ b/src/core/net/url_request_custom_job_delegate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,6 +17,7 @@
#include "base/memory/ref_counted.h"
#include "qtwebenginecoreglobal_p.h"
+#include "resource_request_body_qt.h"
#include <QMap>
#include <QObject>
@@ -60,11 +25,15 @@
QT_FORWARD_DECLARE_CLASS(QIODevice)
+namespace network {
+class ResourceRequestBody;
+}
+
namespace QtWebEngineCore {
class URLRequestCustomJobProxy;
-class Q_WEBENGINECORE_PRIVATE_EXPORT URLRequestCustomJobDelegate : public QObject
+class Q_WEBENGINECORE_EXPORT URLRequestCustomJobDelegate : public QObject
{
Q_OBJECT
public:
@@ -83,7 +52,10 @@ public:
QByteArray method() const;
QUrl initiator() const;
QMap<QByteArray, QByteArray> requestHeaders() const;
+ QIODevice *requestBody();
+ void
+ setAdditionalResponseHeaders(const QMultiMap<QByteArray, QByteArray> &additionalResponseHeaders);
void reply(const QByteArray &contentType, QIODevice *device);
void redirect(const QUrl &url);
void abort();
@@ -93,11 +65,10 @@ private Q_SLOTS:
void slotReadyRead();
private:
- URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy,
- const QUrl &url,
- const QByteArray &method,
- const QUrl &initiatorOrigin,
- const QMap<QByteArray, QByteArray> &requestHeaders);
+ URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy, const QUrl &url,
+ const QByteArray &method, const QUrl &initiatorOrigin,
+ const QMap<QByteArray, QByteArray> &requestHeaders,
+ network::ResourceRequestBody *requestBody);
friend class URLRequestCustomJobProxy;
scoped_refptr<URLRequestCustomJobProxy> m_proxy;
@@ -105,6 +76,8 @@ private:
QByteArray m_method;
QUrl m_initiatorOrigin;
const QMap<QByteArray, QByteArray> m_requestHeaders;
+ QMultiMap<QByteArray, QByteArray> m_additionalResponseHeaders;
+ ResourceRequestBody m_resourceRequestBody;
};
} // namespace
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index b57583341..0f41a3670 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -1,47 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "url_request_custom_job_proxy.h"
#include "url_request_custom_job_delegate.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_errors.h"
+#include "services/network/public/cpp/resource_request_body.h"
#include "api/qwebengineurlrequestjob.h"
#include "profile_adapter.h"
@@ -76,23 +41,26 @@ void URLRequestCustomJobProxy::release()
}
}
-// Fix me: this is never used
-/*
-void URLRequestCustomJobProxy::setReplyCharset(const std::string &charset)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- if (!m_job)
- return;
- m_job->m_charset = charset;
-}
-*/
-void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device)
+void URLRequestCustomJobProxy::reply(std::string contentType, QIODevice *device,
+ QMultiMap<QByteArray, QByteArray> additionalResponseHeaders)
{
if (!m_client)
return;
DCHECK (!m_ioTaskRunner || m_ioTaskRunner->RunsTasksInCurrentSequence());
- m_client->m_mimeType = mimeType;
+ QByteArray qcontentType = QByteArray::fromStdString(contentType).toLower();
+ const int sidx = qcontentType.indexOf(';');
+ if (sidx > 0) {
+ const int cidx = qcontentType.indexOf("charset=", sidx);
+ if (cidx > 0) {
+ m_client->m_charset = qcontentType.mid(cidx + 8).trimmed().toStdString();
+ qcontentType = qcontentType.first(sidx);
+ } else {
+ qWarning() << "QWebEngineUrlRequestJob::reply(): Unrecognized content-type format with ';'" << qcontentType;
+ }
+ }
+ m_client->m_mimeType = qcontentType.trimmed().toStdString();
m_client->m_device = device;
+ m_client->m_additionalResponseHeaders = std::move(additionalResponseHeaders);
if (m_client->m_device && !m_client->m_device->isReadable())
m_client->m_device->open(QIODevice::ReadOnly);
@@ -158,8 +126,9 @@ void URLRequestCustomJobProxy::readyRead()
}
void URLRequestCustomJobProxy::initialize(GURL url, std::string method,
- base::Optional<url::Origin> initiator,
- std::map<std::string, std::string> headers)
+ absl::optional<url::Origin> initiator,
+ std::map<std::string, std::string> headers,
+ scoped_refptr<network::ResourceRequestBody> requestBody)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Q_ASSERT(!m_delegate);
@@ -177,10 +146,9 @@ void URLRequestCustomJobProxy::initialize(GURL url, std::string method,
qHeaders.insert(toQByteArray(it->first), toQByteArray(it->second));
if (schemeHandler) {
- m_delegate = new URLRequestCustomJobDelegate(this, toQt(url),
- QByteArray::fromStdString(method),
- initiatorOrigin,
- qHeaders);
+ m_delegate =
+ new URLRequestCustomJobDelegate(this, toQt(url), QByteArray::fromStdString(method),
+ initiatorOrigin, qHeaders, requestBody.get());
QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate);
schemeHandler->requestStarted(requestJob);
}
diff --git a/src/core/net/url_request_custom_job_proxy.h b/src/core/net/url_request_custom_job_proxy.h
index b14322f91..65c919ed0 100644
--- a/src/core/net/url_request_custom_job_proxy.h
+++ b/src/core/net/url_request_custom_job_proxy.h
@@ -1,54 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef URL_REQUEST_CUSTOM_JOB_PROXY_H_
#define URL_REQUEST_CUSTOM_JOB_PROXY_H_
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/sequenced_task_runner.h"
+#include "base/task/sequenced_task_runner.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "url/origin.h"
#include <QtCore/QPointer>
+#include <QMap>
+#include <QByteArray>
QT_FORWARD_DECLARE_CLASS(QIODevice)
+namespace network {
+class ResourceRequestBody;
+}
+
namespace QtWebEngineCore {
class URLRequestCustomJob;
@@ -65,6 +34,7 @@ public:
public:
std::string m_mimeType;
std::string m_charset;
+ QMultiMap<QByteArray, QByteArray> m_additionalResponseHeaders;
GURL m_redirect;
QIODevice *m_device;
int64_t m_firstBytePosition;
@@ -85,12 +55,15 @@ public:
// Called from URLRequestCustomJobDelegate via post:
//void setReplyCharset(const std::string &);
- void reply(std::string mimeType, QIODevice *device);
+ void reply(std::string mimeType, QIODevice *device,
+ QMultiMap<QByteArray, QByteArray> additionalResponseHeaders);
void redirect(GURL url);
void abort();
void fail(int error);
void release();
- void initialize(GURL url, std::string method, base::Optional<url::Origin> initiatorOrigin, std::map<std::string, std::string> headers);
+ void initialize(GURL url, std::string method, absl::optional<url::Origin> initiatorOrigin,
+ std::map<std::string, std::string> headers,
+ scoped_refptr<network::ResourceRequestBody> requestBody);
void readyRead();
// IO thread owned:
diff --git a/src/core/net/version_ui_qt.cpp b/src/core/net/version_ui_qt.cpp
new file mode 100644
index 000000000..61a89596a
--- /dev/null
+++ b/src/core/net/version_ui_qt.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "version_ui_qt.h"
+#include "api/qtwebenginecoreglobal.h"
+#include "build/build_config.h"
+#include "base/command_line.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/browser/profiles/profile.h"
+#include "qtwebengine/grit/qt_webengine_resources.h"
+#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
+
+namespace {
+const char kQtWebEngineVersion[] = "qtwebengine_version";
+const char kQtWebEngineChromiumVersion[] = "qtwebengine_chromium_version";
+const char kQtWebEngineChromiumSecurityPatchVersion[] =
+ "qtwebengine_chromium_security_patch_version";
+const char kCommandLine[] = "command_line";
+const char kQtVersionCSS[] = "qt_version.css";
+const char kQtLogo[] = "images/qt.png";
+const char kQtWebEngineLogo[] = "images/qtwebengine.png";
+}
+
+VersionUIQt::VersionUIQt(content::WebUI *web_ui) : content::WebUIController(web_ui)
+{
+
+ Profile *profile = Profile::FromWebUI(web_ui);
+ content::WebUIDataSource *html_source =
+ content::WebUIDataSource::CreateAndAdd(profile, chrome::kChromeUIVersionQtHost);
+ html_source->OverrideContentSecurityPolicy(
+ network::mojom::CSPDirectiveName::ScriptSrc,
+ "script-src chrome://resources 'self' 'unsafe-inline';");
+ html_source->SetDefaultResource(IDR_VERSION_UI_QT_HTML);
+ html_source->AddResourcePath(kQtVersionCSS, IDR_VERSION_UI_QT_CSS);
+ html_source->AddResourcePath(kQtLogo, IDR_QT_LOGO);
+ html_source->AddResourcePath(kQtWebEngineLogo, IDR_QTWEBENGINE_LOGO);
+
+ html_source->AddString(kQtWebEngineVersion, qWebEngineVersion());
+ html_source->AddString(kQtWebEngineChromiumVersion, qWebEngineChromiumVersion());
+ html_source->AddString(kQtWebEngineChromiumSecurityPatchVersion,
+ qWebEngineChromiumSecurityPatchVersion());
+#if BUILDFLAG(IS_WIN)
+ html_source->AddString(
+ kCommandLine,
+ base::AsString16(base::CommandLine::ForCurrentProcess()->GetCommandLineString()));
+#else
+ std::string command_line;
+ typedef std::vector<std::string> ArgvList;
+ const ArgvList &argv = base::CommandLine::ForCurrentProcess()->argv();
+ for (auto iter = argv.begin(); iter != argv.end(); iter++)
+ command_line += " " + *iter;
+ html_source->AddString(kCommandLine, command_line);
+#endif
+}
+
+VersionUIQt::~VersionUIQt() { }
diff --git a/src/core/net/version_ui_qt.h b/src/core/net/version_ui_qt.h
new file mode 100644
index 000000000..1fe8ef9e0
--- /dev/null
+++ b/src/core/net/version_ui_qt.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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.
+//
+
+#ifndef VERSION_UI_QT_H_
+#define VERSION_UI_QT_H_
+
+#include "build/build_config.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+class VersionUIQt : public content::WebUIController
+{
+public:
+ explicit VersionUIQt(content::WebUI *web_ui);
+ ~VersionUIQt() override;
+
+ VersionUIQt(const VersionUIQt &) = delete;
+ VersionUIQt &operator=(const VersionUIQt &) = delete;
+};
+
+#endif // VERSION_UI_QT_H
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index 4c39ac030..ed35a3e36 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Based on chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -45,26 +9,25 @@
#include "webui_controller_factory_qt.h"
#include "build_config_qt.h"
-
-#include "base/bind.h"
+#include "devtools_frontend_qt.h"
+#include "base/functional/bind.h"
#include "build/build_config.h"
#include "chrome/browser/accessibility/accessibility_ui.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/device_log_ui.h"
#include "chrome/browser/ui/webui/devtools_ui.h"
#include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
-#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
#include "chrome/browser/ui/webui/user_actions/user_actions_ui.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/url_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "media/media_buildflags.h"
-#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "url/gurl.h"
+#include "version_ui_qt.h"
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
#include "chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h"
#endif
@@ -123,22 +86,19 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
// This will get called a lot to check all URLs, so do a quick check of other
// schemes to filter out most URLs.
if (!content::HasWebUIScheme(url))
- return NULL;
+ return nullptr;
// We must compare hosts only since some of the Web UIs append extra stuff
// after the host name.
- if (url.host() == chrome::kChromeUINetInternalsHost)
+ if (url.host_piece() == chrome::kChromeUINetInternalsHost)
return &NewWebUI<NetInternalsUI>;
- if (url.host() == chrome::kChromeUIQuotaInternalsHost)
- return &NewWebUI<QuotaInternalsUI>;
-
if (url.SchemeIs(content::kChromeDevToolsScheme)) {
- // if (!DevToolsUIBindings::IsValidFrontendURL(url))
- // return nullptr;
+ if (!QtWebEngineCore::DevToolsFrontendQt::IsValidFrontendURL(url))
+ return nullptr;
return &NewWebUI<DevToolsUI>;
}
- if (url.host() == chrome::kChromeUIAccessibilityHost)
+ if (url.host_piece() == chrome::kChromeUIAccessibilityHost)
return &NewWebUI<AccessibilityUI>;
if (url.host_piece() == chrome::kChromeUIUserActionsHost)
@@ -147,6 +107,9 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
if (url.host_piece() == chrome::kChromeUIDeviceLogHost)
return &NewWebUI<chromeos::DeviceLogUI>;
+ if (url.host_piece() == chrome::kChromeUIVersionQtHost)
+ return &NewWebUI<VersionUIQt>;
+
// if (url.host_piece() == chrome::kChromeUIInspectHost)
// return &NewWebUI<InspectUI>;
//
@@ -168,7 +131,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
if (url.host_piece() == chrome::kChromeUIWebRtcLogsHost)
return &NewWebUI<WebRtcLogsUI>;
#endif
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
if (url.host_piece() == chrome::kChromeUISandboxHost)
return &NewWebUI<SandboxInternalsUI>;
#endif
diff --git a/src/core/net/webui_controller_factory_qt.h b/src/core/net/webui_controller_factory_qt.h
index b5f01a504..22219dd5a 100644
--- a/src/core/net/webui_controller_factory_qt.h
+++ b/src/core/net/webui_controller_factory_qt.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_UI_CONTROLLER_FACTORY_QT_H_
#define WEB_UI_CONTROLLER_FACTORY_QT_H_
-#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller_factory.h"
@@ -62,8 +25,6 @@ protected:
private:
friend struct base::DefaultSingletonTraits<WebUIControllerFactoryQt>;
-
- DISALLOW_COPY_AND_ASSIGN(WebUIControllerFactoryQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/ozone/BUILD.gn b/src/core/ozone/BUILD.gn
index e0f9b8a41..aa7b282ae 100644
--- a/src/core/ozone/BUILD.gn
+++ b/src/core/ozone/BUILD.gn
@@ -5,8 +5,8 @@ import("//ui/base/ui_features.gni")
import("//build/config/linux/pkg_config.gni")
if (use_xkbcommon) {
- pkg_config("xkbcommon") {
- packages = [ "xkbcommon" ]
+ pkg_config("xkb") {
+ packages = [ "xkbcommon", "xkbfile" ]
}
}
@@ -21,6 +21,7 @@ source_set("qt") {
deps = [
"//base",
+ "//ui/base:buildflags",
"//ui/ozone:ozone_base",
"//ui/ozone/common",
]
@@ -28,8 +29,7 @@ source_set("qt") {
defines = [ "OZONE_IMPLEMENTATION" ]
libs = []
if (use_xkbcommon) {
- configs += [ ":xkbcommon" ]
- libs += [ "xkbfile" ]
+ configs += [ ":xkb" ]
}
if (ozone_platform_x11) {
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index 8f9093a4e..0042f2bce 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "gl_context_qt.h"
@@ -44,10 +8,21 @@
#include <QThread>
#include <QtGui/private/qtgui-config_p.h>
#include <qpa/qplatformnativeinterface.h>
-#include "ui/gl/gl_context_egl.h"
+
#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface.h"
+
+#if defined(USE_OZONE)
+#include "ui/gl/egl_util.h"
-#if defined(OS_WIN)
+#include <QOpenGLFunctions>
+#include <QOffscreenSurface>
+
+#include <vector>
+#endif
+
+#if BUILDFLAG(IS_WIN)
+#include "ui/gl/gl_context_egl.h"
#include "ui/gl/gl_context_wgl.h"
#endif
@@ -63,7 +38,8 @@ inline void *resourceForContext(const QByteArray &resource)
#if QT_CONFIG(opengl)
QOpenGLContext *shareContext = qt_gl_global_share_context();
if (!shareContext) {
- qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to call QtWebEngineCore::initialize() in your main() function.");
+ qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to "
+ "call QtWebEngineQuick::initialize() in your main() function.");
}
return qApp->platformNativeInterface()->nativeResourceForContext(resource, shareContext);
#else
@@ -130,7 +106,7 @@ void* GLContextHelper::getGlXConfig()
void* GLContextHelper::getEGLDisplay()
{
-#ifdef Q_OS_WIN
+#if BUILDFLAG(IS_WIN)
// Windows QPA plugin does not implement resourceForIntegration for "egldisplay".
// Use resourceForContext instead.
return resourceForContext(QByteArrayLiteral("egldisplay"));
@@ -199,33 +175,228 @@ bool GLContextHelper::isCreateContextRobustnessSupported()
return contextHelper->m_robustness;
}
+#if QT_CONFIG(opengl) && defined(USE_OZONE)
+class ScopedGLContext
+{
+public:
+ ScopedGLContext()
+ : m_context(new QOpenGLContext())
+ , m_previousContext(gl::GLContext::GetCurrent())
+ , m_previousSurface(gl::GLSurface::GetCurrent())
+ {
+ if (!m_context->create()) {
+ qWarning("Failed to create OpenGL context.");
+ return;
+ }
+
+ QOffscreenSurface *surface = new QOffscreenSurface(m_context->screen(), m_context.get());
+ surface->create();
+ Q_ASSERT(surface->isValid());
+
+ if (!m_context->makeCurrent(surface)) {
+ qWarning("Failed to make OpenGL context current.");
+ return;
+ }
+ }
+
+ ~ScopedGLContext()
+ {
+ if (!m_textures.empty()) {
+ auto glFun = m_context->functions();
+ glFun->glDeleteTextures(m_textures.size(), m_textures.data());
+ }
+
+ if (m_previousContext)
+ m_previousContext->MakeCurrent(m_previousSurface);
+ }
+
+ bool isValid() const { return m_context->isValid() && (m_context->surface() != nullptr); }
+
+ EGLDisplay eglDisplay() const
+ {
+ QNativeInterface::QEGLContext *nativeInterface =
+ m_context->nativeInterface<QNativeInterface::QEGLContext>();
+ return nativeInterface->display();
+ }
+
+ EGLContext eglContext() const
+ {
+ QNativeInterface::QEGLContext *nativeInterface =
+ m_context->nativeInterface<QNativeInterface::QEGLContext>();
+ return nativeInterface->nativeContext();
+ }
+
+ uint createTexture(int width, int height)
+ {
+ auto glFun = m_context->functions();
+
+ uint glTexture;
+ glFun->glGenTextures(1, &glTexture);
+ glFun->glBindTexture(GL_TEXTURE_2D, glTexture);
+ glFun->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ NULL);
+ glFun->glBindTexture(GL_TEXTURE_2D, 0);
+
+ m_textures.push_back(glTexture);
+ return glTexture;
+ }
+
+private:
+ QScopedPointer<QOpenGLContext> m_context;
+ gl::GLContext *m_previousContext;
+ gl::GLSurface *m_previousSurface;
+ std::vector<uint> m_textures;
+};
+
+EGLHelper::EGLFunctions::EGLFunctions()
+{
+ const static auto getProcAddress =
+ reinterpret_cast<gl::GLGetProcAddressProc>(GLContextHelper::getEglGetProcAddress());
+
+ eglCreateImage = reinterpret_cast<PFNEGLCREATEIMAGEPROC>(getProcAddress("eglCreateImage"));
+ eglDestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(getProcAddress("eglDestroyImage"));
+ eglGetError = reinterpret_cast<PFNEGLGETERRORPROC>(getProcAddress("eglGetError"));
+ eglExportDMABUFImageMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEMESAPROC>(
+ getProcAddress("eglExportDMABUFImageMESA"));
+ eglExportDMABUFImageQueryMESA = reinterpret_cast<PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC>(
+ getProcAddress("eglExportDMABUFImageQueryMESA"));
+ eglQueryString = reinterpret_cast<PFNEGLQUERYSTRINGPROC>(getProcAddress("eglQueryString"));
+}
+
+EGLHelper *EGLHelper::instance()
+{
+ static EGLHelper eglHelper;
+ return &eglHelper;
+}
+
+EGLHelper::EGLHelper() : m_functions(new EGLHelper::EGLFunctions())
+{
+ const char *extensions = m_functions->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (!extensions) {
+ qWarning("EGL: Failed to query EGL extensions.");
+ return;
+ }
+
+ if (strstr(extensions, "EGL_KHR_base_image")) {
+ qWarning("EGL: EGL_KHR_base_image extension is not supported.");
+ return;
+ }
+
+ auto eglDisplay = GLContextHelper::getEGLDisplay();
+ if (!eglDisplay) {
+ qWarning("EGL: No EGL display.");
+ return;
+ }
+
+ const char *displayExtensions = m_functions->eglQueryString(eglDisplay, EGL_EXTENSIONS);
+ m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import")
+ && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers")
+ && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export");
+
+ if (m_isDmaBufSupported) {
+ // FIXME: This disables GBM for nvidia. Remove this when nvidia fixes its GBM support.
+ //
+ // "Buffer allocation and submission to DRM KMS using gbm is not currently supported."
+ // See: https://download.nvidia.com/XFree86/Linux-x86_64/550.40.07/README/kms.html
+ //
+ // Chromium uses GBM to allocate scanout buffers. Scanout requires DRM KMS. If KMS is
+ // enabled, gbm_device and gbm_buffer are created without any issues but rendering to the
+ // buffer will malfunction. It is not known how to detect this problem before rendering
+ // so we just disable GBM for nvidia.
+ const char *displayVendor = m_functions->eglQueryString(eglDisplay, EGL_VENDOR);
+ m_isDmaBufSupported = !strstr(displayVendor, "NVIDIA");
+ }
+}
+
+void EGLHelper::queryDmaBuf(const int width, const int height, int *fd, int *stride, int *offset,
+ uint64_t *modifiers)
+{
+ if (!m_isDmaBufSupported)
+ return;
+
+ ScopedGLContext context;
+ if (!context.isValid())
+ return;
+
+ EGLDisplay eglDisplay = context.eglDisplay();
+ EGLContext eglContext = context.eglContext();
+ if (!eglContext) {
+ qWarning("EGL: No EGLContext.");
+ return;
+ }
+
+ uint64_t textureId = context.createTexture(width, height);
+ EGLImage eglImage = m_functions->eglCreateImage(eglDisplay, eglContext, EGL_GL_TEXTURE_2D,
+ (EGLClientBuffer)textureId, NULL);
+ if (eglImage == EGL_NO_IMAGE) {
+ qWarning() << "EGL: Failed to create EGLImage:"
+ << ui::GetEGLErrorString(m_functions->eglGetError());
+ return;
+ }
+
+ int numPlanes = 0;
+ if (!m_functions->eglExportDMABUFImageQueryMESA(eglDisplay, eglImage, nullptr, &numPlanes,
+ modifiers))
+ qWarning() << "EGL: Failed to retrieve the pixel format of the buffer:"
+ << ui::GetEGLErrorString(m_functions->eglGetError());
+ Q_ASSERT(numPlanes == 1);
+
+ if (!m_functions->eglExportDMABUFImageMESA(eglDisplay, eglImage, fd, stride, offset))
+ qWarning() << "EGL: Failed to retrieve the dma_buf file descriptor:"
+ << ui::GetEGLErrorString(m_functions->eglGetError());
+
+ m_functions->eglDestroyImage(eglDisplay, eglImage);
+}
+
+bool EGLHelper::isDmaBufSupported()
+{
+ if (!m_isDmaBufSupported)
+ return false;
+
+ int fd = -1;
+ queryDmaBuf(2, 2, &fd, nullptr, nullptr, nullptr);
+ if (fd == -1) {
+ m_isDmaBufSupported = false;
+ return false;
+ }
+
+ close(fd);
+ return true;
+}
+#endif // QT_CONFIG(opengl) && defined(USE_OZONE)
+
QT_END_NAMESPACE
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
namespace gl {
namespace init {
-scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group,
- GLSurface* compatible_surface,
- const GLContextAttribs& attribs)
+scoped_refptr<GLContext> CreateGLContext(GLShareGroup *share_group,
+ GLSurface *compatible_surface,
+ const GLContextAttribs &attribs)
{
- scoped_refptr<GLContext> context;
- if (GetGLImplementation() == kGLImplementationDesktopGL) {
- context = new GLContextWGL(share_group);
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGLCoreProfile:
+ case kGLImplementationDesktopGL: {
+ scoped_refptr<GLContext> context = new GLContextWGL(share_group);
if (!context->Initialize(compatible_surface, attribs))
return nullptr;
return context;
- } else {
- context = new GLContextEGL(share_group);
}
-
- if (!GLContextHelper::initializeContext(context.get(), compatible_surface, attribs))
+ case kGLImplementationEGLANGLE:
+ case kGLImplementationEGLGLES2:
+ return InitializeGLContext(new GLContextEGL(share_group),
+ compatible_surface, attribs);
+ case kGLImplementationDisabled:
return nullptr;
-
- return context;
+ default:
+ break;
+ }
+ Q_UNREACHABLE();
+ return nullptr;
}
} // namespace init
} // namespace gl
-#endif // defined(OS_WIN)
+#endif // BUILDFLAG(IS_WIN)
diff --git a/src/core/ozone/gl_context_qt.h b/src/core/ozone/gl_context_qt.h
index 612aae3f5..bd1137053 100644
--- a/src/core/ozone/gl_context_qt.h
+++ b/src/core/ozone/gl_context_qt.h
@@ -1,50 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_GL_CONTEXT_QT_H_
#define GL_GL_CONTEXT_QT_H_
#include <QObject>
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qtgui-config.h>
+
#include "ui/gl/gl_context.h"
+#if QT_CONFIG(opengl) && defined(USE_OZONE)
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
namespace gl {
-class GLContext;
class GLSurface;
}
@@ -75,6 +46,44 @@ private:
bool m_robustness = false;
};
+#if QT_CONFIG(opengl) && defined(USE_OZONE)
+#undef eglCreateImage
+#undef eglDestroyImage
+#undef eglExportDMABUFImageMESA
+#undef eglExportDMABUFImageQueryMESA
+#undef eglGetError
+#undef eglQueryString
+
+class EGLHelper
+{
+public:
+ struct EGLFunctions
+ {
+ EGLFunctions();
+
+ PFNEGLCREATEIMAGEPROC eglCreateImage;
+ PFNEGLDESTROYIMAGEPROC eglDestroyImage;
+ PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
+ PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;
+ PFNEGLGETERRORPROC eglGetError;
+ PFNEGLQUERYSTRINGPROC eglQueryString;
+ };
+
+ static EGLHelper *instance();
+
+ EGLFunctions *functions() const { return m_functions.get(); }
+ void queryDmaBuf(const int width, const int height, int *fd, int *stride, int *offset,
+ uint64_t *modifiers);
+ bool isDmaBufSupported();
+
+private:
+ EGLHelper();
+
+ QScopedPointer<EGLFunctions> m_functions;
+ bool m_isDmaBufSupported = false;
+};
+#endif // QT_CONFIG(opengl) && defined(USE_OZONE)
+
QT_END_NAMESPACE
#endif
diff --git a/src/core/ozone/gl_ozone_egl_qt.cpp b/src/core/ozone/gl_ozone_egl_qt.cpp
index 14ba5e8d9..26d11df31 100644
--- a/src/core/ozone/gl_ozone_egl_qt.cpp
+++ b/src/core/ozone/gl_ozone_egl_qt.cpp
@@ -1,125 +1,70 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#if defined(USE_OZONE)
#include "gl_context_qt.h"
#include "gl_ozone_egl_qt.h"
#include "gl_surface_egl_qt.h"
-#include "base/files/file_path.h"
-#include "base/native_library.h"
-#include "ui/gl/gl_context_egl.h"
-#include "ui/gl/gl_implementation.h"
+#include "media/gpu/buildflags.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_display.h"
#include "ui/gl/gl_surface.h"
-#include "ui/gl/init/gl_factory.h"
-#include "ui/gl/init/gl_initializer.h"
-
-#include <EGL/egl.h>
-#include <dlfcn.h>
+#include "ui/gl/gl_utils.h"
+#include "ui/ozone/common/native_pixmap_egl_binding.h"
namespace ui {
-base::NativeLibrary LoadLibrary(const base::FilePath& filename) {
- base::NativeLibraryLoadError error;
- base::NativeLibrary library = base::LoadNativeLibrary(filename, &error);
- if (!library) {
- LOG(ERROR) << "Failed to load " << filename.MaybeAsASCII() << ": " << error.ToString();
- return NULL;
- }
- return library;
-}
-
-bool GLOzoneEGLQt::LoadGLES2Bindings(gl::GLImplementation /*implementation*/)
+bool LoadQtEGLBindings()
{
- base::NativeLibrary eglgles2Library = dlopen(NULL, RTLD_LAZY);
- if (!eglgles2Library) {
- LOG(ERROR) << "Failed to open EGL/GLES2 context " << dlerror();
- return false;
- }
-
- gl::GLGetProcAddressProc get_proc_address =
- reinterpret_cast<gl::GLGetProcAddressProc>(
- base::GetFunctionPointerFromNativeLibrary(eglgles2Library,
- "eglGetProcAddress"));
- if (!get_proc_address) {
- // QTBUG-63341 most likely libgles2 not linked with libegl -> fallback to qpa
- get_proc_address =
- reinterpret_cast<gl::GLGetProcAddressProc>(GLContextHelper::getEglGetProcAddress());
- }
-
+ gl::GLGetProcAddressProc get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(GLContextHelper::getEglGetProcAddress());
if (!get_proc_address) {
LOG(ERROR) << "eglGetProcAddress not found.";
- base::UnloadNativeLibrary(eglgles2Library);
return false;
}
-
gl::SetGLGetProcAddressProc(get_proc_address);
- gl::AddGLNativeLibrary(eglgles2Library);
return true;
}
-bool GLOzoneEGLQt::InitializeGLOneOffPlatform()
+bool GLOzoneEGLQt::LoadGLES2Bindings(const gl::GLImplementationParts & /*implementation*/)
{
- if (!gl::GLSurfaceEGLQt::InitializeOneOff()) {
- LOG(ERROR) << "GLOzoneEGLQt::InitializeOneOff failed.";
- return false;
+ return LoadQtEGLBindings();
+}
+
+gl::GLDisplay *GLOzoneEGLQt::InitializeGLOneOffPlatform(bool supports_angle,
+ std::vector<gl::DisplayType> init_displays,
+ gl::GpuPreference gpu_preference)
+{
+ if (auto display = gl::GLSurfaceEGLQt::InitializeOneOff(gpu_preference)) {
+ if (!static_cast<gl::GLDisplayEGL*>(display)->Initialize(supports_angle, std::move(init_displays), GetNativeDisplay())) {
+ LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
+ return nullptr;
+ }
+ return display;
}
- return true;
+ return nullptr;
}
-bool GLOzoneEGLQt::InitializeExtensionSettingsOneOffPlatform()
+
+bool GLOzoneEGLQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display)
{
- return gl::GLSurfaceEGLQt::InitializeExtensionSettingsOneOff();
+ return static_cast<gl::GLDisplayEGL*>(display)->InitializeExtensionSettings();
}
-scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateViewGLSurface(gfx::AcceleratedWidget window)
+scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateViewGLSurface(gl::GLDisplay* display, gfx::AcceleratedWidget window)
{
+ Q_UNUSED(display);
+ Q_UNUSED(window);
return nullptr;
}
-scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(const gfx::Size &size)
+scoped_refptr<gl::GLSurface> GLOzoneEGLQt::CreateOffscreenGLSurface(gl::GLDisplay* display, const gfx::Size &size)
{
- scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceEGLQt(size);
+ scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceEGLQt(static_cast<gl::GLDisplayEGL*>(display), size);
if (surface->Initialize(gl::GLSurfaceFormat()))
return surface;
- surface = new gl::GLSurfacelessQtEGL(size);
+ surface = new gl::GLSurfacelessQtEGL(static_cast<gl::GLDisplayEGL*>(display), size);
if (surface->Initialize(gl::GLSurfaceFormat()))
return surface;
@@ -134,6 +79,24 @@ gl::EGLDisplayPlatform GLOzoneEGLQt::GetNativeDisplay()
return platform;
}
+bool GLOzoneEGLQt::CanImportNativePixmap()
+{
+ return gl::GLSurfaceEGL::GetGLDisplayEGL()->ext->b_EGL_EXT_image_dma_buf_import;
+}
+
+std::unique_ptr<NativePixmapGLBinding> GLOzoneEGLQt::ImportNativePixmap(
+ scoped_refptr<gfx::NativePixmap> pixmap,
+ gfx::BufferFormat plane_format,
+ gfx::BufferPlane plane,
+ gfx::Size plane_size,
+ const gfx::ColorSpace &color_space,
+ GLenum target,
+ GLuint texture_id)
+{
+ return NativePixmapEGLBinding::Create(pixmap, plane_format, plane, plane_size, color_space,
+ target, texture_id);
+}
+
} // namespace ui
#endif // defined(USE_OZONE)
diff --git a/src/core/ozone/gl_ozone_egl_qt.h b/src/core/ozone/gl_ozone_egl_qt.h
index c55ba232c..7ac55979a 100644
--- a/src/core/ozone/gl_ozone_egl_qt.h
+++ b/src/core/ozone/gl_ozone_egl_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_OZONE_EGL_QT
#define GL_OZONE_EGL_QT
@@ -48,12 +12,25 @@ namespace ui {
class GLOzoneEGLQt : public GLOzoneEGL {
public:
- bool InitializeGLOneOffPlatform() override;
- bool InitializeExtensionSettingsOneOffPlatform() override;
+ gl::GLDisplay *InitializeGLOneOffPlatform(bool supports_angle,
+ std::vector<gl::DisplayType> init_displays,
+ gl::GpuPreference gpu_preference) override;
+ bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override;
scoped_refptr<gl::GLSurface> CreateViewGLSurface(
+ gl::GLDisplay *display,
gfx::AcceleratedWidget window) override;
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
- const gfx::Size& size) override;
+ gl::GLDisplay *display,
+ const gfx::Size &size) override;
+ bool CanImportNativePixmap() override;
+ std::unique_ptr<NativePixmapGLBinding> ImportNativePixmap(
+ scoped_refptr<gfx::NativePixmap> pixmap,
+ gfx::BufferFormat plane_format,
+ gfx::BufferPlane plane,
+ gfx::Size plane_size,
+ const gfx::ColorSpace &color_space,
+ GLenum target,
+ GLuint texture_id) override;
protected:
// Returns native platform display handle. This is used to obtain the EGL
@@ -61,7 +38,7 @@ protected:
gl::EGLDisplayPlatform GetNativeDisplay() override;
// Sets up GL bindings for the native surface.
- bool LoadGLES2Bindings(gl::GLImplementation implementation) override;
+ bool LoadGLES2Bindings(const gl::GLImplementationParts &implementation) override;
};
} // namespace ui
diff --git a/src/core/ozone/gl_ozone_glx_qt.cpp b/src/core/ozone/gl_ozone_glx_qt.cpp
index 60b970209..23ba92ea4 100644
--- a/src/core/ozone/gl_ozone_glx_qt.cpp
+++ b/src/core/ozone/gl_ozone_glx_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -45,23 +9,25 @@
#include "gl_ozone_glx_qt.h"
#include "gl_surface_glx_qt.h"
#include "gl_context_qt.h"
+
+#include "media/gpu/buildflags.h"
#include "ui/gl/gl_context_glx.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_glx_api_implementation.h"
+#include "ui/gl/presenter.h"
+
#include <dlfcn.h>
namespace ui {
-bool GLOzoneGLXQt::InitializeGLOneOffPlatform() {
- if (!gl::GLSurfaceGLXQt::InitializeOneOff()) {
- LOG(ERROR) << "GLSurfaceGLXQt::InitializeOneOff failed.";
- return false;
- }
- return true;
+gl::GLDisplay *GLOzoneGLXQt::InitializeGLOneOffPlatform(bool, std::vector<gl::DisplayType>, gl::GpuPreference preference)
+{
+ return gl::GLSurfaceGLXQt::InitializeOneOff(preference);
}
bool GLOzoneGLXQt::InitializeStaticGLBindings(
- gl::GLImplementation implementation) {
+ const gl::GLImplementationParts &implementation) {
+ Q_UNUSED(implementation);
base::NativeLibrary library = dlopen(NULL, RTLD_LAZY);
if (!library) {
@@ -100,7 +66,7 @@ void GLOzoneGLXQt::SetDisabledExtensionsPlatform(
gl::SetDisabledExtensionsGLX(disabled_extensions);
}
-void GLOzoneGLXQt::ShutdownGL() {
+void GLOzoneGLXQt::ShutdownGL(gl::GLDisplay *) {
gl::ClearBindingsGL();
gl::ClearBindingsGLX();
}
@@ -121,16 +87,19 @@ scoped_refptr<gl::GLContext> GLOzoneGLXQt::CreateGLContext(
}
scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) {
return nullptr;
}
-scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateSurfacelessViewGLSurface(
+scoped_refptr<gl::Presenter> GLOzoneGLXQt::CreateSurfacelessViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) {
return nullptr;
}
scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateOffscreenGLSurface(
+ gl::GLDisplay* display,
const gfx::Size& size) {
scoped_refptr<gl::GLSurface> surface = new gl::GLSurfaceGLXQt(size);
if (surface->Initialize(gl::GLSurfaceFormat()))
@@ -139,7 +108,19 @@ scoped_refptr<gl::GLSurface> GLOzoneGLXQt::CreateOffscreenGLSurface(
return nullptr;
}
-bool GLOzoneGLXQt::InitializeExtensionSettingsOneOffPlatform()
+bool GLOzoneGLXQt::CanImportNativePixmap()
+{
+ return false;
+}
+
+std::unique_ptr<ui::NativePixmapGLBinding> GLOzoneGLXQt::ImportNativePixmap(
+ scoped_refptr<gfx::NativePixmap> pixmap, gfx::BufferFormat plane_format, gfx::BufferPlane plane,
+ gfx::Size plane_size, const gfx::ColorSpace &, GLenum target, GLuint texture_id)
+{
+ return nullptr;
+}
+
+bool GLOzoneGLXQt::InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *)
{
return gl::GLSurfaceGLXQt::InitializeExtensionSettingsOneOff();
}
diff --git a/src/core/ozone/gl_ozone_glx_qt.h b/src/core/ozone/gl_ozone_glx_qt.h
index 7825cba35..4df26ba71 100644
--- a/src/core/ozone/gl_ozone_glx_qt.h
+++ b/src/core/ozone/gl_ozone_glx_qt.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef UI_OZONE_GLX_QT_H_
-#define UI_OZONE_GLX_QT_H
+#define UI_OZONE_GLX_QT_H_
-#include "base/macros.h"
#include "ui/gl/gl_implementation.h"
#include "ui/ozone/public/gl_ozone.h"
@@ -52,34 +15,39 @@ public:
GLOzoneGLXQt() {}
~GLOzoneGLXQt() override {}
- bool InitializeGLOneOffPlatform() override;
- bool InitializeStaticGLBindings(gl::GLImplementation implementation) override;
- bool InitializeExtensionSettingsOneOffPlatform() override;
- void ShutdownGL() override;
+ gl::GLDisplay *InitializeGLOneOffPlatform(bool, std::vector<gl::DisplayType>, gl::GpuPreference) override;
+ bool InitializeStaticGLBindings(const gl::GLImplementationParts &implementation) override;
+ bool InitializeExtensionSettingsOneOffPlatform(gl::GLDisplay *display) override;
+ void ShutdownGL(gl::GLDisplay *display) override;
void SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) override;
bool GetGLWindowSystemBindingInfo(
const gl::GLVersionInfo &gl_info,
gl::GLWindowSystemBindingInfo *info) override;
+ bool CanImportNativePixmap() override;
+ std::unique_ptr<ui::NativePixmapGLBinding> ImportNativePixmap(
+ scoped_refptr<gfx::NativePixmap>, gfx::BufferFormat, gfx::BufferPlane,
+ gfx::Size, const gfx::ColorSpace &, GLenum, GLuint) override;
+
scoped_refptr<gl::GLContext> CreateGLContext(
gl::GLShareGroup* share_group,
gl::GLSurface* compatible_surface,
const gl::GLContextAttribs& attribs) override;
scoped_refptr<gl::GLSurface> CreateViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) override;
- scoped_refptr<gl::GLSurface> CreateSurfacelessViewGLSurface(
+ scoped_refptr<gl::Presenter> CreateSurfacelessViewGLSurface(
+ gl::GLDisplay* display,
gfx::AcceleratedWidget window) override;
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
+ gl::GLDisplay* display,
const gfx::Size& size) override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(GLOzoneGLXQt);
};
} // namespace ui
-#endif // UI_OZONE_GLX_QT_H
+#endif // UI_OZONE_GLX_QT_H_
diff --git a/src/core/ozone/gl_share_context_qt.cpp b/src/core/ozone/gl_share_context_qt.cpp
index 4865734f7..b1c5e201f 100644
--- a/src/core/ozone/gl_share_context_qt.cpp
+++ b/src/core/ozone/gl_share_context_qt.cpp
@@ -1,65 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "gl_share_context_qt.h"
#include <QtGui/qtgui-config.h>
#include <qpa/qplatformnativeinterface.h>
-#include <QtGui/qopenglcontext_platform.h>
-#if defined(Q_OS_MACOS)
-#include "macos_context_type_helper.h"
-#endif
+
+#include "ui/gl/gl_context_egl.h"
+#include "ui/gl/gl_implementation.h"
+
#if QT_CONFIG(opengl)
+#include <QtGui/qopenglcontext_platform.h>
#include <QOpenGLContext>
#include <QOpenGLExtraFunctions>
-#endif
+#endif // QT_CONFIG(opengl)
namespace QtWebEngineCore {
-QtShareGLContext::QtShareGLContext(QOpenGLContext *qtContext)
+QtShareGLContext::QtShareGLContext(QOpenGLContext *context)
: gl::GLContext(nullptr), m_handle(nullptr)
{
#if QT_CONFIG(opengl)
- QOpenGLContext *context = QOpenGLContext::globalShareContext();
#if defined(Q_OS_MACOS)
- auto *mac_ctx = context->nativeInterface<QNativeInterface::QCocoaGLContext>();
- if (mac_ctx)
- m_handle = cglContext(mac_ctx->nativeContext());
+ qFatal("macOS only support using ANGLE.");
#endif
#if defined(Q_OS_WIN)
auto *win_ctx = context->nativeInterface<QNativeInterface::QWGLContext>();
@@ -77,7 +39,7 @@ QtShareGLContext::QtShareGLContext(QOpenGLContext *qtContext)
m_handle = (void *)egl_ctx->nativeContext();
#endif
if (!m_handle)
- qFatal("Could not get handle for shared contex");
+ qFatal("Could not get handle for shared context.");
#endif // QT_CONFIG(opengl)
}
@@ -94,17 +56,22 @@ unsigned int QtShareGLContext::CheckStickyGraphicsResetStatusImpl()
void ShareGroupQt::AboutToAddFirstContext()
{
+ if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) {
+ m_shareContextQt = new gl::GLContextEGL(nullptr);
+ return;
+ }
+
#if QT_CONFIG(opengl)
// This currently has to be setup by ::main in all applications using QQuickWebEngineView with
// delegated rendering.
QOpenGLContext *shareContext = QOpenGLContext::globalShareContext();
if (!shareContext) {
qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to "
- "call QtWebEngineCore::initialize() in your main() function before QCoreApplication is "
- "created.");
+ "call QtWebEngineQuick::initialize() in your main() function before "
+ "QCoreApplication is created.");
}
m_shareContextQt = new QtShareGLContext(shareContext);
-#endif
+#endif // QT_CONFIG(opengl)
}
} // namespace
diff --git a/src/core/ozone/gl_share_context_qt.h b/src/core/ozone/gl_share_context_qt.h
index b07f5123e..89be00421 100644
--- a/src/core/ozone/gl_share_context_qt.h
+++ b/src/core/ozone/gl_share_context_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_SHARE_CONTEXT_QT
#define GL_SHARE_CONTEXT_QT
@@ -93,7 +57,7 @@ public:
void AboutToAddFirstContext() override;
private:
- scoped_refptr<QtShareGLContext> m_shareContextQt;
+ scoped_refptr<gl::GLContext> m_shareContextQt;
};
} // namespace
#endif
diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index 849f0ee4d..a0c120ac6 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -44,17 +8,13 @@
#include "gl_context_qt.h"
#include "ozone/gl_surface_egl_qt.h"
-#if !defined(OS_MAC)
#include "ui/gl/egl_util.h"
#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/gl_display.h"
+#include "ui/gl/gl_display_manager.h"
#include "ui/gl/init/gl_factory.h"
-// From ANGLE's egl/eglext.h.
-#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
-#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
-#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
-#endif
+#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
using ui::GetLastEGLErrorString;
@@ -63,41 +23,45 @@ namespace gl {
bool GLSurfaceEGLQt::g_egl_surfaceless_context_supported = false;
bool GLSurfaceEGLQt::s_initialized = false;
+GLSurfaceEGLQt::GLSurfaceEGLQt(gl::GLDisplayEGL *display, const gfx::Size& size)
+ : GLSurfaceQt(size),
+ m_surfaceBuffer(0)
+{
+}
+
GLSurfaceEGLQt::~GLSurfaceEGLQt()
{
Destroy();
}
-bool GLSurfaceEGLQt::InitializeOneOff()
+gl::GLDisplay *GLSurfaceEGLQt::InitializeOneOff(gl::GpuPreference preference)
{
if (s_initialized)
- return true;
+ return g_display;
- // Must be called before initializing the display.
- g_driver_egl.InitializeClientExtensionBindings();
-
- g_display = GLContextHelper::getEGLDisplay();
- if (!g_display) {
+ auto *egl_display = GLDisplayManagerEGL::GetInstance()->GetDisplay(preference);
+ g_display = egl_display;
+ egl_display->SetDisplay(GLContextHelper::getEGLDisplay());
+ if (!egl_display->GetDisplay()) {
LOG(ERROR) << "GLContextHelper::getEGLDisplay() failed.";
- return false;
+ return nullptr;
}
g_config = GLContextHelper::getEGLConfig();
if (!g_config) {
LOG(ERROR) << "GLContextHelper::getEGLConfig() failed.";
- return false;
+ return nullptr;
}
- if (!eglInitialize(g_display, NULL, NULL)) {
+ if (!eglInitialize(egl_display->GetDisplay(), NULL, NULL)) {
LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
- return false;
+ return nullptr;
}
- g_client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
- g_extensions = eglQueryString(g_display, EGL_EXTENSIONS);
- g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context");
+ g_extensions = eglQueryString(egl_display->GetDisplay(), EGL_EXTENSIONS);
+ g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions.c_str(), "EGL_KHR_surfaceless_context");
if (g_egl_surfaceless_context_supported) {
- scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(gfx::Size(1, 1));
+ scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(egl_display, gfx::Size(1, 1));
gl::GLContextAttribs attribs;
scoped_refptr<GLContext> context = init::CreateGLContext(
NULL, surface.get(), attribs);
@@ -113,11 +77,8 @@ bool GLSurfaceEGLQt::InitializeOneOff()
}
}
- // Must be called after initializing the display.
- g_driver_egl.InitializeExtensionBindings();
-
s_initialized = true;
- return true;
+ return egl_display;
}
bool GLSurfaceEGLQt::InitializeExtensionSettingsOneOff()
@@ -125,130 +86,12 @@ bool GLSurfaceEGLQt::InitializeExtensionSettingsOneOff()
return s_initialized;
}
-bool GLSurfaceEGL::InitializeExtensionSettingsOneOff()
-{
- return GLSurfaceEGLQt::InitializeExtensionSettingsOneOff();
-}
-
-EGLDisplay GLSurfaceEGL::GetHardwareDisplay()
-{
- return static_cast<EGLDisplay>(GLSurfaceQt::g_display);
-}
-
-bool GLSurfaceEGL::IsCreateContextRobustnessSupported()
-{
- return GLContextHelper::isCreateContextRobustnessSupported() && HasEGLExtension("EGL_EXT_create_context_robustness");
-}
-
-bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported()
-{
- return false;
-}
-bool GLSurfaceEGL::IsEGLSurfacelessContextSupported()
-{
- return GLSurfaceEGLQt::g_egl_surfaceless_context_supported;
-}
-bool GLSurfaceEGL::IsEGLContextPrioritySupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsRobustResourceInitSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsDisplayTextureShareGroupSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsCreateContextClientArraysSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsPixelFormatFloatSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsANGLEFeatureControlSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsANGLEPowerPreferenceSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsANGLEExternalContextAndSurfaceSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsDisplaySemaphoreShareGroupSupported()
-{
- return false;
-}
-
-bool GLSurfaceEGL::IsRobustnessVideoMemoryPurgeSupported()
-{
- return false;
-}
-
-void GLSurfaceEGL::ShutdownOneOff()
-{
-}
-
-const char *GLSurfaceEGL::GetEGLClientExtensions()
-{
- return GLSurfaceQt::g_client_extensions;
-}
-
-const char *GLSurfaceEGL::GetEGLExtensions()
-{
- return GLSurfaceQt::g_extensions;
-}
-
-bool GLSurfaceEGL::HasEGLClientExtension(const char *name)
-{
- return ExtensionsContain(GetEGLClientExtensions(), name);
-}
-
-bool GLSurfaceEGL::HasEGLExtension(const char *name)
-{
- return ExtensionsContain(GetEGLExtensions(), name);
-}
-
-bool GLSurfaceEGL::InitializeOneOff(gl::EGLDisplayPlatform /*native_display*/)
-{
- return GLSurfaceEGLQt::InitializeOneOff();
-}
-
-bool GLSurfaceEGL::IsAndroidNativeFenceSyncSupported()
-{
- return false;
-}
-
-GLSurfaceEGLQt::GLSurfaceEGLQt(const gfx::Size& size)
- : GLSurfaceQt(size),
- m_surfaceBuffer(0)
-{
-}
-
bool GLSurfaceEGLQt::Initialize(GLSurfaceFormat format)
{
Q_ASSERT(!m_surfaceBuffer);
m_format = format;
- EGLDisplay display = g_display;
+ EGLDisplay display = GLContextHelper::getEGLDisplay();
if (!display) {
LOG(ERROR) << "Trying to create surface with invalid display.";
return false;
@@ -276,7 +119,7 @@ bool GLSurfaceEGLQt::Initialize(GLSurfaceFormat format)
void GLSurfaceEGLQt::Destroy()
{
if (m_surfaceBuffer) {
- if (!eglDestroySurface(g_display, m_surfaceBuffer))
+ if (!eglDestroySurface(GLContextHelper::getEGLDisplay(), m_surfaceBuffer))
LOG(ERROR) << "eglDestroySurface failed with error " << GetLastEGLErrorString();
m_surfaceBuffer = 0;
@@ -314,7 +157,7 @@ void* GLSurfaceEGLQt::GetHandle()
return reinterpret_cast<void*>(m_surfaceBuffer);
}
-GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size)
+GLSurfacelessQtEGL::GLSurfacelessQtEGL(GLDisplayEGL *display, const gfx::Size& size)
: GLSurfaceQt(size)
{
}
@@ -351,26 +194,5 @@ void* GLSurfacelessQtEGL::GetShareHandle()
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 gl
-#else
-namespace gl {
-struct GL_EXPORT DriverEGL {
- static std::string GetPlatformExtensions();
-};
-
-std::string DriverEGL::GetPlatformExtensions()
-{
- return "";
-}
} // namespace gl
-#endif // !defined(OS_MAC)
+#endif // !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN)
diff --git a/src/core/ozone/gl_surface_egl_qt.h b/src/core/ozone/gl_surface_egl_qt.h
index dff25e433..d581f9079 100644
--- a/src/core/ozone/gl_surface_egl_qt.h
+++ b/src/core/ozone/gl_surface_egl_qt.h
@@ -1,56 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_SURFACE_EGL_QT_H_
#define GL_SURFACE_EGL_QT_H_
#include "gl_surface_qt.h"
#include <EGL/egl.h>
-#include <EGL/eglext.h>
namespace gl {
+class GLDisplayEGL;
+
class GLSurfaceEGLQt: public GLSurfaceQt {
public:
- explicit GLSurfaceEGLQt(const gfx::Size& size);
+ explicit GLSurfaceEGLQt(gl::GLDisplayEGL *display, const gfx::Size& size);
- static bool InitializeOneOff();
+ static gl::GLDisplay *InitializeOneOff(gl::GpuPreference preference);
static bool InitializeExtensionSettingsOneOff();
bool Initialize(GLSurfaceFormat format) override;
@@ -69,7 +34,6 @@ public:
private:
EGLSurface m_surfaceBuffer;
static bool s_initialized;
- DISALLOW_COPY_AND_ASSIGN(GLSurfaceEGLQt);
};
// The following comment is cited from chromium/ui/gl/gl_surface_egl.cc:
@@ -79,7 +43,7 @@ private:
class GLSurfacelessQtEGL : public GLSurfaceQt {
public:
- explicit GLSurfacelessQtEGL(const gfx::Size& size);
+ explicit GLSurfacelessQtEGL(gl::GLDisplayEGL *display, const gfx::Size& size);
public:
bool Initialize(GLSurfaceFormat format) override;
@@ -89,9 +53,6 @@ public:
const gfx::ColorSpace &color_space, bool has_alpha) override;
EGLSurface GetHandle() override;
void* GetShareHandle() override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL);
};
}
diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp
index 5ccf5037a..61c9ef9de 100644
--- a/src/core/ozone/gl_surface_glx_qt.cpp
+++ b/src/core/ozone/gl_surface_glx_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -43,18 +7,23 @@
#include "gl_context_qt.h"
#include "ozone/gl_surface_glx_qt.h"
+
#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_display.h"
+#include "ui/gl/gl_display_manager.h"
+#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_surface_glx.h"
namespace gl {
-void GLSurfaceGLX::ShutdownOneOff()
+static bool HasGLXExtension(const char *name)
{
+ return GLSurface::ExtensionsContain(GLSurfaceQt::g_extensions.c_str(), name);
}
bool GLSurfaceGLX::IsCreateContextSupported()
{
- return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context");
+ return HasGLXExtension("GLX_ARB_create_context");
}
bool GLSurfaceGLX::IsCreateContextRobustnessSupported()
@@ -62,16 +31,6 @@ bool GLSurfaceGLX::IsCreateContextRobustnessSupported()
return GLContextHelper::isCreateContextRobustnessSupported() && HasGLXExtension("GLX_ARB_create_context_robustness");
}
-bool GLSurfaceGLX::IsEXTSwapControlSupported()
-{
- return HasGLXExtension("GLX_EXT_swap_control");
-}
-
-bool GLSurfaceGLX::IsMESASwapControlSupported()
-{
- return HasGLXExtension("GLX_MESA_swap_control");
-}
-
bool GLSurfaceGLX::IsCreateContextProfileSupported()
{
return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_profile");
@@ -79,22 +38,7 @@ bool GLSurfaceGLX::IsCreateContextProfileSupported()
bool GLSurfaceGLX::IsCreateContextES2ProfileSupported()
{
- return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_ARB_create_context_es2_profile");
-}
-
-bool GLSurfaceGLX::IsOMLSyncControlSupported()
-{
- return false; // ExtensionsContain(g_extensions, "GLX_OML_sync_control");
-}
-
-bool GLSurfaceGLX::HasGLXExtension(const char *name)
-{
- return ExtensionsContain(GLSurfaceQt::g_extensions, name);
-}
-
-bool GLSurfaceGLX::IsTextureFromPixmapSupported()
-{
- return ExtensionsContain(GLSurfaceQt::g_extensions, "GLX_EXT_texture_from_pixmap");
+ return HasGLXExtension("GLX_ARB_create_context_es2_profile");
}
bool GLSurfaceGLX::IsRobustnessVideoMemoryPurgeSupported()
@@ -102,11 +46,6 @@ bool GLSurfaceGLX::IsRobustnessVideoMemoryPurgeSupported()
return false;
}
-const char* GLSurfaceGLX::GetGLXExtensions()
-{
- return GLSurfaceQt::g_extensions;
-}
-
bool GLSurfaceGLXQt::s_initialized = false;
@@ -121,61 +60,55 @@ GLSurfaceGLXQt::~GLSurfaceGLXQt()
Destroy();
}
-bool GLSurfaceGLXQt::InitializeOneOff()
+GLDisplay *GLSurfaceGLXQt::InitializeOneOff(gl::GpuPreference preference)
{
if (s_initialized)
- return true;
+ return g_display;
- g_display = GLContextHelper::getXDisplay();
- if (!g_display) {
+ g_display = GLDisplayManagerX11::GetInstance()->GetDisplay(preference);
+ if (!g_display->GetDisplay()) {
LOG(ERROR) << "GLContextHelper::getXDisplay() failed.";
- return false;
+ return nullptr;
}
g_config = GLContextHelper::getGlXConfig();
if (!g_config) {
LOG(ERROR) << "GLContextHelper::getGlxConfig() failed.";
- return false;
+ return nullptr;
}
- Display* display = static_cast<Display*>(g_display);
+ Display* display = static_cast<Display*>(g_display->GetDisplay());
int major, minor;
if (!glXQueryVersion(display, &major, &minor)) {
LOG(ERROR) << "glxQueryVersion failed.";
- return false;
+ return nullptr;
}
if (major == 1 && minor < 3) {
LOG(ERROR) << "GLX 1.3 or later is required.";
- return false;
+ return nullptr;
}
s_initialized = true;
- return true;
+ return g_display;
}
-
bool GLSurfaceGLXQt::InitializeExtensionSettingsOneOff()
{
if (!s_initialized)
return false;
- Display* display = static_cast<Display*>(g_display);
+ Display* display = static_cast<Display*>(g_display->GetDisplay());
GLSurfaceQt::g_extensions = glXQueryExtensionsString(display, 0);
- g_driver_glx.InitializeExtensionBindings(g_extensions);
+ g_driver_glx.InitializeExtensionBindings(g_extensions.c_str());
return true;
}
-bool GLSurfaceGLX::InitializeExtensionSettingsOneOff()
-{
- return GLSurfaceGLXQt::InitializeExtensionSettingsOneOff();
-}
-
bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format)
{
Q_ASSERT(!m_surfaceBuffer);
- Display* display = static_cast<Display*>(g_display);
+ Display* display = static_cast<Display*>(g_display->GetDisplay());
const int pbuffer_attributes[] = {
GLX_PBUFFER_WIDTH, m_size.width(),
GLX_PBUFFER_HEIGHT, m_size.height(),
@@ -198,7 +131,7 @@ bool GLSurfaceGLXQt::Initialize(GLSurfaceFormat format)
void GLSurfaceGLXQt::Destroy()
{
if (m_surfaceBuffer) {
- glXDestroyPbuffer(static_cast<Display*>(g_display), m_surfaceBuffer);
+ glXDestroyPbuffer(static_cast<Display*>(g_display->GetDisplay()), m_surfaceBuffer);
m_surfaceBuffer = 0;
}
}
diff --git a/src/core/ozone/gl_surface_glx_qt.h b/src/core/ozone/gl_surface_glx_qt.h
index fb17c5aca..8cbf1fcf2 100644
--- a/src/core/ozone/gl_surface_glx_qt.h
+++ b/src/core/ozone/gl_surface_glx_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_SURFACE_GLX_QT_H_
#define GL_SURFACE_GLX_QT_H_
@@ -48,7 +12,7 @@ class GLSurfaceGLXQt: public GLSurfaceQt {
public:
explicit GLSurfaceGLXQt(const gfx::Size& size);
- static bool InitializeOneOff();
+ static gl::GLDisplay *InitializeOneOff(gl::GpuPreference preference);
static bool InitializeExtensionSettingsOneOff();
bool Initialize(GLSurfaceFormat format) override;
@@ -61,7 +25,6 @@ protected:
private:
static bool s_initialized;
int m_surfaceBuffer;
- DISALLOW_COPY_AND_ASSIGN(GLSurfaceGLXQt);
};
}
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 8af3bd3c1..0cbe75cbd 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -1,71 +1,39 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// 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.Chromium file.
-#if !defined(OS_MAC)
+#include "qtwebenginecoreglobal_p.h"
+
+#if !defined(Q_OS_MACOS)
#include "gl_surface_qt.h"
-#include "qtwebenginecoreglobal_p.h"
#include "base/logging.h"
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#include "web_engine_context.h"
#include "ozone/gl_surface_wgl_qt.h"
-#include "ozone/gl_surface_egl_qt.h"
#include "gpu/ipc/service/image_transport_surface.h"
+#include "ui/gl/init/gl_display_initializer.h"
+#include "ui/gl/direct_composition_support.h"
+#include "ui/gl/gl_angle_util_win.h"
+#include "ui/gl/gl_display.h"
#include "ui/gl/gl_implementation.h"
-#include "ui/gl/direct_composition_surface_win.h"
+#include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/gl_utils.h"
#include "ui/gl/vsync_provider_win.h"
#endif
namespace gl {
-void *GLSurfaceQt::g_display = nullptr;
+GLDisplay *GLSurfaceQt::g_display = nullptr;
void *GLSurfaceQt::g_config = nullptr;
-const char *GLSurfaceQt::g_client_extensions = nullptr;
-const char *GLSurfaceQt::g_extensions = nullptr;
+std::string GLSurfaceQt::g_extensions;
GLSurfaceQt::~GLSurfaceQt()
{
@@ -86,7 +54,7 @@ GLSurfaceQt::GLSurfaceQt(const gfx::Size& size)
bool GLSurfaceQt::HasEGLExtension(const char* name)
{
- return ExtensionsContain(g_extensions, name);
+ return ExtensionsContain(g_extensions.c_str(), name);
}
bool GLSurfaceQt::IsOffscreen()
@@ -94,7 +62,7 @@ bool GLSurfaceQt::IsOffscreen()
return true;
}
-gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback)
+gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback, gfx::FrameData data)
{
LOG(ERROR) << "Attempted to call SwapBuffers on a pbuffer.";
Q_UNREACHABLE();
@@ -111,7 +79,7 @@ GLSurfaceFormat GLSurfaceQt::GetFormat()
return m_format;
}
-void* GLSurfaceQt::GetDisplay()
+GLDisplay *GLSurfaceQt::GetGLDisplay()
{
return g_display;
}
@@ -121,28 +89,47 @@ void* GLSurfaceQt::GetConfig()
return g_config;
}
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
namespace init {
-bool InitializeGLOneOffPlatform()
+
+gl::GLDisplay *InitializeGLOneOffPlatform(gl::GpuPreference gpu_preference)
{
VSyncProviderWin::InitializeOneOff();
- if (GetGLImplementation() == kGLImplementationEGLGLES2 || GetGLImplementation() == kGLImplementationEGLANGLE)
- return GLSurfaceEGLQt::InitializeOneOff();
+ if (GetGLImplementation() == kGLImplementationDesktopGL || GetGLImplementation() == kGLImplementationDesktopGLCoreProfile)
+ return GLSurfaceWGLQt::InitializeOneOff(gpu_preference);
- if (GetGLImplementation() == kGLImplementationDesktopGL)
- return GLSurfaceWGLQt::InitializeOneOff();
-
- return false;
+ GLDisplayEGL *display = GetDisplayEGL(gpu_preference);
+ switch (GetGLImplementation()) {
+ case kGLImplementationEGLANGLE:
+ case kGLImplementationEGLGLES2:
+ if (!InitializeDisplay(display, EGLDisplayPlatform(GetDC(nullptr)))) {
+ LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
+ return nullptr;
+ }
+ if (auto d3d11_device = QueryD3D11DeviceObjectFromANGLE())
+ InitializeDirectComposition(std::move(d3d11_device));
+ break;
+ case kGLImplementationMockGL:
+ case kGLImplementationStubGL:
+ break;
+ default:
+ NOTREACHED();
+ }
+ return display;
}
bool usingSoftwareDynamicGL()
{
+#if QT_CONFIG(opengl)
return QtWebEngineCore::usingSoftwareDynamicGL();
+#else
+ return false;
+#endif // QT_CONFIG(opengl)
}
scoped_refptr<GLSurface>
-CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format)
+CreateOffscreenGLSurfaceWithFormat(GLDisplay *display, const gfx::Size& size, GLSurfaceFormat format)
{
scoped_refptr<GLSurface> surface;
switch (GetGLImplementation()) {
@@ -155,21 +142,10 @@ CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format
}
case kGLImplementationEGLANGLE:
case kGLImplementationEGLGLES2: {
- surface = new GLSurfaceEGLQt(size);
- if (surface->Initialize(format))
- return surface;
-
- // Surfaceless context will be used ONLY if pseudo surfaceless context
- // is not available since some implementations of surfaceless context
- // have problems. (e.g. QTBUG-57290)
- if (GLSurfaceEGLQt::g_egl_surfaceless_context_supported) {
- surface = new GLSurfacelessQtEGL(size);
- if (surface->Initialize(format))
- return surface;
- }
- LOG(ERROR) << "eglCreatePbufferSurface failed and surfaceless context not available";
- LOG(WARNING) << "Failed to create offscreen GL surface";
- break;
+ GLDisplayEGL *display_egl = display->GetAs<gl::GLDisplayEGL>();
+ if (display_egl->IsEGLSurfacelessContextSupported() && size.width() == 0 && size.height() == 0)
+ return InitializeGLSurfaceWithFormat(new SurfacelessEGL(display_egl, size), format);
+ return InitializeGLSurfaceWithFormat(new PbufferGLSurfaceEGL(display_egl, size), format);
}
default:
break;
@@ -180,68 +156,13 @@ CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format
}
scoped_refptr<GLSurface>
-CreateViewGLSurface(gfx::AcceleratedWidget window)
+CreateViewGLSurface(GLDisplay *display, gfx::AcceleratedWidget window)
{
- QT_NOT_USED
return nullptr;
}
} // namespace init
-#endif // defined(OS_WIN)
+#endif // BUILDFLAG(IS_WIN)
} // namespace gl
-#if defined(OS_WIN)
-namespace gpu {
-class GpuCommandBufferStub;
-class GpuChannelManager;
-scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface(base::WeakPtr<ImageTransportSurfaceDelegate>,
- SurfaceHandle, gl::GLSurfaceFormat)
-{
- QT_NOT_USED
- return scoped_refptr<gl::GLSurface>();
-}
-} // namespace gpu
-
-namespace gl {
-
-bool DirectCompositionSurfaceWin::IsDirectCompositionSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::IsDecodeSwapChainSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::IsHDRSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::IsSwapChainTearingSupported()
-{
- return false;
-}
-
-bool DirectCompositionSurfaceWin::AreOverlaysSupported()
-{
- return false;
-}
-
-UINT DirectCompositionSurfaceWin::GetOverlaySupportFlags(DXGI_FORMAT format)
-{
- Q_UNUSED(format);
- return 0;
-}
-
-void DirectCompositionSurfaceWin::DisableDecodeSwapChain()
-{
-}
-
-void DirectCompositionSurfaceWin::DisableSoftwareOverlays()
-{
-}
-} // namespace gl
-#endif
-#endif // !defined(OS_MAC)
+#endif // !defined(Q_OS_MACOS)
diff --git a/src/core/ozone/gl_surface_qt.h b/src/core/ozone/gl_surface_qt.h
index 055b27875..1ae41a078 100644
--- a/src/core/ozone/gl_surface_qt.h
+++ b/src/core/ozone/gl_surface_qt.h
@@ -1,47 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_SURFACE_QT_H_
#define GL_SURFACE_QT_H_
+#include <string>
+
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_surface.h"
@@ -54,10 +18,10 @@ public:
static bool HasEGLExtension(const char* name);
// Implement GLSurface.
- void *GetDisplay() override;
+ GLDisplay *GetGLDisplay() override;
void *GetConfig() override;
bool IsOffscreen() override;
- gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
+ gfx::SwapResult SwapBuffers(PresentationCallback callback, gfx::FrameData data) override;
gfx::Size GetSize() override;
GLSurfaceFormat GetFormat() override;
@@ -70,14 +34,10 @@ protected:
public:
static void* g_config;
- static void* g_display;
- static const char* g_extensions;
- static const char* g_client_extensions;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(GLSurfaceQt);
+ static GLDisplay *g_display;
+ static std::string g_extensions;
};
-}
+} // namespace gl
-#endif
+#endif // GL_SURFACE_QT_H_
diff --git a/src/core/ozone/gl_surface_wgl_qt.cpp b/src/core/ozone/gl_surface_wgl_qt.cpp
index ac27a9c20..db4aed884 100644
--- a/src/core/ozone/gl_surface_wgl_qt.cpp
+++ b/src/core/ozone/gl_surface_wgl_qt.cpp
@@ -1,45 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "gl_surface_wgl_qt.h"
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
+#include "ui/gl/gl_display_manager.h"
#include "ui/gl/gl_surface_wgl.h"
namespace gl {
@@ -55,9 +20,12 @@ GLSurfaceWGLQt::~GLSurfaceWGLQt()
Destroy();
}
-bool GLSurfaceWGLQt::InitializeOneOff()
+gl::GLDisplay *GLSurfaceWGLQt::InitializeOneOff(gl::GpuPreference gpu_preference)
{
- return GLSurfaceWGL::InitializeOneOff();
+ if (GLSurfaceWGL::InitializeOneOff())
+ return GLDisplayManagerWGL::GetInstance()->GetDisplay(gpu_preference);
+
+ return nullptr;
}
bool GLSurfaceWGLQt::Initialize(GLSurfaceFormat format)
@@ -77,9 +45,9 @@ void *GLSurfaceWGLQt::GetHandle()
return m_surfaceBuffer->GetHandle();
}
-void *GLSurfaceWGLQt::GetDisplay()
+GLDisplay *GLSurfaceWGLQt::GetGLDisplay()
{
- return m_surfaceBuffer->GetDisplay();
+ return m_surfaceBuffer->GetGLDisplay();
}
void *GLSurfaceWGLQt::GetConfig()
@@ -89,4 +57,4 @@ void *GLSurfaceWGLQt::GetConfig()
} //namespace gl
-#endif // defined(OS_WIN)
+#endif // BUILDFLAG(IS_WIN)
diff --git a/src/core/ozone/gl_surface_wgl_qt.h b/src/core/ozone/gl_surface_wgl_qt.h
index 2b562b61b..6c590e46c 100644
--- a/src/core/ozone/gl_surface_wgl_qt.h
+++ b/src/core/ozone/gl_surface_wgl_qt.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef GL_SURFACE_WGL_QT_H
#define GL_SURFACE_WGL_QT_H
#include "gl_surface_qt.h"
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
namespace gl {
@@ -52,12 +16,12 @@ class GLSurfaceWGLQt: public GLSurfaceQt {
public:
explicit GLSurfaceWGLQt(const gfx::Size& size);
- static bool InitializeOneOff();
+ static gl::GLDisplay *InitializeOneOff(gl::GpuPreference gpu_preference);
bool Initialize(GLSurfaceFormat format) override;
void Destroy() override;
void *GetHandle() override;
- void *GetDisplay() override;
+ GLDisplay *GetGLDisplay() override;
void *GetConfig() override;
protected:
@@ -65,10 +29,9 @@ protected:
private:
scoped_refptr<PbufferGLSurfaceWGL> m_surfaceBuffer;
- DISALLOW_COPY_AND_ASSIGN(GLSurfaceWGLQt);
};
}
-#endif // defined(OS_WIN)
+#endif // BUILDFLAG(IS_WIN)
#endif // GL_SURFACE_WGL_QT_H
diff --git a/src/core/ozone/ozone_extra.gni b/src/core/ozone/ozone_extra.gni
index a832f741a..191bb3787 100644
--- a/src/core/ozone/ozone_extra.gni
+++ b/src/core/ozone/ozone_extra.gni
@@ -17,3 +17,17 @@ ozone_external_platform_deps = []
# so that they get included into ozone_unittests.
# ozone_external_platform_test_deps = [ "platform/foo1:foo1_unitests", ... ]
ozone_external_platform_test_deps = []
+
+# If a platform has integration tests, the corresponding source_set can be
+# listed here so that they get included into ozone_integration_tests.
+ozone_external_platform_integration_test_deps = []
+
+# If a platform has test support files for ui, the corresponding source_set can
+# be listed here so that they get included into ui_test_support.
+# ozone_external_platform_ui_test_support_deps = [ "platform/foo1:ui_test_support", ... ]
+ozone_external_platform_ui_test_support_deps = []
+
+# If a platform has a test support for interactive_ui_tests, the corresponding
+# source_set can be listed here so that they can included into
+# interactive_ui_tests.
+ozone_external_interactive_ui_tests_deps = []
diff --git a/src/core/ozone/ozone_platform_qt.cpp b/src/core/ozone/ozone_platform_qt.cpp
index 33d7bd992..e8547fa87 100644
--- a/src/core/ozone/ozone_platform_qt.cpp
+++ b/src/core/ozone/ozone_platform_qt.cpp
@@ -1,58 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "ozone_platform_qt.h"
#if defined(USE_OZONE)
+#include "base/no_destructor.h"
+#include "base/task/thread_pool.h"
+#include "media/gpu/buildflags.h"
#include "ui/base/buildflags.h"
-#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
#include "ui/base/ime/input_method.h"
#include "ui/display/types/native_display_delegate.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
-#include "ui/ozone/common/stub_client_native_pixmap_factory.h"
+#include "ui/gfx/linux/client_native_pixmap_dmabuf.h"
+#include "ui/gfx/linux/client_native_pixmap_factory_dmabuf.h"
+#include "ui/ozone/common/bitmap_cursor_factory.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/public/gpu_platform_support_host.h"
#include "ui/ozone/public/input_controller.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/platform_screen.h"
#include "ui/ozone/public/system_input_injector.h"
+#include "ui/ozone/platform/wayland/gpu/wayland_gl_egl_utility.h"
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/platform_window/platform_window_init_properties.h"
@@ -60,14 +29,21 @@
#include "platform_window_qt.h"
#if BUILDFLAG(USE_XKBCOMMON)
+#include "base/logging.h"
#include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>
+#include <filesystem>
+#endif // BUILDFLAG(USE_XKBCOMMON)
+
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h"
+#include "ui/ozone/platform/x11/gl_egl_utility_x11.h"
extern void *GetQtXDisplay();
-#endif // BUILDFLAG(USE_XKBCOMMON)
+#endif
namespace ui {
@@ -86,14 +62,31 @@ public:
ui::InputController* GetInputController() override;
std::unique_ptr<ui::SystemInputInjector> CreateSystemInputInjector() override;
ui::OverlayManagerOzone* GetOverlayManager() override;
- std::unique_ptr<InputMethod> CreateInputMethod(internal::InputMethodDelegate *delegate, gfx::AcceleratedWidget widget) override;
+ std::unique_ptr<InputMethod> CreateInputMethod(ImeKeyEventDispatcher *ime_key_event_dispatcher, gfx::AcceleratedWidget widget) override;
std::unique_ptr<ui::PlatformScreen> CreateScreen() override { return nullptr; }
+ const PlatformProperties &GetPlatformProperties() override;
+ PlatformGLEGLUtility *GetPlatformGLEGLUtility() override;
+
+ const PlatformRuntimeProperties &GetPlatformRuntimeProperties() override
+ {
+ static OzonePlatform::PlatformRuntimeProperties properties;
+ if (has_initialized_gpu()) {
+ // This property is set when the GetPlatformRuntimeProperties is
+ // called on the gpu process side.
+ properties.supports_native_pixmaps = surface_factory_ozone_->SupportsNativePixmaps();
+ }
+ return properties;
+ }
+ bool IsNativePixmapConfigSupported(gfx::BufferFormat format, gfx::BufferUsage usage) const override;
+
private:
- void InitializeUI(const ui::OzonePlatform::InitParams &) override;
+ bool InitializeUI(const ui::OzonePlatform::InitParams &) override;
void InitializeGPU(const ui::OzonePlatform::InitParams &) override;
+ void InitScreen(ui::PlatformScreen *) override {}
+
std::unique_ptr<QtWebEngineCore::SurfaceFactoryQt> surface_factory_ozone_;
- std::unique_ptr<CursorFactory> cursor_factory_ozone_;
+ std::unique_ptr<CursorFactory> cursor_factory_;
std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
std::unique_ptr<InputController> input_controller_;
@@ -103,8 +96,7 @@ private:
XkbEvdevCodes m_xkbEvdevCodeConverter;
#endif
std::unique_ptr<KeyboardLayoutEngine> m_keyboardLayoutEngine;
-
- DISALLOW_COPY_AND_ASSIGN(OzonePlatformQt);
+ std::unique_ptr<PlatformGLEGLUtility> gl_egl_utility_;
};
@@ -112,6 +104,21 @@ OzonePlatformQt::OzonePlatformQt() {}
OzonePlatformQt::~OzonePlatformQt() {}
+const ui::OzonePlatform::PlatformProperties &OzonePlatformQt::GetPlatformProperties()
+{
+ static base::NoDestructor<ui::OzonePlatform::PlatformProperties> properties;
+ static bool initialized = false;
+ if (!initialized) {
+ properties->fetch_buffer_formats_for_gmb_on_gpu = true;
+#if BUILDFLAG(USE_VAAPI)
+ properties->supports_vaapi = true;
+#endif
+ initialized = true;
+ }
+
+ return *properties;
+}
+
ui::SurfaceFactoryOzone* OzonePlatformQt::GetSurfaceFactoryOzone()
{
return surface_factory_ozone_.get();
@@ -119,7 +126,7 @@ ui::SurfaceFactoryOzone* OzonePlatformQt::GetSurfaceFactoryOzone()
ui::CursorFactory* OzonePlatformQt::GetCursorFactory()
{
- return cursor_factory_ozone_.get();
+ return cursor_factory_.get();
}
GpuPlatformSupportHost* OzonePlatformQt::GetGpuPlatformSupportHost()
@@ -184,43 +191,27 @@ static std::string getCurrentKeyboardLayout()
if (XkbRF_GetNamesProp(dpy, nullptr, &vdr) == 0)
return std::string();
- char *layout = strtok(vdr.layout, ",");
- for (int i = 0; i < state.group; i++) {
- layout = strtok(nullptr, ",");
- if (layout == nullptr)
- return std::string();
- }
+ if (!vdr.layout)
+ return std::string();
if (!vdr.variant)
- return layout;
-
- char *variant = strtok(vdr.variant, ",");
- if (!variant)
- return layout;
-
- for (int i = 0; i < state.group; i++) {
- variant = strtok(nullptr, ",");
- if (variant == nullptr)
- return layout;
- }
+ return std::string(vdr.layout);
- std::string layoutWithVariant = layout;
+ std::string layoutWithVariant = vdr.layout;
layoutWithVariant = layoutWithVariant.append("-");
- layoutWithVariant = layoutWithVariant.append(variant);
+ layoutWithVariant = layoutWithVariant.append(vdr.variant);
+
return layoutWithVariant;
}
#endif // BUILDFLAG(USE_XKBCOMMON)
-void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &)
+bool OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &)
{
- overlay_manager_.reset(new StubOverlayManager());
- cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone());
- gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost());
- input_controller_ = CreateStubInputController();
-
#if BUILDFLAG(USE_XKBCOMMON)
+ std::string xkb_path("/usr/share/X11/xkb");
std::string layout = getCurrentKeyboardLayout();
- if (layout.empty()) {
+ if (layout.empty() || !std::filesystem::exists(xkb_path) || std::filesystem::is_empty(xkb_path)) {
+ LOG(WARNING) << "Failed to load keymap file, falling back to StubKeyboardLayoutEngine";
m_keyboardLayoutEngine = std::make_unique<StubKeyboardLayoutEngine>();
} else {
m_keyboardLayoutEngine = std::make_unique<XkbKeyboardLayoutEngine>(m_xkbEvdevCodeConverter);
@@ -231,26 +222,60 @@ void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &)
#endif // BUILDFLAG(USE_XKBCOMMON)
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(m_keyboardLayoutEngine.get());
+
+ overlay_manager_.reset(new StubOverlayManager());
+ input_controller_ = CreateStubInputController();
+ cursor_factory_.reset(new BitmapCursorFactory());
+ gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost());
+ return true;
}
-void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &)
+void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &params)
{
surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt());
+
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+ if (params.enable_native_gpu_memory_buffers) {
+ base::ThreadPool::PostTask(FROM_HERE,
+ base::BindOnce([]()
+ {
+ ui::GpuMemoryBufferSupportX11::GetInstance();
+ }));
+ }
+#endif
}
-std::unique_ptr<InputMethod> OzonePlatformQt::CreateInputMethod(internal::InputMethodDelegate *, gfx::AcceleratedWidget)
+std::unique_ptr<InputMethod> OzonePlatformQt::CreateInputMethod(ImeKeyEventDispatcher *, gfx::AcceleratedWidget)
{
NOTREACHED();
return nullptr;
}
+bool OzonePlatformQt::IsNativePixmapConfigSupported(gfx::BufferFormat format, gfx::BufferUsage usage) const
+{
+ return gfx::ClientNativePixmapDmaBuf::IsConfigurationSupported(format, usage);
+}
+
+PlatformGLEGLUtility *OzonePlatformQt::GetPlatformGLEGLUtility()
+{
+ if (!gl_egl_utility_) {
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+ if (GetQtXDisplay())
+ gl_egl_utility_ = std::make_unique<GLEGLUtilityX11>();
+ else
+#endif
+ gl_egl_utility_ = std::make_unique<WaylandGLEGLUtility>();
+ }
+ return gl_egl_utility_.get();
+}
+
} // namespace
OzonePlatform* CreateOzonePlatformQt() { return new OzonePlatformQt; }
-gfx::ClientNativePixmapFactory* CreateClientNativePixmapFactoryQt()
+gfx::ClientNativePixmapFactory *CreateClientNativePixmapFactoryQt()
{
- return CreateStubClientNativePixmapFactory();
+ return gfx::CreateClientNativePixmapFactoryDmabuf();
}
} // namespace ui
diff --git a/src/core/ozone/ozone_platform_qt.h b/src/core/ozone/ozone_platform_qt.h
index dee66beb3..23629b2eb 100644
--- a/src/core/ozone/ozone_platform_qt.h
+++ b/src/core/ozone/ozone_platform_qt.h
@@ -1,55 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef OZONE_PLATFORM_QT_H
#define OZONE_PLATFORM_QT_H
-#if defined(USE_OZONE)
-
-#include "ui/ozone/public/ozone_platform.h"
-
namespace ui {
+class OzonePlatform;
// Constructor hook for use in ozone_platform_list.cc
-OzonePlatform* CreateOzonePlatformQt();
+OzonePlatform *CreateOzonePlatformQt();
} // namespace ui
-#endif // defined(USE_OZONE)
#endif // OZONE_PLATFORM_QT_H
diff --git a/src/core/ozone/platform_window_qt.cpp b/src/core/ozone/platform_window_qt.cpp
index 42af77774..4923f0f88 100644
--- a/src/core/ozone/platform_window_qt.cpp
+++ b/src/core/ozone/platform_window_qt.cpp
@@ -1,46 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#if defined(USE_OZONE)
-#include "base/bind.h"
+#include "base/functional/bind.h"
#include "ozone/platform_window_qt.h"
+#include "ui/base/cursor/platform_cursor.h"
#include "ui/events/ozone/events_ozone.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/platform_window/platform_window_delegate.h"
@@ -59,17 +24,24 @@ PlatformWindowQt::~PlatformWindowQt()
ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
-gfx::Rect PlatformWindowQt::GetBounds() const
+gfx::Rect PlatformWindowQt::GetBoundsInPixels() const
{
return bounds_;
}
-void PlatformWindowQt::SetBounds(const gfx::Rect& bounds)
+void PlatformWindowQt::Close()
+{
+ delegate_->OnClosed();
+}
+
+void PlatformWindowQt::SetBoundsInPixels(const gfx::Rect& bounds)
{
if (bounds == bounds_)
return;
+ const bool origin_changed = (bounds_.origin() != bounds.origin());
+
bounds_ = bounds;
- delegate_->OnBoundsChanged(bounds);
+ delegate_->OnBoundsChanged({origin_changed});
}
bool PlatformWindowQt::CanDispatchEvent(const ui::PlatformEvent& /*ne*/)
@@ -77,11 +49,21 @@ bool PlatformWindowQt::CanDispatchEvent(const ui::PlatformEvent& /*ne*/)
return true;
}
+gfx::Rect PlatformWindowQt::GetBoundsInDIP() const
+{
+ return delegate_->ConvertRectToDIP(bounds_);
+}
+
+void PlatformWindowQt::SetBoundsInDIP(const gfx::Rect &bounds_in_dip)
+{
+ SetBoundsInPixels(delegate_->ConvertRectToPixels(bounds_in_dip));
+}
+
uint32_t PlatformWindowQt::DispatchEvent(const ui::PlatformEvent& native_event)
{
DispatchEventFromNativeUiEvent(
- native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent,
- base::Unretained(delegate_)));
+ native_event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent,
+ base::Unretained(delegate_)));
return ui::POST_DISPATCH_STOP_PROPAGATION;
}
diff --git a/src/core/ozone/platform_window_qt.h b/src/core/ozone/platform_window_qt.h
index 15c1c3faf..c025102bb 100644
--- a/src/core/ozone/platform_window_qt.h
+++ b/src/core/ozone/platform_window_qt.h
@@ -1,47 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PLATFORM_WINDOW_QT_H
#define PLATFORM_WINDOW_QT_H
#if defined(USE_OZONE)
+#include "ui/base/cursor/platform_cursor.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
@@ -56,26 +21,28 @@ public:
PlatformWindowQt(PlatformWindowDelegate* delegate, const gfx::Rect& bounds);
~PlatformWindowQt() override;
// PlatformWindow:
- gfx::Rect GetBounds() const override;
- void SetBounds(const gfx::Rect& bounds) override;
+ gfx::Rect GetBoundsInPixels() const override;
+ void SetBoundsInPixels(const gfx::Rect& bounds) override;
+ gfx::Rect GetBoundsInDIP() const override;
+ void SetBoundsInDIP(const gfx::Rect& bounds) override;
void Show(bool inactive = false) override { }
void Hide() override { }
- void Close() override { }
+ void Close() override;
bool IsVisible() const override { return true; }
- void SetTitle(const base::string16&) override { }
+ void SetTitle(const std::u16string&) override { }
void SetCapture() override { }
void ReleaseCapture() override { }
bool HasCapture() const override { return false; }
- void ToggleFullscreen() override { }
+ void SetFullscreen(bool, int64_t) override { }
void Maximize() override { }
void Minimize() override { }
void Restore() override { }
PlatformWindowState GetPlatformWindowState() const override { return PlatformWindowState::kUnknown; }
- void SetCursor(PlatformCursor) override { }
+ void SetCursor(scoped_refptr<PlatformCursor>) override { }
void MoveCursorTo(const gfx::Point&) override { }
void ConfineCursorToBounds(const gfx::Rect&) override { }
- void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override { }
- gfx::Rect GetRestoredBoundsInPixels() const override { return gfx::Rect(); }
+ void SetRestoredBoundsInDIP(const gfx::Rect& bounds) override { }
+ gfx::Rect GetRestoredBoundsInDIP() const override { return gfx::Rect(); }
void Activate() override { }
void Deactivate() override { }
void SetUseNativeFrame(bool use_native_frame) override { }
@@ -92,8 +59,6 @@ public:
private:
PlatformWindowDelegate* delegate_;
gfx::Rect bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(PlatformWindowQt);
};
}
diff --git a/src/core/ozone/surface_factory_qt.cpp b/src/core/ozone/surface_factory_qt.cpp
index 846d930d6..204f4d62d 100644
--- a/src/core/ozone/surface_factory_qt.cpp
+++ b/src/core/ozone/surface_factory_qt.cpp
@@ -1,78 +1,260 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#if defined(USE_OZONE)
#include "surface_factory_qt.h"
+#include "qtwebenginecoreglobal_p.h"
#include "ozone/gl_context_qt.h"
#include "ozone/gl_ozone_egl_qt.h"
-#if defined(USE_GLX)
+
+#include "media/gpu/buildflags.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/native_pixmap_dmabuf.h"
+#include "ui/gl/egl_util.h"
+#include "ui/ozone/buildflags.h"
+
+#include <QDebug>
+#include <QtGui/qtgui-config.h>
+
+#if BUILDFLAG(OZONE_PLATFORM_X11)
#include "ozone/gl_ozone_glx_qt.h"
+
+#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h"
+#endif
+
+#if QT_CONFIG(webengine_vulkan)
+#include "compositor/vulkan_implementation_qt.h"
#endif
namespace QtWebEngineCore {
SurfaceFactoryQt::SurfaceFactoryQt()
{
-#if defined(USE_GLX)
+#if BUILDFLAG(OZONE_PLATFORM_X11)
if (GLContextHelper::getGlxPlatformInterface()) {
- m_impl = { gl::kGLImplementationDesktopGL };
+ m_impl = { gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
+ gl::GLImplementationParts(gl::kGLImplementationDisabled) };
m_ozone.reset(new ui::GLOzoneGLXQt());
} else
#endif
if (GLContextHelper::getEglPlatformInterface()) {
- m_impl = { gl::kGLImplementationDesktopGL, gl::kGLImplementationEGLGLES2 };
+ m_impl = { gl::GLImplementationParts(gl::kGLImplementationEGLGLES2),
+ gl::GLImplementationParts(gl::kGLImplementationDesktopGL),
+ gl::GLImplementationParts(gl::kGLImplementationDisabled) };
m_ozone.reset(new ui::GLOzoneEGLQt());
} else {
- qFatal("No suitable graphics backend found\n");
+ m_impl = { gl::GLImplementationParts(gl::kGLImplementationDisabled) };
}
}
-std::vector<gl::GLImplementation> SurfaceFactoryQt::GetAllowedGLImplementations()
+std::vector<gl::GLImplementationParts> SurfaceFactoryQt::GetAllowedGLImplementations()
{
return m_impl;
}
-ui::GLOzone* SurfaceFactoryQt::GetGLOzone(gl::GLImplementation implementation)
+ui::GLOzone *SurfaceFactoryQt::GetGLOzone(const gl::GLImplementationParts &implementation)
{
return m_ozone.get();
}
+#if BUILDFLAG(ENABLE_VULKAN)
+std::unique_ptr<gpu::VulkanImplementation>
+SurfaceFactoryQt::CreateVulkanImplementation(bool /*allow_protected_memory*/,
+ bool /*enforce_protected_memory*/)
+{
+#if QT_CONFIG(webengine_vulkan)
+ return std::make_unique<gpu::VulkanImplementationQt>();
+#else
+ return nullptr;
+#endif
+}
+#endif
+
+bool SurfaceFactoryQt::CanCreateNativePixmapForFormat(gfx::BufferFormat format)
+{
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+ if (GLContextHelper::getGlxPlatformInterface())
+ return ui::GpuMemoryBufferSupportX11::GetInstance()->CanCreateNativePixmapForFormat(format);
+#endif
+
+ if (GLContextHelper::getEglPlatformInterface())
+ return ui::SurfaceFactoryOzone::CanCreateNativePixmapForFormat(format);
+
+ return false;
+}
+
+scoped_refptr<gfx::NativePixmap> SurfaceFactoryQt::CreateNativePixmap(
+ gfx::AcceleratedWidget widget,
+ gpu::VulkanDeviceQueue *device_queue,
+ gfx::Size size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ absl::optional<gfx::Size> framebuffer_size)
+{
+ Q_ASSERT(SupportsNativePixmaps());
+
+#if QT_CONFIG(opengl)
+ if (framebuffer_size && !gfx::Rect(size).Contains(gfx::Rect(*framebuffer_size)))
+ return nullptr;
+
+ gfx::NativePixmapHandle handle;
+
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+ if (GLContextHelper::getGlxPlatformInterface()) {
+ auto gbmBuffer =
+ ui::GpuMemoryBufferSupportX11::GetInstance()->CreateBuffer(format, size, usage);
+ if (!gbmBuffer)
+ qFatal("Failed to create GBM buffer for GLX.");
+ handle = gbmBuffer->ExportHandle();
+ }
+#endif
+
+ if (GLContextHelper::getEglPlatformInterface()) {
+ int fd = -1;
+ int stride;
+ int offset;
+ uint64_t modifiers;
+ EGLHelper::instance()->queryDmaBuf(size.width(), size.height(), &fd, &stride, &offset,
+ &modifiers);
+ if (fd == -1)
+ qFatal("Failed to query DRM FD for EGL.");
+
+ const uint64_t planeSize = uint64_t(size.width()) * size.height() * 4;
+ gfx::NativePixmapPlane plane(stride, offset, planeSize, base::ScopedFD(::dup(fd)));
+
+ handle.planes.push_back(std::move(plane));
+ handle.modifier = modifiers;
+ }
+
+ return base::MakeRefCounted<gfx::NativePixmapDmaBuf>(size, format, std::move(handle));
+#else
+ return nullptr;
+#endif // QT_CONFIG(opengl)
+}
+
+void SurfaceFactoryQt::CreateNativePixmapAsync(
+ gfx::AcceleratedWidget widget,
+ gpu::VulkanDeviceQueue *device_queue,
+ gfx::Size size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ NativePixmapCallback callback)
+{
+ Q_ASSERT(SupportsNativePixmaps());
+ // CreateNativePixmap is non-blocking operation. Thus, it is safe to call it
+ // and return the result with the provided callback.
+ std::move(callback).Run(CreateNativePixmap(widget, device_queue, size, format, usage));
+}
+
+scoped_refptr<gfx::NativePixmap>
+SurfaceFactoryQt::CreateNativePixmapFromHandle(
+ gfx::AcceleratedWidget /*widget*/,
+ gfx::Size size,
+ gfx::BufferFormat format,
+ gfx::NativePixmapHandle handle)
+{
+ Q_ASSERT(SupportsNativePixmaps());
+
+#if QT_CONFIG(opengl)
+ gfx::NativePixmapHandle bufferHandle;
+
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+ if (GLContextHelper::getGlxPlatformInterface()) {
+ auto gbmBuffer = ui::GpuMemoryBufferSupportX11::GetInstance()->CreateBufferFromHandle(
+ size, format, std::move(handle));
+ if (!gbmBuffer)
+ qFatal("Failed to create GBM buffer for GLX.");
+ bufferHandle = gbmBuffer->ExportHandle();
+ }
+#endif
+
+ if (GLContextHelper::getEglPlatformInterface()) {
+ const size_t numPlanes = handle.planes.size();
+ const uint32_t fourccFormat = ui::GetFourCCFormatFromBufferFormat(format);
+
+ std::vector<EGLAttrib> attrs;
+ attrs.push_back(EGL_WIDTH);
+ attrs.push_back(size.width());
+ attrs.push_back(EGL_HEIGHT);
+ attrs.push_back(size.height());
+ attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT);
+ attrs.push_back(fourccFormat);
+ for (size_t planeIndex = 0; planeIndex < numPlanes; ++planeIndex) {
+ attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT + planeIndex * 3);
+ attrs.push_back(handle.planes[planeIndex].fd.get());
+ attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + planeIndex * 3);
+ attrs.push_back(handle.planes[planeIndex].offset);
+ attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + planeIndex * 3);
+ attrs.push_back(handle.planes[planeIndex].stride);
+ attrs.push_back(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + planeIndex * 2);
+ attrs.push_back(handle.modifier & 0xffffffff);
+ attrs.push_back(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + planeIndex * 2);
+ attrs.push_back(handle.modifier >> 32);
+ }
+ attrs.push_back(EGL_NONE);
+
+ EGLDisplay eglDisplay = GLContextHelper::getEGLDisplay();
+ EGLHelper *eglHelper = EGLHelper::instance();
+ auto *eglFun = eglHelper->functions();
+
+ EGLImage eglImage =
+ eglFun->eglCreateImage(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
+ (EGLClientBuffer)NULL, attrs.data());
+ if (eglImage == EGL_NO_IMAGE_KHR) {
+ qFatal() << "Failed to import EGLImage:"
+ << ui::GetEGLErrorString(eglFun->eglGetError());
+ }
+
+ Q_ASSERT(numPlanes <= 3);
+ int fds[3];
+ int strides[3];
+ int offsets[3];
+ if (!eglFun->eglExportDMABUFImageMESA(eglDisplay, eglImage, fds, strides, offsets)) {
+ qFatal() << "Failed to export EGLImage:"
+ << ui::GetEGLErrorString(eglFun->eglGetError());
+ }
+
+ bufferHandle.modifier = handle.modifier;
+ for (size_t i = 0; i < numPlanes; ++i) {
+ int fd = fds[i];
+ int stride = strides[i];
+ int offset = offsets[i];
+ int size = handle.planes[i].size;
+
+ if (fd == -1) {
+ fd = fds[0];
+ stride = handle.planes[i].stride;
+ offset = handle.planes[i].offset;
+ }
+
+ gfx::NativePixmapPlane plane(stride, offset, size, base::ScopedFD(::dup(fd)));
+ bufferHandle.planes.push_back(std::move(plane));
+ }
+
+ eglFun->eglDestroyImage(eglDisplay, eglImage);
+ }
+
+ return base::MakeRefCounted<gfx::NativePixmapDmaBuf>(size, format, std::move(bufferHandle));
+#else
+ return nullptr;
+#endif // QT_CONFIG(opengl)
+}
+
+bool SurfaceFactoryQt::SupportsNativePixmaps() const
+{
+#if QT_CONFIG(opengl)
+#if BUILDFLAG(OZONE_PLATFORM_X11)
+ if (GLContextHelper::getGlxPlatformInterface())
+ return ui::GpuMemoryBufferSupportX11::GetInstance()->has_gbm_device();
+#endif // BUILDFLAG(OZONE_PLATFORM_X11)
+
+ if (GLContextHelper::getEglPlatformInterface())
+ return EGLHelper::instance()->isDmaBufSupported();
+#endif // QT_CONFIG(opengl)
+
+ return false;
+}
} // namespace QtWebEngineCore
#endif // defined(USE_OZONE)
diff --git a/src/core/ozone/surface_factory_qt.h b/src/core/ozone/surface_factory_qt.h
index 232f11e0f..07d7337ac 100644
--- a/src/core/ozone/surface_factory_qt.h
+++ b/src/core/ozone/surface_factory_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef SURFACE_FACTORY_QT
#define SURFACE_FACTORY_QT
@@ -50,10 +14,36 @@ class SurfaceFactoryQt : public ui::SurfaceFactoryOzone
{
public:
SurfaceFactoryQt();
- std::vector<gl::GLImplementation> GetAllowedGLImplementations() override;
- ui::GLOzone* GetGLOzone(gl::GLImplementation implementation) override;
+ std::vector<gl::GLImplementationParts> GetAllowedGLImplementations() override;
+ ui::GLOzone *GetGLOzone(const gl::GLImplementationParts &implementation) override;
+#if BUILDFLAG(ENABLE_VULKAN)
+ std::unique_ptr<gpu::VulkanImplementation>
+ CreateVulkanImplementation(bool allow_protected_memory, bool enforce_protected_memory) override;
+#endif
+ bool CanCreateNativePixmapForFormat(gfx::BufferFormat format) override;
+ scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
+ gfx::AcceleratedWidget widget,
+ gpu::VulkanDeviceQueue* device_queue,
+ gfx::Size size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ absl::optional<gfx::Size> framebuffer_size = absl::nullopt) override;
+ void CreateNativePixmapAsync(gfx::AcceleratedWidget widget,
+ gpu::VulkanDeviceQueue* device_queue,
+ gfx::Size size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ NativePixmapCallback callback) override;
+ scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandle(
+ gfx::AcceleratedWidget widget,
+ gfx::Size size,
+ gfx::BufferFormat format,
+ gfx::NativePixmapHandle handle) override;
+
+ bool SupportsNativePixmaps() const;
+
private:
- std::vector<gl::GLImplementation> m_impl;
+ std::vector<gl::GLImplementationParts> m_impl;
std::unique_ptr<ui::GLOzone> m_ozone;
};
diff --git a/src/core/pdf_util_qt.cpp b/src/core/pdf_util_qt.cpp
new file mode 100644
index 000000000..9503f5910
--- /dev/null
+++ b/src/core/pdf_util_qt.cpp
@@ -0,0 +1,92 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// Copyright 2021 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.Chromium file.
+
+#include "pdf_util_qt.h"
+
+#include <QtGlobal>
+
+#include "base/check.h"
+#include "chrome/common/webui_url_constants.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 "extensions/buildflags/buildflags.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/common/constants.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
+namespace QtWebEngineCore {
+
+bool IsPdfExtensionOrigin(const url::Origin &origin)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ return origin.scheme() == extensions::kExtensionScheme
+ && origin.host() == extension_misc::kPdfExtensionId;
+#else
+ Q_UNUSED(origin);
+ return false;
+#endif
+}
+
+bool IsPdfInternalPluginAllowedOrigin(const url::Origin &origin)
+{
+ if (IsPdfExtensionOrigin(origin))
+ return true;
+
+ // Allow embedding the internal PDF plugin in chrome://print.
+ if (origin == url::Origin::Create(GURL(chrome::kChromeUIPrintURL)))
+ return true;
+
+ // Only allow the PDF plugin in the known, trustworthy origins that are
+ // allowlisted above. See also https://crbug.com/520422 and
+ // https://crbug.com/1027173.
+ return false;
+}
+
+content::RenderFrameHost *GetFullPagePlugin(content::WebContents *contents)
+{
+ content::RenderFrameHost *full_page_plugin = nullptr;
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ contents->ForEachRenderFrameHostWithAction([&full_page_plugin](content::RenderFrameHost *rfh) {
+ auto* guest_view = extensions::MimeHandlerViewGuest::FromRenderFrameHost(rfh);
+ if (guest_view && guest_view->is_full_page_plugin()) {
+ DCHECK_EQ(guest_view->GetGuestMainFrame(), rfh);
+ full_page_plugin = rfh;
+ return content::RenderFrameHost::FrameIterationAction::kStop;
+ }
+ return content::RenderFrameHost::FrameIterationAction::kContinue;
+ });
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+ return full_page_plugin;
+}
+
+content::RenderFrameHost *FindPdfChildFrame(content::RenderFrameHost *rfh)
+{
+ if (!rfh)
+ return nullptr;
+
+ if (!IsPdfExtensionOrigin(rfh->GetLastCommittedOrigin()))
+ return nullptr;
+
+ content::RenderFrameHost *pdf_rfh = nullptr;
+ rfh->ForEachRenderFrameHost([&pdf_rfh](content::RenderFrameHost *rfh) {
+ if (!rfh->GetProcess()->IsPdf())
+ return;
+
+ DCHECK(IsPdfExtensionOrigin(rfh->GetParent()->GetLastCommittedOrigin()));
+ DCHECK(!pdf_rfh);
+ pdf_rfh = rfh;
+ });
+
+ return pdf_rfh;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/pdf_util_qt.h b/src/core/pdf_util_qt.h
new file mode 100644
index 000000000..5ee211800
--- /dev/null
+++ b/src/core/pdf_util_qt.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// Copyright 2021 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.Chromium file.
+
+#ifndef PDF_UTIL_QT_H
+#define PDF_UTIL_QT_H
+
+namespace content {
+class RenderFrameHost;
+class WebContents;
+} // namespace content
+
+namespace url {
+class Origin;
+} // namespace url
+
+namespace QtWebEngineCore {
+
+// from chrome/common/pdf_util.cc:
+constexpr char kPDFMimeType[] = "application/pdf";
+
+bool IsPdfExtensionOrigin(const url::Origin &origin);
+bool IsPdfInternalPluginAllowedOrigin(const url::Origin &origin);
+
+// from chrome/browser/pdf/pdf_frame_util.cc:
+content::RenderFrameHost *GetFullPagePlugin(content::WebContents *contents);
+content::RenderFrameHost *FindPdfChildFrame(content::RenderFrameHost *rfh);
+
+} // namespace QtWebEngineCore
+
+#endif // PDF_UTIL_QT_H
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index e6db004de..b6e727ef8 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -1,50 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "permission_manager_qt.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/permission_controller.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 "third_party/blink/public/common/permissions/permission_utils.h"
#include "type_conversion.h"
#include "web_contents_delegate_qt.h"
@@ -52,44 +16,47 @@
namespace QtWebEngineCore {
-static ProfileAdapter::PermissionType toQt(content::PermissionType type)
+static ProfileAdapter::PermissionType toQt(blink::PermissionType type)
{
switch (type) {
- case content::PermissionType::GEOLOCATION:
+ case blink::PermissionType::GEOLOCATION:
return ProfileAdapter::GeolocationPermission;
- case content::PermissionType::AUDIO_CAPTURE:
+ case blink::PermissionType::AUDIO_CAPTURE:
return ProfileAdapter::AudioCapturePermission;
- case content::PermissionType::VIDEO_CAPTURE:
+ case blink::PermissionType::VIDEO_CAPTURE:
return ProfileAdapter::VideoCapturePermission;
- case content::PermissionType::CLIPBOARD_READ_WRITE:
- return ProfileAdapter::ClipboardRead;
- case content::PermissionType::CLIPBOARD_SANITIZED_WRITE:
- return ProfileAdapter::ClipboardWrite;
- case content::PermissionType::NOTIFICATIONS:
+ // We treat these both as read/write since we do not currently have a
+ // ClipboardSanitizedWrite feature.
+ case blink::PermissionType::CLIPBOARD_READ_WRITE:
+ case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
+ return ProfileAdapter::ClipboardReadWrite;
+ case blink::PermissionType::NOTIFICATIONS:
return ProfileAdapter::NotificationPermission;
- case content::PermissionType::ACCESSIBILITY_EVENTS:
- case content::PermissionType::CAMERA_PAN_TILT_ZOOM:
- case content::PermissionType::WINDOW_PLACEMENT:
+ case blink::PermissionType::LOCAL_FONTS:
+ return ProfileAdapter::LocalFontsPermission;
+ case blink::PermissionType::ACCESSIBILITY_EVENTS:
+ case blink::PermissionType::CAMERA_PAN_TILT_ZOOM:
+ case blink::PermissionType::WINDOW_MANAGEMENT:
return ProfileAdapter::UnsupportedPermission;
- case content::PermissionType::MIDI_SYSEX:
- case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
- case content::PermissionType::MIDI:
- case content::PermissionType::DURABLE_STORAGE:
- case content::PermissionType::BACKGROUND_SYNC:
- case content::PermissionType::SENSORS:
- case content::PermissionType::PAYMENT_HANDLER:
- case content::PermissionType::BACKGROUND_FETCH:
- case content::PermissionType::IDLE_DETECTION:
- case content::PermissionType::PERIODIC_BACKGROUND_SYNC:
- case content::PermissionType::WAKE_LOCK_SCREEN:
- case content::PermissionType::WAKE_LOCK_SYSTEM:
- case content::PermissionType::NFC:
- case content::PermissionType::AR:
- case content::PermissionType::VR:
- case content::PermissionType::STORAGE_ACCESS_GRANT:
- case content::PermissionType::FONT_ACCESS:
- case content::PermissionType::DISPLAY_CAPTURE:
- case content::PermissionType::NUM:
+ case blink::PermissionType::MIDI_SYSEX:
+ case blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
+ case blink::PermissionType::MIDI:
+ case blink::PermissionType::DURABLE_STORAGE:
+ case blink::PermissionType::BACKGROUND_SYNC:
+ case blink::PermissionType::SENSORS:
+ case blink::PermissionType::PAYMENT_HANDLER:
+ case blink::PermissionType::BACKGROUND_FETCH:
+ case blink::PermissionType::IDLE_DETECTION:
+ case blink::PermissionType::PERIODIC_BACKGROUND_SYNC:
+ case blink::PermissionType::WAKE_LOCK_SCREEN:
+ case blink::PermissionType::WAKE_LOCK_SYSTEM:
+ case blink::PermissionType::NFC:
+ case blink::PermissionType::AR:
+ case blink::PermissionType::VR:
+ case blink::PermissionType::STORAGE_ACCESS_GRANT:
+ case blink::PermissionType::DISPLAY_CAPTURE:
+ case blink::PermissionType::TOP_LEVEL_STORAGE_ACCESS:
+ case blink::PermissionType::NUM:
LOG(INFO) << "Unexpected unsupported permission type: " << static_cast<int>(type);
break;
}
@@ -101,6 +68,8 @@ static bool canRequestPermissionFor(ProfileAdapter::PermissionType type)
switch (type) {
case ProfileAdapter::GeolocationPermission:
case ProfileAdapter::NotificationPermission:
+ case ProfileAdapter::ClipboardReadWrite:
+ case ProfileAdapter::LocalFontsPermission:
return true;
default:
break;
@@ -120,6 +89,20 @@ static blink::mojom::PermissionStatus toBlink(ProfileAdapter::PermissionState re
}
}
+static blink::mojom::PermissionStatus getStatusFromSettings(blink::PermissionType type, WebEngineSettings *settings)
+{
+ switch (type) {
+ case blink::PermissionType::CLIPBOARD_READ_WRITE:
+ case blink::PermissionType::CLIPBOARD_SANITIZED_WRITE:
+ if (settings->testAttribute(QWebEngineSettings::JavascriptCanPaste)
+ && settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard))
+ return blink::mojom::PermissionStatus::GRANTED;
+ return blink::mojom::PermissionStatus::ASK;
+ default:
+ return blink::mojom::PermissionStatus::ASK;
+ }
+}
+
PermissionManagerQt::PermissionManagerQt()
: m_requestIdCount(0)
{
@@ -131,8 +114,8 @@ PermissionManagerQt::~PermissionManagerQt()
void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter::PermissionType type, ProfileAdapter::PermissionState reply)
{
- // Normalize the QUrl to GURL origin form.
- const GURL gorigin = toGurl(url).GetOrigin();
+ // Normalize the QUrl to Chromium origin form.
+ const GURL gorigin = toGurl(url).DeprecatedGetOriginAsURL();
const QUrl origin = gorigin.is_empty() ? url : toQt(gorigin);
if (origin.isEmpty())
return;
@@ -166,7 +149,7 @@ void PermissionManagerQt::permissionRequestReply(const QUrl &url, ProfileAdapter
bool answerable = true;
std::vector<blink::mojom::PermissionStatus> result;
result.reserve(it->types.size());
- for (content::PermissionType permission : it->types) {
+ for (blink::PermissionType permission : it->types) {
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::UnsupportedPermission) {
result.push_back(blink::mojom::PermissionStatus::DENIED);
@@ -199,51 +182,13 @@ bool PermissionManagerQt::checkPermission(const QUrl &origin, ProfileAdapter::Pe
return m_permissions.contains(key) && m_permissions[key];
}
-int PermissionManagerQt::RequestPermission(content::PermissionType permission,
- content::RenderFrameHost *frameHost,
- const GURL& requesting_origin,
- bool /*user_gesture*/,
- base::OnceCallback<void(blink::mojom::PermissionStatus)> callback)
+void PermissionManagerQt::RequestPermissions(content::RenderFrameHost *frameHost,
+ const content::PermissionRequestDescription &requestDescription,
+ base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
{
- if (requesting_origin.is_empty()) {
- std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
- return content::PermissionController::kNoPendingOperation;
- }
-
- WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
- content::WebContents::FromRenderFrameHost(frameHost)->GetDelegate());
- Q_ASSERT(contentsDelegate);
-
- ProfileAdapter::PermissionType permissionType = toQt(permission);
- if (permissionType == ProfileAdapter::ClipboardRead) {
- WebEngineSettings *settings = contentsDelegate->webEngineSettings();
- if (settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard)
- && settings->testAttribute(QWebEngineSettings::JavascriptCanPaste))
- std::move(callback).Run(blink::mojom::PermissionStatus::GRANTED);
- else
- std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
- return content::PermissionController::kNoPendingOperation;
- } else if (!canRequestPermissionFor(permissionType)) {
- std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
- return content::PermissionController::kNoPendingOperation;
- }
-
- int request_id = ++m_requestIdCount;
- auto requestOrigin = toQt(requesting_origin);
- m_requests.push_back({ request_id, permissionType, requestOrigin, std::move(callback) });
- contentsDelegate->requestFeaturePermission(permissionType, requestOrigin);
- return request_id;
-}
-
-int PermissionManagerQt::RequestPermissions(const std::vector<content::PermissionType>& permissions,
- content::RenderFrameHost* frameHost,
- const GURL& requesting_origin,
- bool /*user_gesture*/,
- base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
-{
- if (requesting_origin.is_empty()) {
- std::move(callback).Run(std::vector<blink::mojom::PermissionStatus>(permissions.size(), blink::mojom::PermissionStatus::DENIED));
- return content::PermissionController::kNoPendingOperation;
+ if (requestDescription.requesting_origin.is_empty()) {
+ std::move(callback).Run(std::vector<content::PermissionStatus>(requestDescription.permissions.size(), blink::mojom::PermissionStatus::DENIED));
+ return;
}
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
@@ -251,42 +196,47 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
Q_ASSERT(contentsDelegate);
bool answerable = true;
- std::vector<blink::mojom::PermissionStatus> result;
- result.reserve(permissions.size());
- for (content::PermissionType permission : permissions) {
+ std::vector<content::PermissionStatus> result;
+ result.reserve(requestDescription.permissions.size());
+ for (blink::PermissionType permission : requestDescription.permissions) {
const ProfileAdapter::PermissionType permissionType = toQt(permission);
- if (permissionType == ProfileAdapter::UnsupportedPermission)
+ if (permissionType == ProfileAdapter::UnsupportedPermission) {
result.push_back(blink::mojom::PermissionStatus::DENIED);
- else if (permissionType == ProfileAdapter::ClipboardRead) {
- WebEngineSettings *settings = contentsDelegate->webEngineSettings();
- if (settings->testAttribute(QWebEngineSettings::JavascriptCanAccessClipboard)
- && settings->testAttribute(QWebEngineSettings::JavascriptCanPaste))
- result.push_back(blink::mojom::PermissionStatus::GRANTED);
- else
- result.push_back(blink::mojom::PermissionStatus::DENIED);
- } else {
+ continue;
+ }
+
+ auto status = getStatusFromSettings(permission, contentsDelegate->webEngineSettings());
+ if (status == blink::mojom::PermissionStatus::ASK) {
answerable = false;
break;
- }
+ } else
+ result.push_back(status);
}
if (answerable) {
std::move(callback).Run(result);
- return content::PermissionController::kNoPendingOperation;
+ return;
}
int request_id = ++m_requestIdCount;
- auto requestOrigin = toQt(requesting_origin);
- m_multiRequests.push_back({ request_id, permissions, requestOrigin, std::move(callback) });
- for (content::PermissionType permission : permissions) {
+ auto requestOrigin = toQt(requestDescription.requesting_origin);
+ m_multiRequests.push_back({ request_id, requestDescription.permissions, requestOrigin, std::move(callback) });
+ for (blink::PermissionType permission : requestDescription.permissions) {
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (canRequestPermissionFor(permissionType))
contentsDelegate->requestFeaturePermission(permissionType, requestOrigin);
}
- return request_id;
+}
+
+void PermissionManagerQt::RequestPermissionsFromCurrentDocument(content::RenderFrameHost *frameHost,
+ const content::PermissionRequestDescription &requestDescription,
+ base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
+{
+
+ RequestPermissions(frameHost, requestDescription, std::move(callback));
}
blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& /*embedding_origin*/)
{
@@ -302,33 +252,56 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatus(
return blink::mojom::PermissionStatus::DENIED;
}
-blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForFrame(
- content::PermissionType permission,
- content::RenderFrameHost *render_frame_host,
- const GURL &requesting_origin)
+blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForCurrentDocument(
+ blink::PermissionType permission,
+ content::RenderFrameHost *render_frame_host)
{
- if (permission == content::PermissionType::CLIPBOARD_READ_WRITE ||
- permission == content::PermissionType::CLIPBOARD_SANITIZED_WRITE) {
+ if (permission == blink::PermissionType::CLIPBOARD_READ_WRITE ||
+ permission == blink::PermissionType::CLIPBOARD_SANITIZED_WRITE) {
WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(
content::WebContents::FromRenderFrameHost(render_frame_host)->GetDelegate());
- if (!delegate->webEngineSettings()->testAttribute(
- QWebEngineSettings::JavascriptCanAccessClipboard))
- return blink::mojom::PermissionStatus::DENIED;
- if (permission == content::PermissionType::CLIPBOARD_READ_WRITE
- && !delegate->webEngineSettings()->testAttribute(
- QWebEngineSettings::JavascriptCanPaste))
- return blink::mojom::PermissionStatus::DENIED;
- return blink::mojom::PermissionStatus::GRANTED;
+ Q_ASSERT(delegate);
+ auto status = getStatusFromSettings(permission, delegate->webEngineSettings());
+ if (status != blink::mojom::PermissionStatus::ASK)
+ return status;
}
return GetPermissionStatus(
permission,
- requesting_origin,
- content::WebContents::FromRenderFrameHost(render_frame_host)->GetLastCommittedURL().GetOrigin());
+ render_frame_host->GetLastCommittedOrigin().GetURL(),
+ render_frame_host->GetLastCommittedOrigin().GetURL());
+}
+
+blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForWorker(
+ blink::PermissionType permission,
+ content::RenderProcessHost *render_process_host,
+ const GURL &url)
+{
+ return GetPermissionStatus(permission, url, url);
+}
+
+blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForEmbeddedRequester(
+ blink::PermissionType permission,
+ content::RenderFrameHost *render_frame_host,
+ const url::Origin &requesting_origin)
+{
+ return GetPermissionStatus(permission, requesting_origin.GetURL(),
+ render_frame_host->GetLastCommittedOrigin().GetURL());
+}
+
+content::PermissionResult PermissionManagerQt::GetPermissionResultForOriginWithoutContext(
+ blink::PermissionType permission,
+ const url::Origin &requesting_origin,
+ const url::Origin &embedding_origin)
+{
+ blink::mojom::PermissionStatus status =
+ GetPermissionStatus(permission, requesting_origin.GetURL(), embedding_origin.GetURL());
+
+ return content::PermissionResult(status, content::PermissionStatusSource::UNSPECIFIED);
}
void PermissionManagerQt::ResetPermission(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& /*embedding_origin*/)
{
@@ -341,7 +314,8 @@ void PermissionManagerQt::ResetPermission(
}
content::PermissionControllerDelegate::SubscriptionId PermissionManagerQt::SubscribePermissionStatusChange(
- content::PermissionType permission,
+ blink::PermissionType permission,
+ content::RenderProcessHost * /*render_process_host*/,
content::RenderFrameHost * /* render_frame_host */,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h
index f8d7e0ee3..b91498d3d 100644
--- a/src/core/permission_manager_qt.h
+++ b/src/core/permission_manager_qt.h
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PERMISSION_MANAGER_QT_H
#define PERMISSION_MANAGER_QT_H
-#include "base/callback.h"
+#include "base/functional/callback.h"
#include "content/public/browser/permission_controller_delegate.h"
#include "profile_adapter.h"
@@ -49,8 +13,8 @@
namespace QtWebEngineCore {
-class PermissionManagerQt : public content::PermissionControllerDelegate {
-
+class PermissionManagerQt : public content::PermissionControllerDelegate
+{
public:
PermissionManagerQt();
~PermissionManagerQt();
@@ -59,38 +23,37 @@ public:
bool checkPermission(const QUrl &origin, ProfileAdapter::PermissionType type);
// content::PermissionManager implementation:
- int RequestPermission(
- content::PermissionType permission,
- content::RenderFrameHost* render_frame_host,
- const GURL& requesting_origin,
- bool user_gesture,
- base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) override;
-
blink::mojom::PermissionStatus GetPermissionStatus(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
- blink::mojom::PermissionStatus GetPermissionStatusForFrame(
- content::PermissionType permission,
- content::RenderFrameHost *render_frame_host,
- const GURL& requesting_origin) override;
+ blink::mojom::PermissionStatus GetPermissionStatusForCurrentDocument(blink::PermissionType, content::RenderFrameHost *) override;
+
+ blink::mojom::PermissionStatus GetPermissionStatusForWorker(blink::PermissionType, content::RenderProcessHost *, const GURL &) override;
+
+ blink::mojom::PermissionStatus GetPermissionStatusForEmbeddedRequester(blink::PermissionType, content::RenderFrameHost*, const url::Origin&) override;
+
+ content::PermissionResult GetPermissionResultForOriginWithoutContext(blink::PermissionType, const url::Origin&, const url::Origin&) override;
void ResetPermission(
- content::PermissionType permission,
+ blink::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override;
- int RequestPermissions(
- const std::vector<content::PermissionType>& permission,
- content::RenderFrameHost* render_frame_host,
- const GURL& requesting_origin,
- bool user_gesture,
- base::OnceCallback<void(
- const std::vector<blink::mojom::PermissionStatus>&)> callback) override;
+ void RequestPermissions(
+ content::RenderFrameHost *render_frame_host,
+ const content::PermissionRequestDescription &request_description,
+ base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback) override;
+
+ void RequestPermissionsFromCurrentDocument(
+ content::RenderFrameHost *render_frame_host,
+ const content::PermissionRequestDescription &request_description,
+ base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus> &)> callback) override;
content::PermissionControllerDelegate::SubscriptionId SubscribePermissionStatusChange(
- content::PermissionType permission,
+ blink::PermissionType permission,
+ content::RenderProcessHost* render_process_host,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
const base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) override;
@@ -107,7 +70,7 @@ private:
};
struct MultiRequest {
int id;
- std::vector<content::PermissionType> types;
+ std::vector<blink::PermissionType> types;
QUrl origin;
base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback;
};
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
index 5f3017dcf..182a5ad84 100644
--- a/src/core/platform_notification_service_qt.cpp
+++ b/src/core/platform_notification_service_qt.cpp
@@ -1,48 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "platform_notification_service_qt.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/permission_type.h"
#include "content/public/browser/notification_event_dispatcher.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
@@ -50,7 +13,6 @@
#include "profile_adapter_client.h"
#include "profile_qt.h"
#include "user_notification_controller.h"
-#include "resource_context_qt.h"
#include "type_conversion.h"
#include <QSharedPointer>
@@ -90,7 +52,7 @@ struct PersistentNotificationDelegate : UserNotificationController::Delegate {
virtual void clicked() override {
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (auto inst = content::NotificationEventDispatcher::GetInstance())
- inst->DispatchNotificationClickEvent(browser_context, notification_id, origin, base::nullopt, base::nullopt, base::DoNothing());
+ inst->DispatchNotificationClickEvent(browser_context, notification_id, origin, absl::nullopt, absl::nullopt, base::DoNothing());
}
virtual void closed(bool by_user) override {
@@ -114,6 +76,7 @@ PlatformNotificationServiceQt::~PlatformNotificationServiceQt() {}
void PlatformNotificationServiceQt::DisplayNotification(
const std::string &notification_id,
const GURL &origin,
+ const GURL &document_url,
const blink::PlatformNotificationData &notificationData,
const blink::NotificationResources &notificationResources)
{
diff --git a/src/core/platform_notification_service_qt.h b/src/core/platform_notification_service_qt.h
index 12aa2619b..bf8fcca04 100644
--- a/src/core/platform_notification_service_qt.h
+++ b/src/core/platform_notification_service_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PLATFORM_NOTIFICATION_SERVICE_QT_H
#define PLATFORM_NOTIFICATION_SERVICE_QT_H
@@ -58,6 +22,7 @@ public:
// |cancel_callback| argument. This method must be called on the UI thread.
void DisplayNotification(const std::string& notification_id,
const GURL& origin,
+ const GURL& document_url,
const blink::PlatformNotificationData& notificationData,
const blink::NotificationResources& notificationResources) override;
diff --git a/src/core/pointer_device_qt.cpp b/src/core/pointer_device_qt.cpp
new file mode 100644
index 000000000..a3d7f3d37
--- /dev/null
+++ b/src/core/pointer_device_qt.cpp
@@ -0,0 +1,102 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chromium/ui/base/pointer/pointer_device_linux.cc
+// Copyright (c) 2013 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 "ui/base/pointer/pointer_device.h"
+
+#include <algorithm>
+#include <QPointingDevice>
+
+namespace ui {
+
+namespace {
+
+bool IsTouchScreen(const QInputDevice *device)
+{
+ return device->type() & QPointingDevice::DeviceType::TouchScreen;
+}
+
+bool IsMouseOrTouchpad(const QInputDevice *device)
+{
+ return device->type()
+ & (QPointingDevice::DeviceType::TouchPad | QPointingDevice::DeviceType::Mouse);
+}
+
+bool IsTouchDevicePresent()
+{
+ QList<const QInputDevice *> devices = QInputDevice::devices();
+ return std::any_of(devices.constBegin(), devices.constEnd(), IsTouchScreen);
+}
+
+bool IsMouseOrTouchpadPresent()
+{
+ QList<const QInputDevice *> devices = QInputDevice::devices();
+ return std::any_of(devices.constBegin(), devices.constEnd(), IsMouseOrTouchpad);
+}
+
+} // namespace
+
+int GetAvailablePointerTypes()
+{
+ int available_pointer_types = POINTER_TYPE_NONE;
+ if (IsMouseOrTouchpadPresent())
+ available_pointer_types |= POINTER_TYPE_FINE;
+
+ if (IsTouchDevicePresent())
+ available_pointer_types |= POINTER_TYPE_COARSE;
+
+ return available_pointer_types;
+}
+
+int GetAvailableHoverTypes()
+{
+ if (IsMouseOrTouchpadPresent())
+ return HOVER_TYPE_HOVER;
+
+ return HOVER_TYPE_NONE;
+}
+
+TouchScreensAvailability GetTouchScreensAvailability()
+{
+ if (!IsTouchDevicePresent())
+ return TouchScreensAvailability::NONE;
+
+ return TouchScreensAvailability::ENABLED;
+}
+
+int MaxTouchPoints()
+{
+ int max_touch = 0;
+ for (const auto *device : QInputDevice::devices()) {
+ if (IsTouchScreen(device)) {
+ int points = static_cast<const QPointingDevice *>(device)->maximumPoints();
+ max_touch = points > max_touch ? points : max_touch;
+ }
+ }
+
+ return max_touch;
+}
+
+PointerType GetPrimaryPointerType(int available_pointer_types)
+{
+ if (available_pointer_types & POINTER_TYPE_FINE)
+ return POINTER_TYPE_FINE;
+ if (available_pointer_types & POINTER_TYPE_COARSE)
+ return POINTER_TYPE_COARSE;
+ Q_ASSERT(available_pointer_types == POINTER_TYPE_NONE);
+ return POINTER_TYPE_NONE;
+}
+
+HoverType GetPrimaryHoverType(int available_hover_types)
+{
+ if (available_hover_types & HOVER_TYPE_HOVER)
+ return HOVER_TYPE_HOVER;
+ Q_ASSERT(available_hover_types == HOVER_TYPE_NONE);
+ return HOVER_TYPE_NONE;
+}
+
+} // namespace ui
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 9fcb16584..544a84de1 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "pref_service_adapter.h"
@@ -43,8 +7,10 @@
#include "type_conversion.h"
#include "web_engine_context.h"
+#include "base/threading/thread_restrictions.h"
#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
#include "content/public/browser/browser_thread.h"
+#include "components/autofill/core/common/autofill_prefs.h"
#include "components/language/core/browser/pref_names.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/in_memory_pref_store.h"
@@ -52,12 +18,17 @@
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/pref_registry_simple.h"
+#include "components/signin/internal/identity_manager/account_tracker_service.h"
+#include "components/signin/public/base/signin_pref_names.h"
#include "components/user_prefs/user_prefs.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "chrome/common/pref_names.h"
#include "extensions/buildflags/buildflags.h"
#include "content/public/browser/browser_context.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "chrome/browser/devtools/devtools_settings.h"
+
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "components/spellcheck/browser/pref_names.h"
@@ -71,6 +42,10 @@
#include "extensions/common/constants.h"
#endif
+#if defined(Q_OS_WIN)
+#include "components/os_crypt/sync/os_crypt.h"
+#endif
+
namespace {
static const char kPrefMediaDeviceIDSalt[] = "qtwebengine.media_device_salt_id";
}
@@ -82,15 +57,16 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
PrefServiceFactory factory;
factory.set_command_line_prefs(base::MakeRefCounted<ChromeCommandLinePrefStore>(
- WebEngineContext::commandLine()));
+ base::CommandLine::ForCurrentProcess()));
QString userPrefStorePath = profileAdapter.dataPath();
- if (profileAdapter.isOffTheRecord() || profileAdapter.storageName().isEmpty()) {
- factory.set_user_prefs(new InMemoryPrefStore);
- } else {
+ if (!profileAdapter.isOffTheRecord() && !userPrefStorePath.isEmpty() &&
+ const_cast<ProfileAdapter *>(&profileAdapter)->ensureDataPathExists()) {
userPrefStorePath += QDir::separator();
userPrefStorePath += QStringLiteral("user_prefs.json");
factory.set_user_prefs(base::MakeRefCounted<JsonPrefStore>(toFilePath(userPrefStorePath)));
+ } else {
+ factory.set_user_prefs(new InMemoryPrefStore);
}
auto registry = base::MakeRefCounted<PrefRegistrySimple>();
@@ -101,7 +77,6 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
registry->RegisterStringPref(language::prefs::kAcceptLanguages, std::string());
registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries);
registry->RegisterListPref(spellcheck::prefs::kSpellCheckForcedDictionaries);
- registry->RegisterListPref(spellcheck::prefs::kSpellCheckBlacklistedDictionaries);
registry->RegisterListPref(spellcheck::prefs::kSpellCheckBlocklistedDictionaries);
registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string());
registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckEnable, false);
@@ -110,6 +85,19 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
registry->RegisterBooleanPref(prefs::kAccessibilityImageLabelsEnabled, false);
registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
+ registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap);
+ registry->RegisterListPref(prefs::kAccountInfo);
+ registry->RegisterStringPref(prefs::kGoogleServicesLastUsername,
+ std::string());
+ registry->RegisterStringPref(prefs::kGoogleServicesAccountId, std::string());
+ registry->RegisterBooleanPref(prefs::kGoogleServicesConsentedToSync, false);
+ registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
+ registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
+ registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
+ registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
+#if defined(Q_OS_WIN)
+ OSCrypt::RegisterLocalPrefs(registry.get());
+#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
registry->RegisterDictionaryPref(extensions::pref_names::kExtensions);
@@ -123,6 +111,7 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
registry->RegisterListPref(extensions::pref_names::kNativeMessagingBlocklist);
registry->RegisterListPref(extensions::pref_names::kNativeMessagingAllowlist);
registry->RegisterBooleanPref(extensions::pref_names::kNativeMessagingUserLevelHosts, true);
+ registry->RegisterListPref(extensions::pref_names::kExtendedBackgroundLifetimeForPortConnectionsToUrls);
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
// Media device salt id key
@@ -130,12 +119,28 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
// default value will be different. We'll need to initialize it later.
registry->RegisterStringPref(kPrefMediaDeviceIDSalt, std::string());
- m_prefService = factory.Create(registry);
-
- // Initialize salt value if none was stored before
- if (m_prefService->GetString(kPrefMediaDeviceIDSalt).empty()) {
- m_prefService->SetString(kPrefMediaDeviceIDSalt,
- content::BrowserContext::CreateRandomMediaDeviceIDSalt());
+ registry->RegisterBooleanPref(autofill::prefs::kAutofillEnabledDeprecated, false);
+ registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled, false);
+ registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardEnabled, false);
+ registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardFidoAuthEnabled, false);
+
+ // devtools
+ registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
+ registry->RegisterDictionaryPref(prefs::kDevToolsEditedFiles);
+ registry->RegisterDictionaryPref(prefs::kDevToolsPreferences);
+ registry->RegisterBooleanPref(prefs::kDevToolsSyncPreferences, false);
+ // even if kDevToolsSyncPreferences is disabled, the js frontend tries to access
+ // these two. E.g.: 'clearPreferences', that is overridden by devtools_compatibility.js
+ registry->RegisterDictionaryPref(prefs::kDevToolsSyncedPreferencesSyncDisabled);
+ registry->RegisterDictionaryPref(prefs::kDevToolsSyncedPreferencesSyncEnabled);
+
+ registry->RegisterStringPref(prefs::kGoogleServicesSigninScopedDeviceId, std::string());
+ registry->RegisterStringPref(prefs::kGaiaCookieLastListAccountsData, std::string());
+ registry->RegisterStringPref(prefs::kGCMProductCategoryForSubtypes, std::string());
+
+ {
+ base::ScopedAllowBlocking allowBlock;
+ m_prefService = factory.Create(registry);
}
#if QT_CONFIG(webengine_spellchecker)
@@ -183,10 +188,9 @@ void PrefServiceAdapter::setSpellCheckLanguages(const QStringList &languages)
QStringList PrefServiceAdapter::spellCheckLanguages() const
{
QStringList spellcheck_dictionaries;
- for (const auto &value : *m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries)) {
- std::string dictionary;
- if (value.GetAsString(&dictionary))
- spellcheck_dictionaries.append(QString::fromStdString(dictionary));
+ const auto &list = m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries);
+ for (const auto &dictionary : list) {
+ spellcheck_dictionaries.append(QString::fromStdString(dictionary.GetString()));
}
return spellcheck_dictionaries;
diff --git a/src/core/pref_service_adapter.h b/src/core/pref_service_adapter.h
index 93a61302f..efa83a72c 100644
--- a/src/core/pref_service_adapter.h
+++ b/src/core/pref_service_adapter.h
@@ -1,42 +1,5 @@
-
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PREF_SERVICE_ADAPTER_H
#define PREF_SERVICE_ADAPTER_H
diff --git a/src/core/printing/pdf_document_helper_client_qt.cpp b/src/core/printing/pdf_document_helper_client_qt.cpp
new file mode 100644
index 000000000..be1cc2e4c
--- /dev/null
+++ b/src/core/printing/pdf_document_helper_client_qt.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/ui/pdf/chrome_pdf_document_helper_client.cc:
+
+#include "pdf_document_helper_client_qt.h"
+
+#include "content/public/browser/render_process_host.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/common/constants.h"
+
+#include "pdf_util_qt.h"
+
+PDFDocumentHelperClientQt::PDFDocumentHelperClientQt() = default;
+PDFDocumentHelperClientQt::~PDFDocumentHelperClientQt() = default;
+
+content::RenderFrameHost *PDFDocumentHelperClientQt::FindPdfFrame(content::WebContents *contents)
+{
+ content::RenderFrameHost *main_frame = contents->GetPrimaryMainFrame();
+ content::RenderFrameHost *pdf_frame = QtWebEngineCore::FindPdfChildFrame(main_frame);
+ return pdf_frame ? pdf_frame : main_frame;
+}
+
+void PDFDocumentHelperClientQt::SetPluginCanSave(content::RenderFrameHost *render_frame_host, bool can_save)
+{
+ auto *guest_view = extensions::MimeHandlerViewGuest::FromRenderFrameHost(render_frame_host);
+ if (guest_view)
+ guest_view->SetPluginCanSave(can_save);
+}
+
+void PDFDocumentHelperClientQt::UpdateContentRestrictions(content::RenderFrameHost *, int)
+{
+}
diff --git a/src/core/printing/pdf_document_helper_client_qt.h b/src/core/printing/pdf_document_helper_client_qt.h
new file mode 100644
index 000000000..af58c7794
--- /dev/null
+++ b/src/core/printing/pdf_document_helper_client_qt.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PDF_DOCUMENT_HELPER_CLIENT_QT_H
+#define PDF_DOCUMENT_HELPER_CLIENT_QT_H
+
+#include "components/pdf/browser/pdf_document_helper_client.h"
+
+// based on chrome/browser/ui/pdf/chrome_pdf_document_helper_client.h:
+class PDFDocumentHelperClientQt : public pdf::PDFDocumentHelperClient // FIXME: rename
+{
+public:
+ PDFDocumentHelperClientQt();
+ PDFDocumentHelperClientQt(const PDFDocumentHelperClientQt&) = delete;
+ PDFDocumentHelperClientQt& operator=(const PDFDocumentHelperClientQt&) = delete;
+ ~PDFDocumentHelperClientQt() override;
+
+private:
+ // pdf::PDFDocumentHelperClient:
+ content::RenderFrameHost* FindPdfFrame(content::WebContents *contents) override;
+ void OnPDFHasUnsupportedFeature(content::WebContents *contents) override {}
+ void OnSaveURL(content::WebContents *contents) override {}
+ void SetPluginCanSave(content::RenderFrameHost *render_frame_host, bool can_save) override;
+ void UpdateContentRestrictions(content::RenderFrameHost *, int) override;
+};
+
+#endif // PDF_DOCUMENT_HELPER_CLIENT_QT_H
diff --git a/src/core/printing/pdf_stream_delegate_qt.cpp b/src/core/printing/pdf_stream_delegate_qt.cpp
new file mode 100644
index 000000000..8677c82bd
--- /dev/null
+++ b/src/core/printing/pdf_stream_delegate_qt.cpp
@@ -0,0 +1,99 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/pdf/chrome_pdf_stream_delegate.cc:
+
+#include "pdf_stream_delegate_qt.h"
+
+#include "base/no_destructor.h"
+#include "chrome/grit/pdf_resources.h"
+#include "content/public/browser/document_user_data.h"
+#include "content/public/browser/navigation_handle.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "extensions/common/constants.h"
+#include "ui/base/resource/resource_bundle.h"
+
+// Associates a `pdf::PdfStreamDelegate::StreamInfo` with the PDF extension's
+// or Print Preview's `blink::Document`.
+// `ChromePdfStreamDelegate::MapToOriginalUrl()` initializes this in
+// `PdfNavigationThrottle`, and then `ChromePdfStreamDelegate::GetStreamInfo()`
+// returns the stashed result to `PdfURLLoaderRequestInterceptor`.
+class StreamInfoHelper : public content::DocumentUserData<StreamInfoHelper>
+{
+public:
+ absl::optional<pdf::PdfStreamDelegate::StreamInfo> TakeStreamInfo()
+ { return std::move(stream_info_); }
+
+private:
+ friend class content::DocumentUserData<StreamInfoHelper>;
+ DOCUMENT_USER_DATA_KEY_DECL();
+
+ StreamInfoHelper(content::RenderFrameHost* embedder_frame,
+ pdf::PdfStreamDelegate::StreamInfo stream_info)
+ : content::DocumentUserData<StreamInfoHelper>(embedder_frame),
+ stream_info_(std::move(stream_info)) {}
+
+ absl::optional<pdf::PdfStreamDelegate::StreamInfo> stream_info_;
+};
+
+DOCUMENT_USER_DATA_KEY_IMPL(StreamInfoHelper);
+
+PdfStreamDelegateQt::PdfStreamDelegateQt() = default;
+PdfStreamDelegateQt::~PdfStreamDelegateQt() = default;
+
+absl::optional<GURL> PdfStreamDelegateQt::MapToOriginalUrl(content::NavigationHandle &navigation_handle)
+{
+ content::RenderFrameHost *embedder_frame = navigation_handle.GetParentFrame();
+ StreamInfoHelper *helper = StreamInfoHelper::GetForCurrentDocument(embedder_frame);
+ if (helper) {
+ // PDF viewer and Print Preview only do this once per WebContents.
+ return absl::nullopt;
+ }
+
+ GURL original_url;
+ StreamInfo info;
+
+ content::WebContents* contents = navigation_handle.GetWebContents();
+ extensions::MimeHandlerViewGuest *guest =
+ extensions::MimeHandlerViewGuest::FromWebContents(contents);
+ if (guest) {
+ base::WeakPtr<extensions::StreamContainer> stream = guest->GetStreamWeakPtr();
+ if (!stream || stream->extension_id() != extension_misc::kPdfExtensionId ||
+ stream->stream_url() != navigation_handle.GetURL() ||
+ !stream->pdf_plugin_attributes()) {
+ return absl::nullopt;
+ }
+
+ original_url = stream->original_url();
+ info.background_color = base::checked_cast<SkColor>(stream->pdf_plugin_attributes()->background_color);
+ info.full_frame = !stream->embedded();
+ info.allow_javascript = stream->pdf_plugin_attributes()->allow_javascript;
+ } else {
+ return absl::nullopt;
+ }
+
+ static const base::NoDestructor<std::string> injected_script(
+ ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
+ IDR_PDF_PDF_INTERNAL_PLUGIN_WRAPPER_ROLLUP_JS));
+
+ info.stream_url = navigation_handle.GetURL();
+ info.original_url = original_url;
+ info.injected_script = injected_script.get();
+ StreamInfoHelper::CreateForCurrentDocument(embedder_frame, std::move(info));
+ return original_url;
+}
+
+absl::optional<pdf::PdfStreamDelegate::StreamInfo>
+PdfStreamDelegateQt::GetStreamInfo(content::RenderFrameHost* embedder_frame)
+{
+ if (!embedder_frame)
+ return absl::nullopt;
+
+ StreamInfoHelper *helper = StreamInfoHelper::GetForCurrentDocument(embedder_frame);
+ if (!helper)
+ return absl::nullopt;
+
+ // Only the call immediately following `MapToOriginalUrl()` requires a valid
+ // `StreamInfo`; subsequent calls should just get nothing.
+ return helper->TakeStreamInfo();
+}
diff --git a/src/core/printing/pdf_stream_delegate_qt.h b/src/core/printing/pdf_stream_delegate_qt.h
new file mode 100644
index 000000000..fd279af72
--- /dev/null
+++ b/src/core/printing/pdf_stream_delegate_qt.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PDF_STREAM_DELEGATE_QT_H
+#define PDF_STREAM_DELEGATE_QT_H
+
+#include "components/pdf/browser/pdf_stream_delegate.h"
+
+// based on chrome/browser/pdf/chrome_pdf_stream_delegate.h:
+class PdfStreamDelegateQt : public pdf::PdfStreamDelegate
+{
+public:
+ PdfStreamDelegateQt();
+ PdfStreamDelegateQt(const PdfStreamDelegateQt &) = delete;
+ PdfStreamDelegateQt operator=(const PdfStreamDelegateQt &) = delete;
+ ~PdfStreamDelegateQt() override;
+
+ // pdf::PdfStreamDelegate:
+ absl::optional<GURL> MapToOriginalUrl(content::NavigationHandle &navigation_handle) override;
+ absl::optional<StreamInfo> GetStreamInfo(content::RenderFrameHost *embedder_frame) override;
+};
+
+#endif // PDF_STREAM_DELEGATE_QT_H
diff --git a/src/core/printing/pdfium_document_wrapper_qt.cpp b/src/core/printing/pdfium_document_wrapper_qt.cpp
index dae6ec44b..56588620d 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.cpp
+++ b/src/core/printing/pdfium_document_wrapper_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "pdfium_document_wrapper_qt.h"
#include <QtCore/qhash.h>
diff --git a/src/core/printing/pdfium_document_wrapper_qt.h b/src/core/printing/pdfium_document_wrapper_qt.h
index e0778c32b..feb34e36a 100644
--- a/src/core/printing/pdfium_document_wrapper_qt.h
+++ b/src/core/printing/pdfium_document_wrapper_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -57,7 +21,7 @@
namespace QtWebEngineCore {
-class Q_WEBENGINECORE_PRIVATE_EXPORT PdfiumDocumentWrapperQt
+class Q_WEBENGINECORE_EXPORT PdfiumDocumentWrapperQt
{
public:
PdfiumDocumentWrapperQt(const void *pdfData, size_t size, const char *password = nullptr);
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index 8d2d1bfd6..b2b8e34fc 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// This is based on chrome/browser/printing/print_view_manager_base.cc:
// Copyright 2013 The Chromium Authors. All rights reserved.
@@ -49,9 +13,8 @@
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
#include "base/task/current_thread.h"
-#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
@@ -84,182 +47,71 @@ void GetDefaultPrintSettingsReply(printing::mojom::PrintManagerHost::GetDefaultP
std::move(callback).Run(std::move(params));
}
-void GetDefaultPrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+void OnDidGetDefaultPrintSettings(scoped_refptr<printing::PrintQueriesQueue> queue,
std::unique_ptr<printing::PrinterQuery> printer_query,
printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
printing::mojom::PrintParamsPtr params = printing::mojom::PrintParams::New();
- if (printer_query && printer_query->last_status() == printing::PrintingContext::OK) {
+ if (printer_query && printer_query->last_status() == printing::mojom::ResultCode::kSuccess) {
RenderParamsFromPrintSettings(printer_query->settings(), params.get());
params->document_cookie = printer_query->cookie();
}
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&GetDefaultPrintSettingsReply,
- std::move(callback), std::move(params)));
+ GetDefaultPrintSettingsReply(std::move(callback), std::move(params));
// If printing was enabled.
if (printer_query) {
// If user hasn't cancelled.
if (printer_query->cookie() && printer_query->settings().dpi()) {
queue->QueuePrinterQuery(std::move(printer_query));
- } else {
- printer_query->StopWorker();
}
}
}
-void GetDefaultPrintSettingsOnIO(printing::mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback,
- scoped_refptr<printing::PrintQueriesQueue> queue,
- int process_id, int routing_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(0);
- if (!printer_query)
- printer_query = queue->CreatePrinterQuery(process_id, routing_id);
-
- // Loads default settings. This is asynchronous, only the mojo message sender
- // will hang until the settings are retrieved.
- auto *printer_query_ptr = printer_query.get();
- printer_query_ptr->GetSettings(
- printing::PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false,
- printing::mojom::MarginType::kDefaultMargins, false, false,
- base::BindOnce(&GetDefaultPrintSettingsReplyOnIO, queue,
- std::move(printer_query), std::move(callback)));
-}
-
-// Runs |callback| with |params| to reply to
-// mojom::PrintManagerHost::UpdatePrintSettings.
-void UpdatePrintSettingsReply(printing::mojom::PrintManagerHost::UpdatePrintSettingsCallback callback,
- printing::mojom::PrintPagesParamsPtr params, bool canceled)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (!params) {
- // Fills |params| with initial values.
- params = printing::mojom::PrintPagesParams::New();
- params->params = printing::mojom::PrintParams::New();
- }
- std::move(callback).Run(std::move(params), canceled);
-}
-
-void UpdatePrintSettingsReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+void OnDidUpdatePrintSettings(scoped_refptr<printing::PrintQueriesQueue> queue,
std::unique_ptr<printing::PrinterQuery> printer_query,
printing::mojom::PrintManagerHost::UpdatePrintSettingsCallback callback,
int process_id, int routing_id)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(printer_query);
auto params = printing::mojom::PrintPagesParams::New();
params->params = printing::mojom::PrintParams::New();
- if (printer_query->last_status() == printing::PrintingContext::OK) {
+ if (printer_query->last_status() == printing::mojom::ResultCode::kSuccess) {
RenderParamsFromPrintSettings(printer_query->settings(), params->params.get());
params->params->document_cookie = printer_query->cookie();
- params->pages = printing::PageRange::GetPages(printer_query->settings().ranges());
+ params->pages = printer_query->settings().ranges();
}
- bool canceled = printer_query->last_status() == printing::PrintingContext::CANCEL;
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&UpdatePrintSettingsReply, std::move(callback), std::move(params), canceled));
+ std::move(callback).Run(std::move(params));
if (printer_query->cookie() && printer_query->settings().dpi()) {
queue->QueuePrinterQuery(std::move(printer_query));
- } else {
- printer_query->StopWorker();
- }
-}
-
-void UpdatePrintSettingsOnIO(int32_t cookie,
- printing::mojom::PrintManagerHost::UpdatePrintSettingsCallback callback,
- scoped_refptr<printing::PrintQueriesQueue> queue,
- base::Value job_settings,
- int process_id, int routing_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(cookie);
- if (!printer_query)
- printer_query = queue->CreatePrinterQuery(content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
-
- auto *printer_query_ptr = printer_query.get();
- printer_query_ptr->SetSettings(
- std::move(job_settings),
- base::BindOnce(&UpdatePrintSettingsReplyOnIO,
- queue, std::move(printer_query), std::move(callback),
- process_id, routing_id));
-}
-
-// Runs |callback| with |params| to reply to
-// mojom::PrintManagerHost::ScriptedPrint.
-void ScriptedPrintReply(printing::mojom::PrintManagerHost::ScriptedPrintCallback callback,
- printing::mojom::PrintPagesParamsPtr params,
- int process_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- if (!content::RenderProcessHost::FromID(process_id)) {
- // Early return if the renderer is not alive.
- return;
- }
-
- if (!params) {
- // Fills |params| with initial values.
- params = printing::mojom::PrintPagesParams::New();
- params->params = printing::mojom::PrintParams::New();
}
- std::move(callback).Run(std::move(params));
}
-void ScriptedPrintReplyOnIO(scoped_refptr<printing::PrintQueriesQueue> queue,
+void OnDidScriptedPrint(scoped_refptr<printing::PrintQueriesQueue> queue,
std::unique_ptr<printing::PrinterQuery> printer_query,
- printing::mojom::PrintManagerHost::ScriptedPrintCallback callback,
- int process_id)
+ printing::mojom::PrintManagerHost::ScriptedPrintCallback callback)
{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auto params = printing::mojom::PrintPagesParams::New();
params->params = printing::mojom::PrintParams::New();
- if (printer_query->last_status() == printing::PrintingContext::OK &&
- printer_query->settings().dpi()) {
+ if (printer_query->last_status() == printing::mojom::ResultCode::kSuccess && printer_query->settings().dpi()) {
RenderParamsFromPrintSettings(printer_query->settings(), params->params.get());
params->params->document_cookie = printer_query->cookie();
- params->pages = printing::PageRange::GetPages(printer_query->settings().ranges());
+ params->pages = printer_query->settings().ranges();
}
bool has_valid_cookie = params->params->document_cookie;
bool has_dpi = !params->params->dpi.IsEmpty();
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE, base::BindOnce(&ScriptedPrintReply, std::move(callback),
- std::move(params), process_id));
+ std::move(callback).Run(std::move(params));
if (has_dpi && has_valid_cookie) {
queue->QueuePrinterQuery(std::move(printer_query));
- } else {
- printer_query->StopWorker();
}
}
-void ScriptedPrintOnIO(printing::mojom::ScriptedPrintParamsPtr params,
- printing::mojom::PrintManagerHost::ScriptedPrintCallback callback,
- scoped_refptr<printing::PrintQueriesQueue> queue,
- int process_id,
- int routing_id)
-{
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- std::unique_ptr<printing::PrinterQuery> printer_query = queue->PopPrinterQuery(params->cookie);
- if (!printer_query)
- printer_query = queue->CreatePrinterQuery(process_id, routing_id);
-
- auto *printer_query_ptr = printer_query.get();
- printer_query_ptr->GetSettings(
- printing::PrinterQuery::GetSettingsAskParam::ASK_USER, params->expected_pages_count,
- params->has_selection, params->margin_type, params->is_scripted,
- params->is_modifiable,
- base::BindOnce(&ScriptedPrintReplyOnIO, queue, std::move(printer_query),
- std::move(callback), process_id));
-}
-
} // namespace
PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents)
@@ -268,9 +120,6 @@ PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents)
, m_didPrintingSucceed(false)
, m_printerQueriesQueue(WebEngineContext::current()->getPrintJobManager()->queue())
{
- // FIXME: Check if this needs to be executed async:
- // TODO: Add isEnabled to profile
- PrintViewManagerBaseQt::UpdatePrintingEnabled();
}
PrintViewManagerBaseQt::~PrintViewManagerBaseQt()
@@ -285,16 +134,23 @@ void PrintViewManagerBaseQt::SetPrintingRFH(content::RenderFrameHost *rfh)
m_printingRFH = rfh;
}
-void PrintViewManagerBaseQt::UpdatePrintingEnabled()
-{
+void PrintViewManagerBaseQt::ScriptedPrintReply(ScriptedPrintCallback callback,
+ int process_id,
+ printing::mojom::PrintPagesParamsPtr params) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- bool enabled = false;
-#if QT_CONFIG(webengine_printing_and_pdf)
- enabled = true;
+
+#if BUILDFLAG(ENABLE_OOP_PRINTING)
+ // Finished getting all settings (defaults and from user), no further need
+ // to be registered as a system print client.
+ UnregisterSystemPrintClient();
#endif
- web_contents()->ForEachFrame(
- base::Bind(&PrintViewManagerBaseQt::SendPrintingEnabled,
- base::Unretained(this), enabled));
+ if (!content::RenderProcessHost::FromID(process_id)) {
+ // Early return if the renderer is not alive.
+ return;
+ }
+
+// set_cookie(params->params->document_cookie);
+ std::move(callback).Run(std::move(params));
}
void PrintViewManagerBaseQt::NavigationStopped()
@@ -303,7 +159,7 @@ void PrintViewManagerBaseQt::NavigationStopped()
TerminatePrintJob(true);
}
-base::string16 PrintViewManagerBaseQt::RenderSourceName()
+std::u16string PrintViewManagerBaseQt::RenderSourceName()
{
return toString16(QLatin1String(""));
}
@@ -371,31 +227,46 @@ void PrintViewManagerBaseQt::DidPrintDocument(printing::mojom::DidPrintDocumentP
void PrintViewManagerBaseQt::GetDefaultPrintSettings(GetDefaultPrintSettingsCallback callback)
{
- content::RenderFrameHost* render_frame_host =
- print_manager_host_receivers_.GetCurrentTargetFrame();
+ content::RenderFrameHost *render_frame_host =
+ print_manager_host_receivers_.GetCurrentTargetFrame();
+ content::RenderProcessHost *render_process_host =
+ render_frame_host->GetProcess();
+
+ auto callback_wrapper =
+ base::BindOnce(&GetDefaultPrintSettingsReply, std::move(callback));
+ std::unique_ptr<printing::PrinterQuery> printer_query = m_printerQueriesQueue->PopPrinterQuery(0);
+ if (!printer_query)
+ printer_query = m_printerQueriesQueue->CreatePrinterQuery(render_frame_host->GetGlobalId());
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&GetDefaultPrintSettingsOnIO, std::move(callback), m_printerQueriesQueue,
- render_frame_host->GetProcess()->GetID(),
- render_frame_host->GetRoutingID()));
+ // Loads default settings. This is asynchronous, only the mojo message sender
+ // will hang until the settings are retrieved.
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->GetDefaultSettings(
+ base::BindOnce(&OnDidGetDefaultPrintSettings, m_printerQueriesQueue,
+ std::move(printer_query), std::move(callback_wrapper)),
+ false,
+ !render_process_host->IsPdf());
}
-void PrintViewManagerBaseQt::PrintingFailed(int32_t cookie)
+void PrintViewManagerBaseQt::PrintingFailed(int32_t cookie, printing::mojom::PrintFailureReason reason)
{
// Note: Not redundant with cookie checks in the same method in other parts of
// the class hierarchy.
if (!IsValidCookie(cookie))
return;
- PrintManager::PrintingFailed(cookie);
+ PrintManager::PrintingFailed(cookie, reason);
ReleasePrinterQuery();
-
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_PRINT_JOB_RELEASED,
- content::Source<content::WebContents>(web_contents()),
- content::NotificationService::NoDetails());
+}
+void PrintViewManagerBaseQt::IsPrintingEnabled(IsPrintingEnabledCallback callback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ bool enabled = false;
+#if QT_CONFIG(webengine_printing_and_pdf)
+ enabled = true;
+#endif
+ std::move(callback).Run(enabled);
}
void PrintViewManagerBaseQt::ScriptedPrint(printing::mojom::ScriptedPrintParamsPtr params,
@@ -404,21 +275,23 @@ void PrintViewManagerBaseQt::ScriptedPrint(printing::mojom::ScriptedPrintParamsP
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
content::RenderFrameHost *render_frame_host =
print_manager_host_receivers_.GetCurrentTargetFrame();
+ content::RenderProcessHost *render_process_host =
+ render_frame_host->GetProcess();
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&ScriptedPrintOnIO, std::move(params), std::move(callback),
- m_printerQueriesQueue, render_frame_host->GetProcess()->GetID(),
- render_frame_host->GetRoutingID()));
-}
+ auto callback_wrapper = base::BindOnce(
+ &PrintViewManagerBaseQt::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
+ std::move(callback), render_process_host->GetID());
-void PrintViewManagerBaseQt::ShowInvalidPrinterSettingsError()
-{
-}
+ std::unique_ptr<printing::PrinterQuery> printer_query =
+ m_printerQueriesQueue->PopPrinterQuery(params->cookie);
+ if (!printer_query)
+ printer_query = m_printerQueriesQueue->CreatePrinterQuery(render_frame_host->GetGlobalId());
-void PrintViewManagerBaseQt::DidStartLoading()
-{
- UpdatePrintingEnabled();
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->GetSettingsFromUser(
+ params->expected_pages_count, params->has_selection, params->margin_type,
+ params->is_scripted, !render_process_host->IsPdf(),
+ base::BindOnce(&OnDidScriptedPrint, m_printerQueriesQueue, std::move(printer_query), std::move(callback_wrapper)));
}
// Note: In PrintViewManagerQt we always initiate printing with
@@ -449,61 +322,22 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render
}
}
-void PrintViewManagerBaseQt::Observe(int type,
- const content::NotificationSource& /*source*/,
- const content::NotificationDetails& details)
+void PrintViewManagerBaseQt::OnDocDone(int /*job_id*/, printing::PrintedDocument * /*document*/)
{
- DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
- OnNotifyPrintJobEvent(*content::Details<printing::JobEventDetails>(details).ptr());
}
-void PrintViewManagerBaseQt::OnNotifyPrintJobEvent(const printing::JobEventDetails& event_details)
+void PrintViewManagerBaseQt::OnJobDone()
{
- switch (event_details.type()) {
- case printing::JobEventDetails::FAILED: {
- TerminatePrintJob(true);
-
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_PRINT_JOB_RELEASED,
- content::Source<content::WebContents>(web_contents()),
- content::NotificationService::NoDetails());
- break;
- }
- case printing::JobEventDetails::USER_INIT_DONE:
- case printing::JobEventDetails::DEFAULT_INIT_DONE:
- case printing::JobEventDetails::USER_INIT_CANCELED: {
- NOTREACHED();
- break;
- }
- case printing::JobEventDetails::ALL_PAGES_REQUESTED: {
- ShouldQuitFromInnerMessageLoop();
- break;
- }
- case printing::JobEventDetails::NEW_DOC:
-#if defined(OS_WIN)
- case printing::JobEventDetails::PAGE_DONE:
-#endif
- case printing::JobEventDetails::DOC_DONE: {
- // Don't care about the actual printing process.
- break;
- }
- case printing::JobEventDetails::JOB_DONE: {
- // Printing is done, we don't need it anymore.
- // print_job_->is_job_pending() may still be true, depending on the order
- // of object registration.
- m_didPrintingSucceed = true;
- ReleasePrintJob();
+ // Printing is done, we don't need it anymore.
+ // print_job_->is_job_pending() may still be true, depending on the order
+ // of object registration.
+ m_didPrintingSucceed = true;
+ ReleasePrintJob();
+}
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_PRINT_JOB_RELEASED,
- content::Source<content::WebContents>(web_contents()),
- content::NotificationService::NoDetails());
- break;
- }
- default:
- NOTREACHED();
- break;
- }
+void PrintViewManagerBaseQt::OnFailed()
+{
+ TerminatePrintJob(true);
}
// Requests the RenderView to render all the missing pages for the print job.
@@ -522,8 +356,8 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow()
// We can't print if there is no renderer.
if (!web_contents() ||
- !web_contents()->GetRenderViewHost() ||
- !web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
+ !web_contents()->GetPrimaryMainFrame() ||
+ !web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive()) {
return false;
}
@@ -532,11 +366,9 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow()
// pages in an hurry if a print_job_ is still pending. No need to wait for it
// to actually spool the pages, only to have the renderer generate them. Run
// a message loop until we get our signal that the print job is satisfied.
- // PrintJob will send a ALL_PAGES_REQUESTED after having received all the
- // pages it needs. MessageLoop::current()->Quit() will be called as soon as
- // print_job_->document()->IsComplete() is true on either ALL_PAGES_REQUESTED
- // or in DidPrintPage(). The check is done in
- // ShouldQuitFromInnerMessageLoop().
+ // |quit_inner_loop_| will be called as soon as
+ // print_job_->document()->IsComplete() is true in DidPrintDocument(). The
+ // check is done in ShouldQuitFromInnerMessageLoop().
// BLOCKS until all the pages are received. (Need to enable recursive task)
if (!RunInnerMessageLoop()) {
// This function is always called from DisconnectFromCurrentPrintJob() so we
@@ -564,11 +396,14 @@ bool PrintViewManagerBaseQt::CreateNewPrintJob(std::unique_ptr<printing::Printer
DCHECK(query);
// Disconnect the current |m_printJob|.
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
DisconnectFromCurrentPrintJob();
+ if (!weak_this)
+ return false;
// We can't print if there is no renderer.
- if (!web_contents()->GetRenderViewHost() ||
- !web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
+ if (!web_contents()->GetPrimaryMainFrame() ||
+ !web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive()) {
return false;
}
@@ -576,10 +411,9 @@ bool PrintViewManagerBaseQt::CreateNewPrintJob(std::unique_ptr<printing::Printer
// view and switch to it, initialize the printer and show the print dialog.
DCHECK(!m_printJob.get());
- m_printJob = base::MakeRefCounted<printing::PrintJob>();
+ m_printJob = base::MakeRefCounted<printing::PrintJob>(nullptr /*g_browser_process->print_job_manager()*/);
m_printJob->Initialize(std::move(query), RenderSourceName(), number_pages_);
- m_registrar.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
- content::Source<printing::PrintJob>(m_printJob.get()));
+ m_printJob->AddObserver(*this);
m_didPrintingSucceed = false;
return true;
}
@@ -635,8 +469,8 @@ void PrintViewManagerBaseQt::ReleasePrintJob()
if (rfh)
GetPrintRenderFrame(rfh)->PrintingDone(m_didPrintingSucceed);
- m_registrar.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
- content::Source<printing::PrintJob>(m_printJob.get()));
+ m_printJob->RemoveObserver(*this);
+
// Don't close the worker thread.
m_printJob = nullptr;
}
@@ -658,16 +492,15 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop()
base::OneShotTimer quit_timer;
base::RunLoop run_loop;
quit_timer.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
+ base::Milliseconds(kPrinterSettingsTimeout),
run_loop.QuitWhenIdleClosure());
m_quitInnerLoop = run_loop.QuitClosure();
- // Need to enable recursive task.
- {
- base::CurrentThread::ScopedNestableTaskAllower allow;
- run_loop.Run();
- }
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ run_loop.Run();
+ if (!weak_this)
+ return false;
bool success = !m_quitInnerLoop;
m_quitInnerLoop.Reset();
@@ -718,12 +551,8 @@ void PrintViewManagerBaseQt::ReleasePrinterQuery()
if (!printJobManager)
return;
- std::unique_ptr<printing::PrinterQuery> printerQuery;
- printerQuery = m_printerQueriesQueue->PopPrinterQuery(cookie);
- if (!printerQuery)
- return;
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&printing::PrinterQuery::StopWorker, std::move(printerQuery)));
+ std::unique_ptr<printing::PrinterQuery> printerQuery =
+ m_printerQueriesQueue->PopPrinterQuery(cookie);
}
// Originally from print_preview_message_handler.cc:
@@ -731,38 +560,31 @@ void PrintViewManagerBaseQt::StopWorker(int documentCookie)
{
if (documentCookie <= 0)
return;
- std::unique_ptr<printing::PrinterQuery> printer_query =
+ std::unique_ptr<printing::PrinterQuery> printerQuery =
m_printerQueriesQueue->PopPrinterQuery(documentCookie);
- if (printer_query.get()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&printing::PrinterQuery::StopWorker, std::move(printer_query)));
- }
}
-void PrintViewManagerBaseQt::SendPrintingEnabled(bool enabled, content::RenderFrameHost* rfh)
-{
- GetPrintRenderFrame(rfh)->SetPrintingEnabled(enabled);
-}
-
-void PrintViewManagerBaseQt::UpdatePrintSettings(int32_t cookie, base::Value job_settings,
+void PrintViewManagerBaseQt::UpdatePrintSettings(base::Value::Dict job_settings,
UpdatePrintSettingsCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (!job_settings.FindIntKey(printing::kSettingPrinterType)) {
- UpdatePrintSettingsReply(std::move(callback), nullptr, false);
+ if (!job_settings.FindInt(printing::kSettingPrinterType)) {
+ std::move(callback).Run(nullptr);
return;
}
content::RenderFrameHost *render_frame_host =
print_manager_host_receivers_.GetCurrentTargetFrame();
+ std::unique_ptr<printing::PrinterQuery> printer_query =
+ m_printerQueriesQueue->CreatePrinterQuery(content::GlobalRenderFrameHostId());
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&UpdatePrintSettingsOnIO, cookie, std::move(callback),
- m_printerQueriesQueue, std::move(job_settings),
- render_frame_host->GetProcess()->GetID(),
- render_frame_host->GetRoutingID()));
+ auto *printer_query_ptr = printer_query.get();
+ printer_query_ptr->SetSettings(
+ std::move(job_settings),
+ base::BindOnce(&OnDidUpdatePrintSettings,
+ m_printerQueriesQueue, std::move(printer_query), std::move(callback),
+ render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()));
}
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_base_qt.h b/src/core/printing/print_view_manager_base_qt.h
index 21069af67..d4b5bfe82 100644
--- a/src/core/printing/print_view_manager_base_qt.h
+++ b/src/core/printing/print_view_manager_base_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -45,7 +9,7 @@
#define PRINT_VIEW_MANAGER_BASE_QT_H
#include "base/memory/ref_counted_memory.h"
-#include "base/strings/string16.h"
+#include "chrome/browser/printing/print_job.h"
#include "components/prefs/pref_member.h"
#include "components/printing/browser/print_manager.h"
#include "components/printing/common/print.mojom-forward.h"
@@ -61,35 +25,30 @@ class RenderFrameHost;
}
namespace printing {
-class JobEventDetails;
-class PrintJob;
class PrintQueriesQueue;
class PrinterQuery;
}
namespace QtWebEngineCore {
-class PrintViewManagerBaseQt : public content::NotificationObserver
- , public printing::PrintManager
+class PrintViewManagerBaseQt : public printing::PrintManager
+ , public printing::PrintJob::Observer
{
public:
~PrintViewManagerBaseQt() override;
- // Whether printing is enabled or not.
- void UpdatePrintingEnabled();
-
- base::string16 RenderSourceName();
+ std::u16string RenderSourceName();
// mojom::PrintManagerHost:
void DidGetPrintedPagesCount(int32_t cookie, uint32_t number_pages) override;
void DidPrintDocument(printing::mojom::DidPrintDocumentParamsPtr params,
DidPrintDocumentCallback callback) override;
void GetDefaultPrintSettings(GetDefaultPrintSettingsCallback callback) override;
- void UpdatePrintSettings(int32_t cookie, base::Value job_settings,
- UpdatePrintSettingsCallback callback) override;
+ void UpdatePrintSettings(base::Value::Dict, UpdatePrintSettingsCallback) override;
+ void IsPrintingEnabled(IsPrintingEnabledCallback callback) override;
void ScriptedPrint(printing::mojom::ScriptedPrintParamsPtr,
printing::mojom::PrintManagerHost::ScriptedPrintCallback) override;
- void ShowInvalidPrinterSettingsError() override;
- void PrintingFailed(int32_t cookie) override;
+ void PrintingFailed(int32_t cookie,
+ printing::mojom::PrintFailureReason reason) override;
protected:
explicit PrintViewManagerBaseQt(content::WebContents*);
@@ -112,25 +71,24 @@ protected:
// disconnect from it.
void DisconnectFromCurrentPrintJob();
+ // PrintJob::Observer overrides:
+ void OnDocDone(int job_id, printing::PrintedDocument *document) override;
+ void OnJobDone() override;
+ void OnFailed() override;
+
void StopWorker(int documentCookie);
private:
- // content::NotificationObserver implementation.
- void Observe(int,
- const content::NotificationSource&,
- const content::NotificationDetails&) override;
-
- // content::WebContentsObserver implementation.
- void DidStartLoading() override;
-
- // Processes a NOTIFY_PRINT_JOB_EVENT notification.
- void OnNotifyPrintJobEvent(const printing::JobEventDetails &event_details);
-
// Requests the RenderView to render all the missing pages for the print job.
// No-op if no print job is pending. Returns true if at least one page has
// been requested to the renderer.
bool RenderAllMissingPagesNow();
+ // Runs `callback` with `params` to reply to ScriptedPrint().
+ void ScriptedPrintReply(ScriptedPrintCallback callback,
+ int process_id,
+ printing::mojom::PrintPagesParamsPtr params);
+
// Checks that synchronization is correct with |print_job_| based on |cookie|.
bool PrintJobHasDocument(int cookie);
@@ -144,9 +102,8 @@ private:
// Quits the current message loop if these conditions hold true: a document is
// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This
- // function is called in DidPrintDocument() or on ALL_PAGES_REQUESTED
- // notification. The inner message loop is created was created by
- // RenderAllMissingPagesNow().
+ // function is called in DidPrintDocument(). The inner message loop was
+ // created by RenderAllMissingPagesNow().
void ShouldQuitFromInnerMessageLoop();
// Terminates the print job. No-op if no print job has been created. If
@@ -172,9 +129,6 @@ private:
// Release the PrinterQuery associated with our |cookie_|.
void ReleasePrinterQuery();
- // Helper method for UpdatePrintingEnabled().
- void SendPrintingEnabled(bool enabled, content::RenderFrameHost* rfh);
-
private:
content::NotificationRegistrar m_registrar;
scoped_refptr<printing::PrintJob> m_printJob;
@@ -186,7 +140,7 @@ private:
base::OnceClosure m_quitInnerLoop;
scoped_refptr<printing::PrintQueriesQueue> m_printerQueriesQueue;
- DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBaseQt);
+ base::WeakPtrFactory<PrintViewManagerBaseQt> weak_ptr_factory_{this};
};
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index 3b66ad29d..1d21c2fb9 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Loosely based on print_view_manager.cc and print_preview_message_handler.cc
// Copyright 2013 The Chromium Authors. All rights reserved.
@@ -44,6 +8,7 @@
#include "print_view_manager_qt.h"
+#include "pdf_util_qt.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
@@ -55,7 +20,7 @@
#include "base/values.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/printing/common/print.mojom.h"
@@ -65,6 +30,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "printing/metafile_skia.h"
+#include "printing/mojom/print.mojom-shared.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -98,7 +64,7 @@ GetBytesFromHandle(const base::ReadOnlySharedMemoryRegion &handle)
// Write the PDF file to disk.
static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
const base::FilePath &path,
- const QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback &saveCallback)
+ QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback saveCallback)
{
DCHECK_GT(data->size(), 0U);
@@ -108,47 +74,47 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
base::File file(path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
bool success = file.IsValid() && metafile.SaveTo(&file);
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(saveCallback, success));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(saveCallback), success));
}
-static base::DictionaryValue *createPrintSettings()
+static base::Value::Dict createPrintSettings()
{
- base::DictionaryValue *printSettings = new base::DictionaryValue();
+ base::Value::Dict printSettings;
// TO DO: Check if we can use the request ID from Qt here somehow.
static int internalRequestId = 0;
- printSettings->SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0);
- printSettings->SetInteger(printing::kPreviewRequestID, internalRequestId);
+ printSettings.Set(printing::kIsFirstRequest, internalRequestId++ == 0);
+ printSettings.Set(printing::kPreviewRequestID, internalRequestId);
// The following are standard settings that Chromium expects to be set.
- printSettings->SetInteger(printing::kSettingPrinterType, static_cast<int>(printing::PrinterType::kPdf));
+ printSettings.Set(printing::kSettingPrinterType, static_cast<int>(printing::mojom::PrinterType::kPdf));
- printSettings->SetInteger(printing::kSettingDpiHorizontal, printing::kPointsPerInch);
- printSettings->SetInteger(printing::kSettingDpiVertical, printing::kPointsPerInch);
+ printSettings.Set(printing::kSettingDpiHorizontal, printing::kPointsPerInch);
+ printSettings.Set(printing::kSettingDpiVertical, printing::kPointsPerInch);
- printSettings->SetInteger(printing::kSettingDuplexMode, static_cast<int>(printing::mojom::DuplexMode::kSimplex));
- printSettings->SetInteger(printing::kSettingCopies, 1);
- printSettings->SetInteger(printing::kSettingPagesPerSheet, 1);
- printSettings->SetBoolean(printing::kSettingCollate, false);
+ printSettings.Set(printing::kSettingDuplexMode, static_cast<int>(printing::mojom::DuplexMode::kSimplex));
+ printSettings.Set(printing::kSettingCopies, 1);
+ printSettings.Set(printing::kSettingPagesPerSheet, 1);
+ printSettings.Set(printing::kSettingCollate, false);
// printSettings->SetBoolean(printing::kSettingGenerateDraftData, false);
- printSettings->SetBoolean(printing::kSettingPreviewModifiable, false);
+ printSettings.Set(printing::kSettingPreviewModifiable, false);
- printSettings->SetKey(printing::kSettingShouldPrintSelectionOnly, base::Value(false));
- printSettings->SetKey(printing::kSettingShouldPrintBackgrounds, base::Value(true));
- printSettings->SetKey(printing::kSettingHeaderFooterEnabled, base::Value(false));
- printSettings->SetKey(printing::kSettingRasterizePdf, base::Value(false));
- printSettings->SetInteger(printing::kSettingScaleFactor, 100);
- printSettings->SetString(printing::kSettingDeviceName, "");
- printSettings->SetInteger(printing::kPreviewUIID, 12345678);
+ printSettings.Set(printing::kSettingShouldPrintSelectionOnly, base::Value(false));
+ printSettings.Set(printing::kSettingShouldPrintBackgrounds, base::Value(true));
+ printSettings.Set(printing::kSettingHeaderFooterEnabled, base::Value(false));
+ printSettings.Set(printing::kSettingRasterizePdf, base::Value(false));
+ printSettings.Set(printing::kSettingScaleFactor, 100);
+ printSettings.Set(printing::kSettingDeviceName, "");
+ printSettings.Set(printing::kPreviewUIID, 12345678);
return printSettings;
}
-static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout,
+static base::Value::Dict createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout,
bool useCustomMargins)
{
- base::DictionaryValue *printSettings = createPrintSettings();
+ base::Value::Dict printSettings = createPrintSettings();
QRectF pageSizeInMillimeter;
if (useCustomMargins) {
@@ -156,43 +122,43 @@ static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayo
pageSizeInMillimeter = pageLayout.pageSize().rect(QPageSize::Millimeter);
QMargins pageMarginsInPoints = pageLayout.marginsPoints();
- std::unique_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
- marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
- marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
- marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
- marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
+ base::Value::Dict marginsDict;
+ marginsDict.Set(printing::kSettingMarginTop, pageMarginsInPoints.top());
+ marginsDict.Set(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
+ marginsDict.Set(printing::kSettingMarginLeft, pageMarginsInPoints.left());
+ marginsDict.Set(printing::kSettingMarginRight, pageMarginsInPoints.right());
- printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict));
- printSettings->SetInteger(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kCustomMargins);
+ printSettings.Set(printing::kSettingMarginsCustom, std::move(marginsDict));
+ printSettings.Set(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kCustomMargins);
// pageSizeInMillimeter is in portrait orientation. Transpose it if necessary.
- printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
+ printSettings.Set(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
} else {
// QPrinter will handle margins
pageSizeInMillimeter = pageLayout.paintRect(QPageLayout::Millimeter);
- printSettings->SetInteger(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kNoMargins);
+ printSettings.Set(printing::kSettingMarginsType, (int)printing::mojom::MarginType::kNoMargins);
// pageSizeInMillimeter already contains the orientation.
- printSettings->SetBoolean(printing::kSettingLandscape, false);
+ printSettings.Set(printing::kSettingLandscape, false);
}
//Set page size attributes, chromium expects these in micrometers
- std::unique_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue);
- sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMillimeter.width() * kMicronsToMillimeter);
- sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMillimeter.height() * kMicronsToMillimeter);
- printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict));
+ base::Value::Dict sizeDict;
+ sizeDict.Set(printing::kSettingMediaSizeWidthMicrons, int(pageSizeInMillimeter.width() * kMicronsToMillimeter));
+ sizeDict.Set(printing::kSettingMediaSizeHeightMicrons, int(pageSizeInMillimeter.height() * kMicronsToMillimeter));
+ printSettings.Set(printing::kSettingMediaSize, std::move(sizeDict));
return printSettings;
}
-static base::ListValue *createPageRangeSettings(const QList<QPageRanges::Range> &ranges)
+static base::Value::List createPageRangeSettings(const QList<QPageRanges::Range> &ranges)
{
- base::ListValue *pageRangeArray = new base::ListValue;
+ base::Value::List pageRangeArray;
for (int i = 0; i < ranges.count(); i++) {
- std::unique_ptr<base::DictionaryValue> pageRange(new base::DictionaryValue);
- pageRange->SetInteger(printing::kSettingPageRangeFrom, ranges.at(i).from);
- pageRange->SetInteger(printing::kSettingPageRangeTo, ranges.at(i).to);
- pageRangeArray->Append(std::move(pageRange));
+ base::Value::Dict pageRange;
+ pageRange.Set(printing::kSettingPageRangeFrom, ranges.at(i).from);
+ pageRange.Set(printing::kSettingPageRangeTo, ranges.at(i).to);
+ pageRangeArray.Append(std::move(pageRange));
}
return pageRangeArray;
}
@@ -209,22 +175,22 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
const QPageRanges &pageRanges,
bool printInColor,
const QString &filePath,
- const PrintToPDFFileCallback& callback)
+ PrintToPDFFileCallback callback)
{
if (callback.is_null())
return;
- if (m_printSettings || !filePath.length()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(callback, false));
+ if (!m_printSettings.empty() || !filePath.length()) {
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(callback), false));
return;
}
m_pdfOutputPath = toFilePath(filePath);
- m_pdfSaveCallback = callback;
+ m_pdfSaveCallback = std::move(callback);
if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor)) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(callback, false));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(m_pdfSaveCallback), false));
resetPdfState();
}
}
@@ -233,22 +199,22 @@ void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
const QPageRanges &pageRanges,
bool printInColor,
bool useCustomMargins,
- const PrintToPDFCallback& callback)
+ PrintToPDFCallback callback)
{
if (callback.is_null())
return;
// If there already is a pending print in progress, don't try starting another one.
- if (m_printSettings) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(callback, QSharedPointer<QByteArray>()));
+ if (!m_printSettings.empty()) {
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(callback), QSharedPointer<QByteArray>()));
return;
}
- m_pdfPrintCallback = callback;
+ m_pdfPrintCallback = std::move(callback);
if (!PrintToPDFInternal(pageLayout, pageRanges, printInColor, useCustomMargins)) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(callback, QSharedPointer<QByteArray>()));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
resetPdfState();
}
@@ -262,20 +228,23 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
if (!pageLayout.isValid())
return false;
- m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, useCustomMargins));
- m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds,
+ m_printSettings = createPrintSettingsFromQPageLayout(pageLayout, useCustomMargins);
+ m_printSettings.Set(printing::kSettingShouldPrintBackgrounds,
web_contents()->GetOrCreateWebPreferences().should_print_backgrounds);
- m_printSettings->SetInteger(printing::kSettingColor,
+ m_printSettings.Set(printing::kSettingColor,
int(printInColor ? printing::mojom::ColorModel::kColor : printing::mojom::ColorModel::kGrayscale));
if (!pageRanges.isEmpty())
- m_printSettings->Set(printing::kSettingPageRange,
- std::unique_ptr<base::ListValue>(createPageRangeSettings(pageRanges.toRangeList())));
+ m_printSettings.Set(printing::kSettingPageRange, createPageRangeSettings(pageRanges.toRangeList()));
if (web_contents()->IsCrashed())
return false;
- content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
- GetPrintRenderFrame(rfh)->InitiatePrintPreview(mojo::PendingAssociatedRemote<printing::mojom::PrintRenderer>(), false);
+ content::RenderFrameHost *rfh = web_contents()->GetPrimaryMainFrame();
+ // Use the plugin frame for printing if web_contents() is a PDF viewer guest
+ content::RenderFrameHost *full_page_plugin = GetFullPagePlugin(web_contents());
+ if (content::RenderFrameHost *pdf_rfh = FindPdfChildFrame(full_page_plugin ? full_page_plugin : rfh))
+ rfh = pdf_rfh;
+ GetPrintRenderFrame(rfh)->InitiatePrintPreview(false);
DCHECK(!m_printPreviewRfh);
m_printPreviewRfh = rfh;
@@ -284,22 +253,36 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
PrintViewManagerQt::PrintViewManagerQt(content::WebContents *contents)
: PrintViewManagerBaseQt(contents)
+ , content::WebContentsUserData<PrintViewManagerQt>(*contents)
, m_printPreviewRfh(nullptr)
{
}
+// static
+void PrintViewManagerQt::BindPrintManagerHost(mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost> receiver,
+ content::RenderFrameHost *rfh)
+{
+ auto *web_contents = content::WebContents::FromRenderFrameHost(rfh);
+ if (!web_contents)
+ return;
+ auto *print_manager = PrintViewManagerQt::FromWebContents(web_contents);
+ if (!print_manager)
+ return;
+ print_manager->BindReceiver(std::move(receiver), rfh);
+}
+
void PrintViewManagerQt::resetPdfState()
{
m_pdfOutputPath.clear();
m_pdfPrintCallback.Reset();
m_pdfSaveCallback.Reset();
- m_printSettings.reset();
+ m_printSettings.clear();
}
void PrintViewManagerQt::PrintPreviewDone()
{
- if (IsPrintRenderFrameConnected(m_printPreviewRfh))
+ if (m_printPreviewRfh->IsRenderFrameLive() && IsPrintRenderFrameConnected(m_printPreviewRfh))
GetPrintRenderFrame(m_printPreviewRfh)->OnPrintPreviewDialogClosed();
m_printPreviewRfh = nullptr;
}
@@ -309,19 +292,19 @@ void PrintViewManagerQt::PrintPreviewDone()
void PrintViewManagerQt::NavigationStopped()
{
if (!m_pdfPrintCallback.is_null()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(m_pdfPrintCallback, QSharedPointer<QByteArray>()));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
}
resetPdfState();
PrintViewManagerBaseQt::NavigationStopped();
}
-void PrintViewManagerQt::RenderProcessGone(base::TerminationStatus status)
+void PrintViewManagerQt::PrimaryMainFrameRenderProcessGone(base::TerminationStatus status)
{
- PrintViewManagerBaseQt::RenderProcessGone(status);
+ PrintViewManagerBaseQt::PrimaryMainFrameRenderProcessGone(status);
if (!m_pdfPrintCallback.is_null()) {
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(m_pdfPrintCallback, QSharedPointer<QByteArray>()));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(m_pdfPrintCallback), QSharedPointer<QByteArray>()));
}
resetPdfState();
}
@@ -358,11 +341,26 @@ void PrintViewManagerQt::ShowScriptedPrintPreview(bool /*source_is_modifiable*/)
// ignore for now
}
-void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPreviewParamsPtr /*params*/)
+void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPreviewParamsPtr params)
{
+ if (!m_printPreviewRfh && params->webnode_only) {
+ // The preview was requested by the print button of PDF viewer plugin. The code path ends up here, because
+ // Chromium automatically initiated a preview generation. We don't want that, just notify our embedder
+ // like we do in SetupScriptedPrintPreview() after window.print() and let them decide what to do.
+ content::WebContentsView *view = static_cast<content::WebContentsImpl*>(web_contents()->GetOutermostWebContents())->GetView();
+ if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client())
+ client->printRequested();
+ return;
+ }
+
+ if (m_printSettings.empty()) {
+ PrintPreviewDone();
+ return;
+ }
+
mojo::AssociatedRemote<printing::mojom::PrintRenderFrame> printRenderFrame;
m_printPreviewRfh->GetRemoteAssociatedInterfaces()->GetInterface(&printRenderFrame);
- printRenderFrame->PrintPreview(m_printSettings->Clone());
+ printRenderFrame->PrintPreview(m_printSettings.Clone());
PrintPreviewDone();
}
@@ -375,6 +373,11 @@ void PrintViewManagerQt::CheckForCancel(int32_t preview_ui_id,
std::move(callback).Run(false);
}
+void PrintViewManagerQt::SetAccessibilityTree(int32_t, const ui::AXTreeUpdate &)
+{
+ // FIXME!
+}
+
void PrintViewManagerQt::MetafileReadyForPrinting(printing::mojom::DidPreviewDocumentParamsPtr params,
int32_t preview_ui_id)
{
@@ -390,15 +393,15 @@ void PrintViewManagerQt::MetafileReadyForPrinting(printing::mojom::DidPreviewDoc
if (!pdf_print_callback.is_null()) {
QSharedPointer<QByteArray> data_array = GetStdVectorFromHandle(params->content->metafile_data_region);
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(pdf_print_callback, data_array));
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ base::BindOnce(std::move(pdf_print_callback), data_array));
} else {
scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params->content->metafile_data_region);
- base::PostTask(FROM_HERE, {base::ThreadPool(), base::MayBlock()},
- base::BindOnce(&SavePdfFile, data_bytes, pdfOutputPath, pdf_save_callback));
+ base::ThreadPool::PostTask(FROM_HERE, { base::MayBlock() },
+ base::BindOnce(&SavePdfFile, data_bytes, pdfOutputPath, std::move(pdf_save_callback)));
}
}
-WEB_CONTENTS_USER_DATA_KEY_IMPL(PrintViewManagerQt)
+WEB_CONTENTS_USER_DATA_KEY_IMPL(PrintViewManagerQt);
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 0496a9ba7..956849ef9 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -49,7 +13,6 @@
#include "qtwebenginecoreglobal_p.h"
#include "base/memory/ref_counted.h"
-#include "base/strings/string16.h"
#include "components/prefs/pref_member.h"
#include "components/printing/common/print.mojom.h"
#include "content/public/browser/web_contents_user_data.h"
@@ -70,20 +33,24 @@ class PrintViewManagerQt
{
public:
~PrintViewManagerQt() override;
- typedef base::Callback<void(QSharedPointer<QByteArray> result)> PrintToPDFCallback;
- typedef base::Callback<void(bool success)> PrintToPDFFileCallback;
+
+ static void BindPrintManagerHost(mojo::PendingAssociatedReceiver<printing::mojom::PrintManagerHost> receiver,
+ content::RenderFrameHost *rfh);
+
+ typedef base::OnceCallback<void(QSharedPointer<QByteArray> result)> PrintToPDFCallback;
+ typedef base::OnceCallback<void(bool success)> PrintToPDFFileCallback;
// Method to print a page to a Pdf document with page size \a pageSize in location \a filePath.
void PrintToPDFFileWithCallback(const QPageLayout &pageLayout,
const QPageRanges &pageRanges,
bool printInColor,
const QString &filePath,
- const PrintToPDFFileCallback& callback);
+ PrintToPDFFileCallback callback);
void PrintToPDFWithCallback(const QPageLayout &pageLayout,
const QPageRanges &pageRanges,
bool printInColor,
bool useCustomMargins,
- const PrintToPDFCallback &callback);
+ PrintToPDFCallback callback);
protected:
explicit PrintViewManagerQt(content::WebContents*);
@@ -95,7 +62,7 @@ protected:
void NavigationStopped() override;
// Terminates or cancels the print job if one was pending.
- void RenderProcessGone(base::TerminationStatus status) override;
+ void PrimaryMainFrameRenderProcessGone(base::TerminationStatus status) override;
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
@@ -108,7 +75,7 @@ protected:
CheckForCancelCallback callback) override;
void MetafileReadyForPrinting(printing::mojom::DidPreviewDocumentParamsPtr params,
int32_t preview_ui_id) override;
-
+ void SetAccessibilityTree(int32_t, const ui::AXTreeUpdate &) override;
private:
void resetPdfState();
@@ -120,10 +87,9 @@ private:
base::FilePath m_pdfOutputPath;
PrintToPDFCallback m_pdfPrintCallback;
PrintToPDFFileCallback m_pdfSaveCallback;
- std::unique_ptr<base::DictionaryValue> m_printSettings;
+ base::Value::Dict m_printSettings;
friend class content::WebContentsUserData<PrintViewManagerQt>;
- DISALLOW_COPY_AND_ASSIGN(PrintViewManagerQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/printing/printer_worker.cpp b/src/core/printing/printer_worker.cpp
index 411e326c3..6032f2211 100644
--- a/src/core/printing/printer_worker.cpp
+++ b/src/core/printing/printer_worker.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "printer_worker.h"
@@ -63,22 +27,8 @@ void PrinterWorker::print()
PdfiumDocumentWrapperQt pdfiumWrapper(m_data->constData(), m_data->size());
- const QPageRanges ranges = m_device->pageRanges();
- int toPage = ranges.firstPage();
- int fromPage = ranges.lastPage();
- bool ascendingOrder = true;
-
- if (fromPage == 0 && toPage == 0) {
- fromPage = 1;
- toPage = pdfiumWrapper.pageCount();
- }
- fromPage = qMax(1, fromPage);
- toPage = qMin(pdfiumWrapper.pageCount(), toPage);
-
- if (!m_firstPageFirst) {
- qSwap(fromPage, toPage);
- ascendingOrder = false;
- }
+ const int fromPage = m_firstPageFirst ? 0 : pdfiumWrapper.pageCount() - 1;
+ const int toPage = m_firstPageFirst ? pdfiumWrapper.pageCount() : -1;
int pageCopies = 1;
if (m_collateCopies) {
@@ -94,15 +44,13 @@ void PrinterWorker::print()
if (printedDocuments > 0)
m_device->newPage();
- int currentPageIndex = fromPage;
-
- for (int i = 0; true; i++) {
- QSizeF documentSize = (pdfiumWrapper.pageSize(currentPageIndex - 1) * resolution);
+ for (int i = fromPage; i != toPage; m_firstPageFirst ? i++ : i--) {
+ QSizeF documentSize = (pdfiumWrapper.pageSize(i) * resolution);
bool isLandscape = documentSize.width() > documentSize.height();
m_device->setPageOrientation(isLandscape ? QPageLayout::Landscape
: QPageLayout::Portrait);
- QRectF pageRect = m_device->pageLayout().pageSize().rectPixels(m_deviceResolution);
- documentSize = documentSize.scaled(pageRect.size(), Qt::KeepAspectRatio);
+ QRectF paintRect = m_device->pageLayout().paintRectPixels(m_deviceResolution);
+ documentSize = documentSize.scaled(paintRect.size(), Qt::KeepAspectRatio);
// setPageOrientation has to be called before qpainter.begin() or before
// qprinter.newPage() so correct metrics is used, therefore call begin now for only
@@ -113,29 +61,21 @@ void PrinterWorker::print()
return;
}
- if (i > 0)
+ if (i != fromPage)
m_device->newPage();
for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
if (printedPages > 0)
m_device->newPage();
- QImage currentImage = pdfiumWrapper.pageAsQImage(
- currentPageIndex - 1, documentSize.width(), documentSize.height());
+ QImage currentImage =
+ pdfiumWrapper.pageAsQImage(i, documentSize.width(), documentSize.height());
if (currentImage.isNull()) {
Q_EMIT resultReady(false);
return;
}
painter.drawImage(0, 0, currentImage);
}
-
- if (currentPageIndex == toPage)
- break;
-
- if (ascendingOrder)
- currentPageIndex++;
- else
- currentPageIndex--;
}
}
painter.end();
diff --git a/src/core/printing/printer_worker.h b/src/core/printing/printer_worker.h
index 3681312a9..0d2454fa0 100644
--- a/src/core/printing/printer_worker.h
+++ b/src/core/printing/printer_worker.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,7 +17,8 @@
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
-#include <QSharedPointer>
+#include <QtCore/qobject.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
class QPagedPaintDevice;
@@ -61,7 +26,7 @@ QT_END_NAMESPACE
namespace QtWebEngineCore {
-class Q_WEBENGINECORE_PRIVATE_EXPORT PrinterWorker : public QObject
+class Q_WEBENGINECORE_EXPORT PrinterWorker : public QObject
{
Q_OBJECT
public:
diff --git a/src/core/process_main.cpp b/src/core/process_main.cpp
index 709f8bd6d..6a7d26ffd 100644
--- a/src/core/process_main.cpp
+++ b/src/core/process_main.cpp
@@ -1,50 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtwebenginecoreglobal_p.h"
#include "content_main_delegate_qt.h"
#include "content/public/app/content_main.h"
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
#include "sandbox/win/src/sandbox_types.h"
#include "content/public/app/sandbox_helper_win.h"
-#elif defined(OS_MAC)
-#include "base/logging.h"
+#elif BUILDFLAG(IS_MAC)
#include "sandbox/mac/seatbelt_exec.h"
#endif
@@ -56,10 +19,10 @@ int processMain(int argc, const char **argv)
ContentMainDelegateQt delegate;
content::ContentMainParams params(&delegate);
-#if defined(OS_WIN)
+#if BUILDFLAG(IS_WIN)
HINSTANCE instance_handle = NULL;
params.sandbox_info = QtWebEngineSandbox::staticSandboxInterfaceInfo();
- sandbox::SandboxInterfaceInfo sandbox_info = {0};
+ sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
if (!params.sandbox_info) {
content::InitializeSandboxInfo(&sandbox_info);
params.sandbox_info = &sandbox_info;
@@ -68,16 +31,15 @@ int processMain(int argc, const char **argv)
#else
params.argc = argc;
params.argv = argv;
-#endif // OS_WIN
-#if defined(OS_MAC)
+#endif // IS_WIN
+#if BUILDFLAG(IS_MAC)
sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt =
sandbox::SeatbeltExecServer::CreateFromArguments(argv[0], argc, const_cast<char**>(argv));
if (seatbelt.sandbox_required) {
CHECK(seatbelt.server->InitializeSandbox());
}
-#endif // defined(OS_MAC)
-
- return content::ContentMain(params);
+#endif // IS_MAC
+ return content::ContentMain(std::move(params));
}
} // namespace QtWebEngineCore
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 7f7b7181e..b26f9b1de 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -1,45 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "profile_adapter.h"
+#include "base/files/file_util.h"
#include "base/task/cancelable_task_tracker.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/time/time_to_iso8601.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "components/favicon/core/favicon_service.h"
#include "components/history/content/browser/history_database_helper.h"
#include "components/history/core/browser/history_database_params.h"
@@ -48,9 +16,8 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/download_manager.h"
-#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/browser/storage_partition.h"
-#include "services/network/public/cpp/cors/origin_access_list.h"
+#include "services/network/public/mojom/network_context.mojom.h"
#include "url/url_util.h"
#include "api/qwebengineurlscheme.h"
@@ -64,12 +31,8 @@
#include "renderer_host/user_resource_controller_host.h"
#include "type_conversion.h"
#include "visited_links_manager_qt.h"
-#include "web_engine_context.h"
#include "web_contents_adapter_client.h"
-
-#include "base/files/file_util.h"
-#include "base/time/time_to_iso8601.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "web_engine_context.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/browser/extension_system.h"
@@ -77,6 +40,8 @@
#include <QCoreApplication>
#include <QDir>
+#include <QJsonObject>
+#include <QSet>
#include <QString>
#include <QStandardPaths>
@@ -100,6 +65,8 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_clientHintsEnabled(true)
+ , m_pushServiceEnabled(false)
, m_httpCacheMaxSize(0)
{
WebEngineContext::current()->addProfileAdapter(this);
@@ -113,18 +80,19 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
extensions::ExtensionSystem::Get(m_profile.data())->InitForRegularProfile(true);
#endif
m_cancelableTaskTracker.reset(new base::CancelableTaskTracker());
+
+ m_profile->DoFinalInit();
}
ProfileAdapter::~ProfileAdapter()
{
m_cancelableTaskTracker->TryCancelAll();
- content::BrowserContext::NotifyWillBeDestroyed(m_profile.data());
- while (!m_webContentsAdapterClients.isEmpty()) {
- m_webContentsAdapterClients.first()->releaseProfile();
- }
+ m_profile->NotifyWillBeDestroyed();
+ releaseAllWebContentsAdapterClients();
+
WebEngineContext::current()->removeProfileAdapter(this);
if (m_downloadManagerDelegate) {
- m_profile->GetDownloadManager(m_profile.data())->Shutdown();
+ m_profile->GetDownloadManager()->Shutdown();
m_downloadManagerDelegate.reset();
}
#if QT_CONFIG(ssl)
@@ -175,6 +143,26 @@ ProfileQt *ProfileAdapter::profile()
return m_profile.data();
}
+bool ProfileAdapter::ensureDataPathExists()
+{
+ Q_ASSERT(!m_offTheRecord);
+ base::ScopedAllowBlocking allowBlock;
+ const base::FilePath &path = toFilePath(dataPath());
+ if (path.empty())
+ return false;
+ if (base::DirectoryExists(path))
+ return true;
+
+ base::File::Error error;
+ if (base::CreateDirectoryAndGetError(path, &error))
+ return true;
+
+ std::string errorstr = base::File::ErrorToString(error);
+ qWarning("Cannot create directory %s. Error: %s.", path.AsUTF8Unsafe().c_str(),
+ errorstr.c_str());
+ return false;
+}
+
VisitedLinksManagerQt *ProfileAdapter::visitedLinksManager()
{
if (!m_visitedLinksManager)
@@ -216,9 +204,9 @@ void ProfileAdapter::removeClient(ProfileAdapterClient *adapterClient)
m_clients.removeOne(adapterClient);
}
-void ProfileAdapter::cancelDownload(quint32 downloadId)
+bool ProfileAdapter::cancelDownload(quint32 downloadId)
{
- downloadManagerDelegate()->cancelDownload(downloadId);
+ return downloadManagerDelegate()->cancelDownload(downloadId);
}
void ProfileAdapter::pauseDownload(quint32 downloadId)
@@ -334,13 +322,16 @@ void ProfileAdapter::setHttpUserAgent(const QString &userAgent)
std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
for (content::WebContentsImpl *web_contents : list)
- if (web_contents->GetBrowserContext() == m_profile.data())
- web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(stdUserAgent), true);
+ if (web_contents->GetBrowserContext() == m_profile.data()) {
+ auto userAgentOverride = blink::UserAgentOverride::UserAgentOnly(stdUserAgent);
+ userAgentOverride.ua_metadata_override = m_profile->m_userAgentMetadata;
+ web_contents->SetUserAgentOverride(userAgentOverride, true);
+ }
- content::BrowserContext::ForEachStoragePartition(
- m_profile.get(), base::BindRepeating([](const std::string &user_agent, content::StoragePartition *storage_partition) {
- storage_partition->GetNetworkContext()->SetUserAgent(user_agent);
- }, stdUserAgent));
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](const std::string &user_agent, content::StoragePartition *storage_partition) {
+ storage_partition->GetNetworkContext()->SetUserAgent(user_agent);
+ }, stdUserAgent));
}
ProfileAdapter::HttpCacheType ProfileAdapter::httpCacheType() const
@@ -360,8 +351,6 @@ void ProfileAdapter::setHttpCacheType(ProfileAdapter::HttpCacheType newhttpCache
return;
if (!m_offTheRecord && !m_profile->m_profileIOData->isClearHttpCacheInProgress()) {
m_profile->m_profileIOData->resetNetworkContext();
- if (m_httpCacheType == NoCache)
- clearHttpCache();
}
}
@@ -479,10 +468,10 @@ const QList<QByteArray> ProfileAdapter::customUrlSchemes() const
void ProfileAdapter::updateCustomUrlSchemeHandlers()
{
- content::BrowserContext::ForEachStoragePartition(
- m_profile.get(), base::BindRepeating([](content::StoragePartition *storage_partition) {
- storage_partition->ResetURLLoaderFactories();
- }));
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](content::StoragePartition *storage_partition) {
+ storage_partition->ResetURLLoaderFactories();
+ }));
}
void ProfileAdapter::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
@@ -601,10 +590,114 @@ void ProfileAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
}
}
- content::BrowserContext::ForEachStoragePartition(
- m_profile.get(), base::BindRepeating([](std::string accept_language, content::StoragePartition *storage_partition) {
- storage_partition->GetNetworkContext()->SetAcceptLanguage(accept_language);
- }, http_accept_language));
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](std::string accept_language, content::StoragePartition *storage_partition) {
+ storage_partition->GetNetworkContext()->SetAcceptLanguage(accept_language);
+ }, http_accept_language));
+}
+
+QVariant ProfileAdapter::clientHint(ClientHint clientHint) const
+{
+ blink::UserAgentMetadata &userAgentMetadata = m_profile->m_userAgentMetadata;
+ switch (clientHint) {
+ case ProfileAdapter::UAArchitecture:
+ return QVariant(toQString(userAgentMetadata.architecture));
+ case ProfileAdapter::UAPlatform:
+ return QVariant(toQString(userAgentMetadata.platform));
+ case ProfileAdapter::UAModel:
+ return QVariant(toQString(userAgentMetadata.model));
+ case ProfileAdapter::UAMobile:
+ return QVariant(userAgentMetadata.mobile);
+ case ProfileAdapter::UAFullVersion:
+ return QVariant(toQString(userAgentMetadata.full_version));
+ case ProfileAdapter::UAPlatformVersion:
+ return QVariant(toQString(userAgentMetadata.platform_version));
+ case ProfileAdapter::UABitness:
+ return QVariant(toQString(userAgentMetadata.bitness));
+ case ProfileAdapter::UAFullVersionList: {
+ QJsonObject ret;
+ for (const auto &value : userAgentMetadata.brand_full_version_list)
+ ret.insert(toQString(value.brand), QJsonValue(toQString(value.version)));
+ return QVariant(ret);
+ }
+ case ProfileAdapter::UAWOW64:
+ return QVariant(userAgentMetadata.wow64);
+ default:
+ return QVariant();
+ }
+}
+
+void ProfileAdapter::setClientHint(ClientHint clientHint, const QVariant &value)
+{
+ blink::UserAgentMetadata &userAgentMetadata = m_profile->m_userAgentMetadata;
+ switch (clientHint) {
+ case ProfileAdapter::UAArchitecture:
+ userAgentMetadata.architecture = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAPlatform:
+ userAgentMetadata.platform = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAModel:
+ userAgentMetadata.model = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAMobile:
+ userAgentMetadata.mobile = value.toBool();
+ break;
+ case ProfileAdapter::UAFullVersion:
+ userAgentMetadata.full_version = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAPlatformVersion:
+ userAgentMetadata.platform_version = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UABitness:
+ userAgentMetadata.bitness = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAFullVersionList: {
+ userAgentMetadata.brand_full_version_list.clear();
+ QJsonObject fullVersionList = value.toJsonObject();
+ for (const QString &key : fullVersionList.keys())
+ userAgentMetadata.brand_full_version_list.push_back({
+ key.toStdString(),
+ fullVersionList.value(key).toString().toStdString()
+ });
+ break;
+ }
+ case ProfileAdapter::UAWOW64:
+ userAgentMetadata.wow64 = value.toBool();
+ break;
+ default:
+ break;
+ }
+
+ std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
+ for (content::WebContentsImpl *web_contents : list) {
+ if (web_contents->GetBrowserContext() == m_profile.data()) {
+ web_contents->GetMutableRendererPrefs()->user_agent_override.ua_metadata_override = userAgentMetadata;
+ web_contents->SyncRendererPrefs();
+ }
+ }
+}
+
+bool ProfileAdapter::clientHintsEnabled()
+{
+ return m_clientHintsEnabled;
+}
+
+void ProfileAdapter::setClientHintsEnabled(bool enabled)
+{
+ m_clientHintsEnabled = enabled;
+}
+
+void ProfileAdapter::resetClientHints()
+{
+ m_profile->m_userAgentMetadata = embedder_support::GetUserAgentMetadata();
+ std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
+ for (content::WebContentsImpl *web_contents : list) {
+ if (web_contents->GetBrowserContext() == m_profile.data()) {
+ web_contents->GetMutableRendererPrefs()->user_agent_override.ua_metadata_override = m_profile->m_userAgentMetadata;
+ web_contents->SyncRendererPrefs();
+ }
+ }
}
void ProfileAdapter::clearHttpCache()
@@ -644,6 +737,16 @@ bool ProfileAdapter::isSpellCheckEnabled() const
#endif
}
+bool ProfileAdapter::pushServiceEnabled() const
+{
+ return m_pushServiceEnabled;
+}
+
+void ProfileAdapter::setPushServiceEnabled(bool enabled)
+{
+ m_pushServiceEnabled = enabled;
+}
+
void ProfileAdapter::addWebContentsAdapterClient(WebContentsAdapterClient *client)
{
m_webContentsAdapterClients.append(client);
@@ -654,6 +757,12 @@ void ProfileAdapter::removeWebContentsAdapterClient(WebContentsAdapterClient *cl
m_webContentsAdapterClients.removeAll(client);
}
+void ProfileAdapter::releaseAllWebContentsAdapterClients()
+{
+ while (!m_webContentsAdapterClients.isEmpty())
+ m_webContentsAdapterClients.first()->releaseProfile();
+}
+
void ProfileAdapter::resetVisitedLinksManager()
{
m_visitedLinksManager.reset(new VisitedLinksManagerQt(m_profile.data(), persistVisitedLinks()));
@@ -661,8 +770,8 @@ void ProfileAdapter::resetVisitedLinksManager()
void ProfileAdapter::reinitializeHistoryService()
{
- Q_ASSERT(!m_profile->IsOffTheRecord());
- if (m_profile->ensureDirectoryExists()) {
+ Q_ASSERT(!m_offTheRecord);
+ if (ensureDataPathExists()) {
favicon::FaviconService *faviconService =
FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
history::HistoryService *historyService = static_cast<history::HistoryService *>(
@@ -680,7 +789,11 @@ QString ProfileAdapter::determineDownloadPath(const QString &downloadDirectory,
QString suggestedFilePath = suggestedFile.absoluteFilePath();
base::FilePath tmpFilePath(toFilePath(suggestedFilePath).NormalizePathSeparatorsTo('/'));
- int uniquifier = base::GetUniquePathNumber(tmpFilePath);
+ int uniquifier = 0;
+ {
+ base::ScopedAllowBlocking allowBlock;
+ uniquifier = base::GetUniquePathNumber(tmpFilePath);
+ }
if (uniquifier > 0)
suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", uniquifier)).AsUTF8Unsafe());
else if (uniquifier == -1) {
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 373d6e2a9..4be0ea51e 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,10 +17,11 @@
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
-#include <QEnableSharedFromThis>
+#include <QHash>
#include <QList>
#include <QPointer>
#include <QScopedPointer>
+#include <QSharedPointer>
#include <QString>
#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
@@ -81,7 +46,7 @@ class UserResourceControllerHost;
class VisitedLinksManagerQt;
class WebContentsAdapterClient;
-class Q_WEBENGINECORE_PRIVATE_EXPORT ProfileAdapter : public QObject
+class Q_WEBENGINECORE_EXPORT ProfileAdapter : public QObject
{
public:
explicit ProfileAdapter(const QString &storagePrefix = QString());
@@ -103,12 +68,13 @@ public:
void addClient(ProfileAdapterClient *adapterClient);
void removeClient(ProfileAdapterClient *adapterClient);
- void cancelDownload(quint32 downloadId);
+ bool cancelDownload(quint32 downloadId);
void pauseDownload(quint32 downloadId);
void resumeDownload(quint32 downloadId);
void removeDownload(quint32 downloadId);
ProfileQt *profile();
+ bool ensureDataPathExists();
QString storageName() const { return m_name; }
void setStorageName(const QString &storageName);
@@ -135,8 +101,12 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
+ bool pushServiceEnabled() const;
+ void setPushServiceEnabled(bool enabled);
+
void addWebContentsAdapterClient(WebContentsAdapterClient *client);
void removeWebContentsAdapterClient(WebContentsAdapterClient *client);
+ void releaseAllWebContentsAdapterClients();
// KEEP IN SYNC with API or add mapping layer
enum HttpCacheType {
@@ -163,8 +133,8 @@ public:
NotificationPermission = 2,
AudioCapturePermission = 3,
VideoCapturePermission = 4,
- ClipboardRead = 5,
- ClipboardWrite = 6,
+ ClipboardReadWrite = 5,
+ LocalFontsPermission = 6,
};
enum PermissionState {
@@ -173,6 +143,18 @@ public:
DeniedPermission = 2
};
+ enum ClientHint : uchar {
+ UAArchitecture,
+ UAPlatform,
+ UAModel,
+ UAMobile,
+ UAFullVersion,
+ UAPlatformVersion,
+ UABitness,
+ UAFullVersionList,
+ UAWOW64,
+ };
+
HttpCacheType httpCacheType() const;
void setHttpCacheType(ProfileAdapter::HttpCacheType);
@@ -203,6 +185,12 @@ public:
QString httpAcceptLanguage() const;
void setHttpAcceptLanguage(const QString &httpAcceptLanguage);
+ QVariant clientHint(ClientHint clientHint) const;
+ void setClientHint(ClientHint clientHint, const QVariant &value);
+ bool clientHintsEnabled();
+ void setClientHintsEnabled(bool enabled);
+ void resetClientHints();
+
void clearHttpCache();
#if QT_CONFIG(ssl)
@@ -251,9 +239,11 @@ private:
QHash<QByteArray, QPointer<QWebEngineUrlSchemeHandler>> m_customUrlSchemeHandlers;
QHash<QByteArray, QWeakPointer<UserNotificationController>> m_ephemeralNotifications;
QHash<QByteArray, QSharedPointer<UserNotificationController>> m_persistentNotifications;
+ bool m_clientHintsEnabled;
QList<ProfileAdapterClient*> m_clients;
QList<WebContentsAdapterClient *> m_webContentsAdapterClients;
+ bool m_pushServiceEnabled;
int m_httpCacheMaxSize;
QrcUrlSchemeHandler m_qrcHandler;
std::unique_ptr<base::CancelableTaskTracker> m_cancelableTaskTracker;
diff --git a/src/core/profile_adapter_client.cpp b/src/core/profile_adapter_client.cpp
index 9aa084da9..b6a16c21a 100644
--- a/src/core/profile_adapter_client.cpp
+++ b/src/core/profile_adapter_client.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "profile_adapter_client.h"
#include "components/download/public/common/download_item.h"
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index 9329b504c..06ac0de8b 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -1,41 +1,5 @@
- /****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -60,9 +24,10 @@
namespace QtWebEngineCore {
class WebContentsAdapterClient;
+class WebEngineSettings;
class UserNotificationController;
-class Q_WEBENGINECORE_PRIVATE_EXPORT ProfileAdapterClient
+class Q_WEBENGINECORE_EXPORT ProfileAdapterClient
{
public:
// Keep in sync with content::DownloadItem::DownloadState
@@ -144,6 +109,9 @@ public:
virtual void addWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
virtual void removeWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
+ virtual WebEngineSettings *coreSettings() const = 0;
+ virtual void clearHttpCacheCompleted() = 0;
+
static QString downloadInterruptReasonToString(DownloadInterruptReason reason);
};
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index bc256bb08..859aff8d4 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -1,69 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "profile_io_data_qt.h"
-#include "base/task/post_task.h"
#include "content/browser/storage_partition_impl.h"
-#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
-#include "content/public/browser/network_service_instance.h"
+#include "content/public/browser/resource_context.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
-#include "content/public/common/content_features.h"
-#include "net/ssl/ssl_config_service_defaults.h"
-#include "services/cert_verifier/cert_verifier_creation.h"
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
-#include "services/network/public/mojom/cert_verifier_service.mojom.h"
-#include "net/client_cert_override.h"
+#include "net/client_cert_qt.h"
#include "net/client_cert_store_data.h"
#include "net/cookie_monster_delegate_qt.h"
#include "net/system_network_context_manager.h"
+#include "profile_adapter_client.h"
#include "profile_qt.h"
-#include "resource_context_qt.h"
#include "type_conversion.h"
-#include <QDebug>
-#include <mutex>
-
namespace QtWebEngineCore {
ProfileIODataQt::ProfileIODataQt(ProfileQt *profile)
@@ -102,11 +57,9 @@ void ProfileIODataQt::shutdownOnUIThread()
m_cookieDelegate->unsetMojoCookieManager();
m_proxyConfigMonitor.reset();
- if (m_clearHttpCacheInProgress) {
- m_clearHttpCacheInProgress = false;
- content::BrowsingDataRemover *remover =
- content::BrowserContext::GetBrowsingDataRemover(m_profileAdapter->profile());
- remover->RemoveObserver(&m_removerObserver);
+ if (m_clearHttpCacheState == Removing) {
+ m_clearHttpCacheState = Completed;
+ removeBrowsingDataRemoverObserver();
}
bool posted = content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, this);
@@ -138,7 +91,7 @@ void ProfileIODataQt::initializeOnUIThread()
{
m_profileAdapter = m_profile->profileAdapter();
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- m_resourceContext.reset(new ResourceContextQt(this));
+ m_resourceContext.reset(new content::ResourceContext());
m_cookieDelegate = new CookieMonsterDelegateQt();
m_cookieDelegate->setClient(m_profile->profileAdapter()->cookieStore());
m_proxyConfigMonitor.reset(new ProxyConfigMonitor(m_profile->GetPrefs()));
@@ -147,10 +100,10 @@ void ProfileIODataQt::initializeOnUIThread()
void ProfileIODataQt::clearHttpCache()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- if (!m_clearHttpCacheInProgress) {
- m_clearHttpCacheInProgress = true;
+ if (m_clearHttpCacheState == Completed) {
+ m_clearHttpCacheState = Removing;
content::BrowsingDataRemover *remover =
- content::BrowserContext::GetBrowsingDataRemover(m_profileAdapter->profile());
+ m_profileAdapter->profile()->GetBrowsingDataRemover();
remover->AddObserver(&m_removerObserver);
remover->RemoveAndReply(base::Time(), base::Time::Max(),
content::BrowsingDataRemover::DATA_TYPE_CACHE,
@@ -163,7 +116,7 @@ void ProfileIODataQt::clearHttpCache()
void ProfileIODataQt::removeBrowsingDataRemoverObserver()
{
content::BrowsingDataRemover *remover =
- content::BrowserContext::GetBrowsingDataRemover(m_profileAdapter->profile());
+ m_profileAdapter->profile()->GetBrowsingDataRemover();
remover->RemoveObserver(&m_removerObserver);
}
@@ -174,9 +127,9 @@ BrowsingDataRemoverObserverQt::BrowsingDataRemoverObserverQt(ProfileIODataQt *pr
void BrowsingDataRemoverObserverQt::OnBrowsingDataRemoverDone(uint64_t)
{
- Q_ASSERT(m_profileIOData->m_clearHttpCacheInProgress);
+ Q_ASSERT(m_profileIOData->m_clearHttpCacheState == ProfileIODataQt::Removing);
m_profileIOData->removeBrowsingDataRemoverObserver();
- m_profileIOData->m_clearHttpCacheInProgress = false;
+ m_profileIOData->m_clearHttpCacheState = ProfileIODataQt::Resetting;
m_profileIOData->resetNetworkContext();
}
@@ -197,13 +150,44 @@ void ProfileIODataQt::setFullConfiguration()
void ProfileIODataQt::resetNetworkContext()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ Q_ASSERT(m_clearHttpCacheState != Removing);
setFullConfiguration();
- content::BrowserContext::ForEachStoragePartition(
- m_profile, base::BindRepeating([](content::StoragePartition *storage) {
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](ProfileIODataQt *profileData,
+ content::StoragePartition *storage) {
+ storage->SetNetworkContextCreatedObserver(profileData);
+
auto storage_impl = static_cast<content::StoragePartitionImpl *>(storage);
storage_impl->ResetURLLoaderFactories();
storage_impl->ResetNetworkContext();
- }));
+ }, this));
+}
+
+void ProfileIODataQt::OnNetworkContextCreated(content::StoragePartition *storage)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ storage->SetNetworkContextCreatedObserver(nullptr);
+
+ if (m_clearHttpCacheState != Resetting)
+ return;
+
+ bool pendingReset = false;
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](bool *pendingReset,
+ ProfileIODataQt *profileData,
+ content::StoragePartition *storage) {
+ if (storage->GetNetworkContextCreatedObserver() == profileData)
+ *pendingReset = true;
+ }, &pendingReset, this));
+
+ if (pendingReset)
+ return;
+
+ m_clearHttpCacheState = Completed;
+
+ for (ProfileAdapterClient *client : m_profileAdapter->clients())
+ client->clearHttpCacheCompleted();
}
bool ProfileIODataQt::canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const
@@ -221,9 +205,9 @@ ClientCertificateStoreData *ProfileIODataQt::clientCertificateStoreData()
std::unique_ptr<net::ClientCertStore> ProfileIODataQt::CreateClientCertStore()
{
#if QT_CONFIG(ssl)
- return std::unique_ptr<net::ClientCertStore>(new ClientCertOverrideStore(m_clientCertificateStoreData));
+ return std::unique_ptr<net::ClientCertStore>(new ClientCertStoreQt(m_clientCertificateStoreData));
#else
- return std::unique_ptr<net::ClientCertStore>(new ClientCertOverrideStore(nullptr));
+ return std::unique_ptr<net::ClientCertStore>(new ClientCertStoreQt(nullptr));
#endif
}
@@ -236,7 +220,6 @@ void ProfileIODataQt::ConfigureNetworkContextParams(bool in_memory,
SystemNetworkContextManager::GetInstance()->ConfigureDefaultNetworkContextParams(network_context_params, cert_verifier_creation_params);
- network_context_params->context_name = m_storageName.toStdString();
network_context_params->user_agent = m_httpUserAgent.toStdString();
network_context_params->accept_language = m_httpAcceptLanguage.toStdString();
@@ -246,26 +229,24 @@ void ProfileIODataQt::ConfigureNetworkContextParams(bool in_memory,
network_context_params->http_cache_enabled = m_httpCacheType != ProfileAdapter::NoCache;
network_context_params->http_cache_max_size = m_httpCacheMaxSize;
- if (m_httpCacheType == ProfileAdapter::DiskHttpCache && !m_httpCachePath.isEmpty() && !m_inMemoryOnly && !in_memory)
- network_context_params->http_cache_path = toFilePath(m_httpCachePath);
- if (m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies && !m_inMemoryOnly && !in_memory) {
- base::FilePath cookie_path = toFilePath(m_dataPath);
- cookie_path = cookie_path.AppendASCII("Cookies");
- network_context_params->cookie_path = cookie_path;
-
- network_context_params->restore_old_session_cookies = m_persistentCookiesPolicy == ProfileAdapter::ForcePersistentCookies;
- network_context_params->persist_session_cookies = m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies;
- }
+ network_context_params->persist_session_cookies = false;
if (!m_inMemoryOnly && !in_memory) {
- network_context_params->http_server_properties_path = toFilePath(m_dataPath).AppendASCII("Network Persistent State");
- network_context_params->transport_security_persister_path = toFilePath(m_dataPath);
+ network_context_params->file_paths =
+ network::mojom::NetworkContextFilePaths::New();
+ network_context_params->file_paths->data_directory = toFilePath(m_dataPath);
+ network_context_params->file_paths->http_server_properties_file_name = base::FilePath::FromASCII("Network Persistent State");
+ network_context_params->file_paths->transport_security_persister_file_name = base::FilePath::FromASCII("TransportSecurity");
+ network_context_params->file_paths->trust_token_database_name = base::FilePath::FromASCII("Trust Tokens");
+ if (m_httpCacheType == ProfileAdapter::DiskHttpCache && !m_httpCachePath.isEmpty())
+ network_context_params->file_paths->http_cache_directory = toFilePath(m_httpCachePath);
+ if (m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies) {
+ network_context_params->file_paths->cookie_database_name = base::FilePath::FromASCII("Cookies");
+ network_context_params->restore_old_session_cookies = m_persistentCookiesPolicy == ProfileAdapter::ForcePersistentCookies;
+ network_context_params->persist_session_cookies = m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies;
+ }
}
-#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
- network_context_params->enable_ftp_url_support = true;
-#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
-
network_context_params->enforce_chrome_ct_policy = false;
// Should be initialized with existing per-profile CORS access lists.
@@ -282,11 +263,4 @@ ProfileIODataQt *ProfileIODataQt::FromBrowserContext(content::BrowserContext *br
return static_cast<ProfileQt *>(browser_context)->m_profileIOData.get();
}
-// static
-ProfileIODataQt *ProfileIODataQt::FromResourceContext(content::ResourceContext *resource_context)
-{
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- return static_cast<ResourceContextQt *>(resource_context)->m_io_data;
-}
-
} // namespace QtWebEngineCore
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 6bd555dbf..0d032e4dc 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -1,47 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PROFILE_IO_DATA_QT_H
#define PROFILE_IO_DATA_QT_H
#include "content/public/browser/browsing_data_remover.h"
-#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/storage_partition.h"
#include "extensions/buildflags/buildflags.h"
#include "net/proxy_config_monitor.h"
@@ -49,21 +13,25 @@
#include <QtCore/QString>
#include <QtCore/QPointer>
-#include <QtCore/QMutex>
+#include <QtCore/QRecursiveMutex>
namespace cert_verifier {
namespace mojom {
class CertVerifierCreationParams;
}}
-namespace net {
-class ClientCertStore;
+namespace content {
+class ResourceContext;
}
namespace extensions {
class ExtensionSystemQt;
}
+namespace net {
+class ClientCertStore;
+}
+
namespace QtWebEngineCore {
struct ClientCertificateStoreData;
@@ -85,9 +53,15 @@ private:
// we still use shared memebers and use mutex which breaks
// idea for this object, but this is wip.
-class ProfileIODataQt {
+class ProfileIODataQt : public content::StoragePartition::NetworkContextCreatedObserver {
public:
+ enum ClearHttpCacheState {
+ Completed = 0,
+ Removing,
+ Resetting
+ };
+
ProfileIODataQt(ProfileQt *profile); // runs on ui thread
virtual ~ProfileIODataQt();
@@ -104,8 +78,9 @@ public:
void setFullConfiguration(); // runs on ui thread
void resetNetworkContext(); // runs on ui thread
+
void clearHttpCache(); // runs on ui thread
- bool isClearHttpCacheInProgress() { return m_clearHttpCacheInProgress; }
+ bool isClearHttpCacheInProgress() const { return m_clearHttpCacheState != Completed; }
void ConfigureNetworkContextParams(bool in_memory,
const base::FilePath &relative_partition_path,
@@ -117,12 +92,14 @@ public:
#endif
std::unique_ptr<net::ClientCertStore> CreateClientCertStore();
static ProfileIODataQt *FromBrowserContext(content::BrowserContext *browser_context);
- static ProfileIODataQt *FromResourceContext(content::ResourceContext *resource_context);
base::WeakPtr<ProfileIODataQt> getWeakPtrOnIOThread();
CookieMonsterDelegateQt *cookieDelegate() const { return m_cookieDelegate.get(); }
+ // content::StoragePartition::NetworkContextCreatedObserver overrides:
+ void OnNetworkContextCreated(content::StoragePartition *storage) override; // runs on ui thread
+
private:
void removeBrowsingDataRemoverObserver();
@@ -146,9 +123,8 @@ private:
int m_httpCacheMaxSize = 0;
BrowsingDataRemoverObserverQt m_removerObserver;
QString m_dataPath;
- bool m_clearHttpCacheInProgress = false;
+ ClearHttpCacheState m_clearHttpCacheState = Completed;
base::WeakPtrFactory<ProfileIODataQt> m_weakPtrFactory; // this should be always the last member
- DISALLOW_COPY_AND_ASSIGN(ProfileIODataQt);
friend class BrowsingDataRemoverObserverQt;
};
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index ec7da1406..293e8d557 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -1,85 +1,40 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "profile_qt.h"
#include "profile_adapter.h"
#include "browsing_data_remover_delegate_qt.h"
+#include "client_hints.h"
#include "download_manager_delegate_qt.h"
+#include "file_system_access/file_system_access_permission_context_factory_qt.h"
#include "net/ssl_host_state_delegate_qt.h"
#include "permission_manager_qt.h"
+#include "profile_io_data_qt.h"
#include "platform_notification_service_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
#include "web_engine_library_info.h"
#include "web_engine_context.h"
-#include "base/barrier_closure.h"
-#include "base/time/time.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_origin_pattern_setter.h"
-#include "content/public/browser/shared_cors_origin_access_list.h"
-#include "content/public/browser/storage_partition.h"
-
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/prefs/pref_member.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/in_memory_pref_store.h"
-#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_service.h"
-#include "components/prefs/pref_service_factory.h"
-#include "components/prefs/pref_registry_simple.h"
#include "components/user_prefs/user_prefs.h"
-#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
-#include "chrome/common/pref_names.h"
-#if QT_CONFIG(webengine_spellchecker)
-#include "chrome/browser/spellchecker/spellcheck_service.h"
-#include "components/spellcheck/browser/pref_names.h"
-#endif
+#include "components/profile_metrics/browser_profile_type.h"
+#include "content/public/browser/browser_thread.h"
+#include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
+#include "chrome/browser/push_messaging/push_messaging_service_factory.h"
+#include "chrome/browser/push_messaging/push_messaging_service_impl.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "base/command_line.h"
#include "components/guest_view/browser/guest_view_manager.h"
-#include "extensions/browser/pref_names.h"
-#include "extensions/browser/process_manager.h"
-#include "extensions/common/constants.h"
+#include "extensions/browser/extension_pref_value_map_factory.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_prefs_factory.h"
+#include "extensions/browser/extensions_browser_client.h"
#include "extensions/extension_system_qt.h"
#endif
@@ -87,13 +42,17 @@
namespace QtWebEngineCore {
ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
- : m_sharedCorsOriginAccessList(content::SharedCorsOriginAccessList::Create())
- , m_profileIOData(new ProfileIODataQt(this))
+ : m_profileIOData(new ProfileIODataQt(this))
, m_profileAdapter(profileAdapter)
+ , m_userAgentMetadata(embedder_support::GetUserAgentMetadata())
#if BUILDFLAG(ENABLE_EXTENSIONS)
, m_extensionSystem(nullptr)
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
{
+ profile_metrics::SetBrowserProfileType(this, IsOffTheRecord()
+ ? profile_metrics::BrowserProfileType::kIncognito
+ : profile_metrics::BrowserProfileType::kRegular);
+
setupPrefService();
// Mark the context as live. This prevents the use-after-free DCHECK in
@@ -113,12 +72,20 @@ ProfileQt::~ProfileQt()
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
m_prefServiceAdapter.commit();
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(this);
+ // Remembering push subscriptions and not persisting notification permissions would
+ // confuse most of web applications.
+ PushMessagingAppIdentifier::DeleteAllFromPrefs(this);
ShutdownStoragePartitions();
m_profileIOData->shutdownOnUIThread();
//Should be deleted by IO Thread
m_profileIOData.release();
}
+void ProfileQt::DoFinalInit()
+{
+ PushMessagingServiceImpl::InitializeForProfile(this);
+}
+
PrefService* ProfileQt::GetPrefs()
{
return m_prefServiceAdapter.prefService();
@@ -129,6 +96,11 @@ const PrefService* ProfileQt::GetPrefs() const
return m_prefServiceAdapter.prefService();
}
+bool ProfileQt::IsNewProfile() const
+{
+ return GetPrefs()->GetInitializationStatus() == PrefService::INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
+}
+
base::FilePath ProfileQt::GetPath()
{
return toFilePath(m_profileAdapter->dataPath());
@@ -171,7 +143,10 @@ storage::SpecialStoragePolicy *ProfileQt::GetSpecialStoragePolicy()
content::PushMessagingService *ProfileQt::GetPushMessagingService()
{
- return nullptr;
+ if (m_profileAdapter->pushServiceEnabled())
+ return PushMessagingServiceFactory::GetForProfile(this);
+ else
+ return nullptr;
}
content::SSLHostStateDelegate* ProfileQt::GetSSLHostStateDelegate()
@@ -212,7 +187,7 @@ content::PermissionControllerDelegate *ProfileQt::GetPermissionControllerDelegat
content::ClientHintsControllerDelegate *ProfileQt::GetClientHintsControllerDelegate()
{
- return nullptr;
+ return ClientHintsFactory::GetForBrowserContext(this);
}
content::StorageNotificationService *ProfileQt::GetStorageNotificationService()
@@ -220,33 +195,9 @@ content::StorageNotificationService *ProfileQt::GetStorageNotificationService()
return nullptr;
}
-void ProfileQt::SetCorsOriginAccessListForOrigin(TargetBrowserContexts target_mode,
- const url::Origin &source_origin,
- std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
- std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
- base::OnceClosure closure)
-{
- Q_UNUSED(target_mode); // We have no related OTR profiles
-
- auto barrier_closure = base::BarrierClosure(2, std::move(closure));
-
- // Keep profile storage partitions' NetworkContexts synchronized.
- auto profile_setter = base::MakeRefCounted<content::CorsOriginPatternSetter>(
- source_origin,
- content::CorsOriginPatternSetter::ClonePatterns(allow_patterns),
- content::CorsOriginPatternSetter::ClonePatterns(block_patterns),
- barrier_closure);
- profile_setter->ApplyToEachStoragePartition(this);
-
- m_sharedCorsOriginAccessList->SetForOrigin(source_origin,
- std::move(allow_patterns),
- std::move(block_patterns),
- barrier_closure);
-}
-
-content::SharedCorsOriginAccessList *ProfileQt::GetSharedCorsOriginAccessList()
+content::ReduceAcceptLanguageControllerDelegate *ProfileQt::GetReduceAcceptLanguageControllerDelegate()
{
- return m_sharedCorsOriginAccessList.get();
+ return nullptr;
}
#if QT_CONFIG(webengine_spellchecker)
@@ -270,16 +221,43 @@ std::string ProfileQt::GetMediaDeviceIDSalt()
return m_prefServiceAdapter.mediaDeviceIdSalt();
}
+content::FileSystemAccessPermissionContext *ProfileQt::GetFileSystemAccessPermissionContext()
+{
+ return FileSystemAccessPermissionContextFactoryQt::GetForProfile(this);
+}
+
void ProfileQt::setupPrefService()
{
+ const bool recreation = m_prefServiceAdapter.prefService() != nullptr;
+ profile_metrics::SetBrowserProfileType(this,
+ IsOffTheRecord()
+ ? profile_metrics::BrowserProfileType::kIncognito
+ : profile_metrics::BrowserProfileType::kRegular);
+
// Remove previous handler before we set a new one or we will assert
// TODO: Remove in Qt6
- if (m_prefServiceAdapter.prefService() != nullptr) {
+ if (recreation) {
user_prefs::UserPrefs::Remove(this);
m_prefServiceAdapter.commit();
}
m_prefServiceAdapter.setup(*m_profileAdapter);
user_prefs::UserPrefs::Set(this, m_prefServiceAdapter.prefService());
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (recreation) {
+ // Recreate ExtensionPrefs to update its pointer to the new PrefService
+ extensions::ExtensionsBrowserClient *client = extensions::ExtensionsBrowserClient::Get();
+ std::vector<extensions::EarlyExtensionPrefsObserver *> prefsObservers;
+ client->GetEarlyExtensionPrefsObservers(this, &prefsObservers);
+ auto extensionPrefs = extensions::ExtensionPrefs::Create(
+ this, client->GetPrefServiceForContext(this),
+ this->GetPath().AppendASCII(extensions::kInstallDirectoryName),
+ ExtensionPrefValueMapFactory::GetForBrowserContext(this),
+ client->AreExtensionsDisabled(*base::CommandLine::ForCurrentProcess(), this),
+ prefsObservers);
+ extensions::ExtensionPrefsFactory::GetInstance()->SetInstanceForTesting(this, std::move(extensionPrefs));
+ }
+#endif
}
PrefServiceAdapter &ProfileQt::prefServiceAdapter()
@@ -292,29 +270,16 @@ const PrefServiceAdapter &ProfileQt::prefServiceAdapter() const
return m_prefServiceAdapter;
}
+const blink::UserAgentMetadata &ProfileQt::userAgentMetadata()
+{
+ return m_userAgentMetadata;
+}
-content::PlatformNotificationService *ProfileQt::platformNotificationService()
+content::PlatformNotificationService *ProfileQt::GetPlatformNotificationService()
{
if (!m_platformNotificationService)
m_platformNotificationService = std::make_unique<PlatformNotificationServiceQt>(this);
return m_platformNotificationService.get();
}
-bool ProfileQt::ensureDirectoryExists()
-{
- const base::FilePath &path = GetPath();
-
- if (base::PathExists(path))
- return true;
-
- base::File::Error error;
- if (base::CreateDirectoryAndGetError(path, &error))
- return true;
-
- std::string errorstr = base::File::ErrorToString(error);
- qWarning("Cannot create directory %s. Error: %s.", path.AsUTF8Unsafe().c_str(),
- errorstr.c_str());
- return false;
-}
-
} // namespace QtWebEngineCore
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 8ad1922df..b5cd08db1 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -1,56 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PROFILE_QT_H
#define PROFILE_QT_H
#include "chrome/browser/profiles/profile.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/resource_context.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "pref_service_adapter.h"
-#include "profile_io_data_qt.h"
-#include <QtGlobal>
-class InMemoryPrefStore;
class PrefService;
+namespace content {
+class ResourceContext;
+}
+
namespace extensions {
class ExtensionSystemQt;
}
@@ -58,8 +22,9 @@ class ExtensionSystemQt;
namespace QtWebEngineCore {
class BrowsingDataRemoverDelegateQt;
-class ProfileAdapter;
class PermissionManagerQt;
+class ProfileAdapter;
+class ProfileIODataQt;
class SSLHostStateDelegateQt;
class ProfileQt : public Profile
@@ -89,23 +54,18 @@ public:
content::BrowsingDataRemoverDelegate *GetBrowsingDataRemoverDelegate() override;
content::ClientHintsControllerDelegate *GetClientHintsControllerDelegate() override;
content::StorageNotificationService *GetStorageNotificationService() override;
- void SetCorsOriginAccessListForOrigin(TargetBrowserContexts target_mode,
- const url::Origin &source_origin,
- std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
- std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
- base::OnceClosure closure) override;
-
- content::SharedCorsOriginAccessList *GetSharedCorsOriginAccessList() override;
- std::string GetMediaDeviceIDSalt() override;
+ content::PlatformNotificationService *GetPlatformNotificationService() override;
+ content::FileSystemAccessPermissionContext *GetFileSystemAccessPermissionContext() override;
+ content::ReduceAcceptLanguageControllerDelegate *GetReduceAcceptLanguageControllerDelegate() override;
// Profile implementation:
PrefService *GetPrefs() override;
const PrefService *GetPrefs() const override;
+ bool IsNewProfile() const override;
- void Initialize();
+ void DoFinalInit();
ProfileAdapter *profileAdapter() { return m_profileAdapter; }
-
- content::PlatformNotificationService *platformNotificationService();
+ std::string GetMediaDeviceIDSalt();
#if QT_CONFIG(webengine_spellchecker)
void FailedToLoadDictionary(const std::string &language) override;
@@ -119,19 +79,19 @@ public:
void setupPrefService();
PrefServiceAdapter &prefServiceAdapter();
-
const PrefServiceAdapter &prefServiceAdapter() const;
- bool ensureDirectoryExists();
+
+ const blink::UserAgentMetadata &userAgentMetadata();
private:
std::unique_ptr<BrowsingDataRemoverDelegateQt> m_removerDelegate;
std::unique_ptr<PermissionManagerQt> m_permissionManager;
std::unique_ptr<SSLHostStateDelegateQt> m_sslHostStateDelegate;
- scoped_refptr<content::SharedCorsOriginAccessList> m_sharedCorsOriginAccessList;
std::unique_ptr<ProfileIODataQt> m_profileIOData;
std::unique_ptr<content::PlatformNotificationService> m_platformNotificationService;
ProfileAdapter *m_profileAdapter;
PrefServiceAdapter m_prefServiceAdapter;
+ blink::UserAgentMetadata m_userAgentMetadata;
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionSystemQt *m_extensionSystem;
@@ -139,8 +99,6 @@ private:
friend class ProfileAdapter;
friend class ProfileIODataQt;
-
- DISALLOW_COPY_AND_ASSIGN(ProfileQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/quota_permission_context_qt.cpp b/src/core/quota_permission_context_qt.cpp
deleted file mode 100644
index 549414d33..000000000
--- a/src/core/quota_permission_context_qt.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "quota_permission_context_qt.h"
-
-#include "base/task/post_task.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_frame_host.h"
-#include "quota_request_controller_impl.h"
-#include "qwebenginequotarequest.h"
-#include "web_contents_delegate_qt.h"
-#include "web_contents_view_qt.h"
-
-using content::QuotaPermissionContext;
-using content::RenderFrameHost;
-using content::StorageQuotaParams;
-using content::WebContents;
-
-namespace QtWebEngineCore {
-
-void QuotaPermissionContextQt::RequestQuotaPermission(const StorageQuotaParams &params, int render_process_id, PermissionCallback callback)
-{
- if (params.storage_type != blink::mojom::StorageType::kPersistent) {
- // For now we only support requesting quota with this interface
- // for Persistent storage type.
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_DISALLOW);
- return;
- }
-
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- base::PostTask(
- FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&QuotaPermissionContextQt::RequestQuotaPermission, this,
- params, render_process_id, std::move(callback)));
- return;
- }
-
- RenderFrameHost *renderFrameHost = RenderFrameHost::FromID(render_process_id, params.render_frame_id);
- if (!renderFrameHost) {
- LOG(WARNING) << "Attempt to request quota from frameless renderer: "
- << render_process_id << "," << params.render_frame_id;
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
-
- WebContents *webContents = WebContents::FromRenderFrameHost(renderFrameHost);
- if (!webContents) {
- LOG(ERROR) << "Attempt to request quota from frame missing webcontents";
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
-
- WebContentsAdapterClient *client = WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents)->GetView())->client();
- if (!client) {
- LOG(ERROR) << "Attempt to request quota from content missing webcontents client";
- dispatchCallbackOnIOThread(std::move(callback), QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
-
- QWebEngineQuotaRequest request(
- QSharedPointer<QuotaRequestControllerImpl>::create(this, params, std::move(callback)));
- client->runQuotaRequest(std::move(request));
-}
-
-void QuotaPermissionContextQt::dispatchCallbackOnIOThread(PermissionCallback callback,
- QuotaPermissionContext::QuotaPermissionResponse response)
-{
- if (callback.is_null())
- return;
-
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
- base::PostTask(
- FROM_HERE, {content::BrowserThread::IO},
- base::BindOnce(&QuotaPermissionContextQt::dispatchCallbackOnIOThread,
- this, std::move(callback), response));
- return;
- }
-
- std::move(callback).Run(response);
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/quota_permission_context_qt.h b/src/core/quota_permission_context_qt.h
deleted file mode 100644
index 528928c1a..000000000
--- a/src/core/quota_permission_context_qt.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUOTA_PERMISSION_CONTEXT_QT_H
-#define QUOTA_PERMISSION_CONTEXT_QT_H
-
-#include "content/public/browser/quota_permission_context.h"
-
-namespace QtWebEngineCore {
-
-class QuotaPermissionContextQt : public content::QuotaPermissionContext {
-public:
- void RequestQuotaPermission(const content::StorageQuotaParams &params,
- int render_process_id,
- PermissionCallback callback) override;
-
- void dispatchCallbackOnIOThread(PermissionCallback callback,
- QuotaPermissionContext::QuotaPermissionResponse response);
-};
-
-} // namespace QtWebEngineCore
-
-#endif // QUOTA_PERMISSION_CONTEXT_QT_H
diff --git a/src/core/quota_request_controller.h b/src/core/quota_request_controller.h
deleted file mode 100644
index 0bb0cbff3..000000000
--- a/src/core/quota_request_controller.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUOTA_REQUEST_CONTROLLER_H
-#define QUOTA_REQUEST_CONTROLLER_H
-
-#include "request_controller.h"
-
-namespace QtWebEngineCore {
-
-class QuotaRequestController : public RequestController {
-public:
- QuotaRequestController(QUrl origin, qint64 requestedSize)
- : RequestController(std::move(origin))
- , m_requestedSize(requestedSize)
- {}
-
- qint64 requestedSize() const { return m_requestedSize; }
-
-private:
- qint64 m_requestedSize;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // QUOTA_REQUEST_CONTROLLER_H
diff --git a/src/core/quota_request_controller_impl.cpp b/src/core/quota_request_controller_impl.cpp
deleted file mode 100644
index ea2526d45..000000000
--- a/src/core/quota_request_controller_impl.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "quota_request_controller_impl.h"
-
-#include "type_conversion.h"
-
-namespace QtWebEngineCore {
-
-QuotaRequestControllerImpl::QuotaRequestControllerImpl(QuotaPermissionContextQt *context,
- const content::StorageQuotaParams &params,
- content::QuotaPermissionContext::PermissionCallback callback)
- : QuotaRequestController(
- toQt(params.origin_url),
- params.requested_size)
- , m_context(context)
- , m_callback(std::move(callback))
-{}
-
-QuotaRequestControllerImpl::~QuotaRequestControllerImpl()
-{
- if (m_callback)
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
-}
-
-void QuotaRequestControllerImpl::accepted()
-{
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
-}
-
-void QuotaRequestControllerImpl::rejected()
-{
- m_context->dispatchCallbackOnIOThread(std::move(m_callback), content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/quota_request_controller_impl.h b/src/core/quota_request_controller_impl.h
deleted file mode 100644
index 65e661694..000000000
--- a/src/core/quota_request_controller_impl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUOTA_REQUEST_CONTROLLER_IMPL_H
-#define QUOTA_REQUEST_CONTROLLER_IMPL_H
-
-#include "quota_permission_context_qt.h"
-#include "quota_request_controller.h"
-
-namespace QtWebEngineCore {
-
-class QuotaRequestControllerImpl final : public QuotaRequestController {
-public:
- QuotaRequestControllerImpl(
- QuotaPermissionContextQt *context,
- const content::StorageQuotaParams &params,
- content::QuotaPermissionContext::PermissionCallback callback);
-
- ~QuotaRequestControllerImpl();
-
-protected:
- void accepted() override;
- void rejected() override;
-
-private:
- scoped_refptr<QuotaPermissionContextQt> m_context;
- content::QuotaPermissionContext::PermissionCallback m_callback;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // QUOTA_REQUEST_CONTROLLER_IMPL_H
diff --git a/src/core/register_protocol_handler_request_controller.h b/src/core/register_protocol_handler_request_controller.h
deleted file mode 100644
index 2f9c9fc49..000000000
--- a/src/core/register_protocol_handler_request_controller.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_H
-#define REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_H
-
-#include "request_controller.h"
-
-namespace QtWebEngineCore {
-
-class RegisterProtocolHandlerRequestController : public RequestController {
-public:
- RegisterProtocolHandlerRequestController(QUrl origin, QString scheme)
- : RequestController(std::move(origin))
- , m_scheme(std::move(scheme))
- {}
-
- QString scheme() const { return m_scheme; }
-
-private:
- QString m_scheme;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_H
diff --git a/src/core/register_protocol_handler_request_controller_impl.cpp b/src/core/register_protocol_handler_request_controller_impl.cpp
deleted file mode 100644
index 0f24d8812..000000000
--- a/src/core/register_protocol_handler_request_controller_impl.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "register_protocol_handler_request_controller_impl.h"
-
-#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
-#include "content/public/browser/web_contents.h"
-#include "type_conversion.h"
-
-namespace QtWebEngineCore {
-
-RegisterProtocolHandlerRequestControllerImpl::RegisterProtocolHandlerRequestControllerImpl(
- content::WebContents *webContents,
- ProtocolHandler handler)
- : RegisterProtocolHandlerRequestController(
- toQt(handler.url()),
- toQt(handler.protocol()))
- , content::WebContentsObserver(webContents)
- , m_handler(handler)
-{}
-
-RegisterProtocolHandlerRequestControllerImpl::~RegisterProtocolHandlerRequestControllerImpl()
-{
- reject();
-}
-
-ProtocolHandlerRegistry *RegisterProtocolHandlerRequestControllerImpl::protocolHandlerRegistry()
-{
- content::WebContents *webContents = web_contents();
- if (!webContents)
- return nullptr;
- content::BrowserContext *context = webContents->GetBrowserContext();
- return ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
-}
-
-void RegisterProtocolHandlerRequestControllerImpl::accepted()
-{
- if (ProtocolHandlerRegistry *registry = protocolHandlerRegistry())
- registry->OnAcceptRegisterProtocolHandler(m_handler);
-}
-
-void RegisterProtocolHandlerRequestControllerImpl::rejected()
-{
- if (ProtocolHandlerRegistry *registry = protocolHandlerRegistry())
- registry->OnIgnoreRegisterProtocolHandler(m_handler);
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/register_protocol_handler_request_controller_impl.h b/src/core/register_protocol_handler_request_controller_impl.h
deleted file mode 100644
index 64f229ac4..000000000
--- a/src/core/register_protocol_handler_request_controller_impl.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_IMPL_H
-#define REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_IMPL_H
-
-#include "register_protocol_handler_request_controller.h"
-
-#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
-#include "chrome/common/custom_handlers/protocol_handler.h"
-#include "content/public/browser/web_contents_observer.h"
-
-class ProtocolHandlerRegistry;
-
-namespace QtWebEngineCore {
-
-class RegisterProtocolHandlerRequestControllerImpl final : public RegisterProtocolHandlerRequestController,
- private content::WebContentsObserver {
-public:
- RegisterProtocolHandlerRequestControllerImpl(
- content::WebContents *webContents,
- ProtocolHandler handler);
-
- ~RegisterProtocolHandlerRequestControllerImpl();
-
-protected:
- void accepted() override;
- void rejected() override;
-
-private:
- ProtocolHandlerRegistry *protocolHandlerRegistry();
- ProtocolHandler m_handler;
-};
-
-} // namespace QtWebEngineCore
-
-#endif // REGISTER_PROTOCOL_HANDLER_REQUEST_CONTROLLER_IMPL_H
diff --git a/src/core/render_view_context_menu_qt.cpp b/src/core/render_view_context_menu_qt.cpp
index 47c8a6e32..b7aabfd5b 100644
--- a/src/core/render_view_context_menu_qt.cpp
+++ b/src/core/render_view_context_menu_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include "render_view_context_menu_qt.h"
diff --git a/src/core/render_view_context_menu_qt.h b/src/core/render_view_context_menu_qt.h
index f818ce200..71901424c 100644
--- a/src/core/render_view_context_menu_qt.h
+++ b/src/core/render_view_context_menu_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -57,7 +21,7 @@ QT_FORWARD_DECLARE_CLASS(QWebEngineContextMenuRequest)
namespace QtWebEngineCore {
-class Q_WEBENGINECORE_PRIVATE_EXPORT RenderViewContextMenuQt
+class Q_WEBENGINECORE_EXPORT RenderViewContextMenuQt
{
public:
enum ContextMenuItem {
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 9d5744cbf..888043fda 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -1,46 +1,8 @@
-
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "render_widget_host_view_qt.h"
-#include "browser_accessibility_manager_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt_delegate.h"
#include "render_widget_host_view_qt_delegate_client.h"
@@ -50,13 +12,12 @@
#include "web_contents_adapter_client.h"
#include "web_event_factory.h"
-#include "base/threading/thread_task_runner_handle.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/image_transport_factory.h"
-#include "content/browser/renderer_host/display_util.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/cursor_manager.h"
@@ -68,9 +29,11 @@
#include "content/browser/renderer_host/ui_events_helper.h"
#include "content/common/content_switches_internal.h"
#include "content/common/cursors/webcursor.h"
+#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/display/display_util.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/event.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
@@ -83,12 +46,12 @@
#endif
#if defined(USE_AURA)
+#include "ui/wm/core/cursor_util.h"
#include "ui/base/cursor/cursor_size.h"
-#include "ui/base/cursor/cursors_aura.h"
#endif
#if defined(Q_OS_MACOS)
-#include "content/app/resources/grit/content_resources.h"
+#include "ui/resources/grit/ui_resources.h"
#endif
#include <QGuiApplication>
@@ -129,16 +92,27 @@ static inline ui::GestureProvider::Config QtGestureProviderConfig() {
extern display::Display toDisplayDisplay(int id, const QScreen *screen);
-static blink::ScreenInfo screenInfoFromQScreen(QScreen *screen)
+static display::ScreenInfos screenInfosFromQtForUpdate(QScreen *currentScreen)
{
- blink::ScreenInfo r;
- if (!screen)
- screen = qApp->primaryScreen();
- if (screen)
- content::DisplayUtil::DisplayToScreenInfo(&r, toDisplayDisplay(0, screen));
- else
- r.device_scale_factor = qGuiApp->devicePixelRatio();
- return r;
+ display::ScreenInfo screenInfo;
+ const auto &screens = qApp->screens();
+ if (screens.isEmpty()) {
+ screenInfo.device_scale_factor = qGuiApp->devicePixelRatio();
+ return display::ScreenInfos(screenInfo);
+ }
+
+ Q_ASSERT(qApp->primaryScreen() == screens.first());
+ display::ScreenInfos result;
+ for (int i = 0; i < screens.length(); ++i) {
+ display::DisplayUtil::DisplayToScreenInfo(&screenInfo, toDisplayDisplay(i, screens.at(i)));
+ result.screen_infos.push_back(screenInfo);
+ if (currentScreen == screens.at(i))
+ result.current_display_id = i;
+ }
+
+ Q_ASSERT(result.current_display_id != display::kInvalidDisplayId);
+
+ return result;
}
// An minimal override to support progressing flings
@@ -168,33 +142,10 @@ public:
}
};
-class GuestInputEventObserverQt : public content::RenderWidgetHost::InputEventObserver
-{
-public:
- GuestInputEventObserverQt(RenderWidgetHostViewQt *rwhv)
- : m_rwhv(rwhv)
- {
- }
- ~GuestInputEventObserverQt() {}
-
- void OnInputEvent(const blink::WebInputEvent&) override {}
- void OnInputEventAck(blink::mojom::InputEventResultSource,
- blink::mojom::InputEventResultState state,
- const blink::WebInputEvent &event) override
- {
- if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel)
- m_rwhv->WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state);
- }
-
-private:
- RenderWidgetHostViewQt *m_rwhv;
-};
-
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
: content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget)
- , m_taskRunner(base::ThreadTaskRunnerHandle::Get())
+ , m_taskRunner(base::SingleThreadTaskRunner::GetCurrentDefault())
, m_gestureProvider(QtGestureProviderConfig(), this)
- , m_guestInputEventObserver(new GuestInputEventObserverQt(this))
, m_frameSinkId(host()->GetFrameSinkId())
, m_delegateClient(new RenderWidgetHostViewQtDelegateClient(this))
{
@@ -226,11 +177,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
m_cursorManager.reset(new content::CursorManager(this));
m_touchSelectionControllerClient.reset(new TouchSelectionControllerClientQt(this));
- ui::TouchSelectionController::Config config;
- config.max_tap_duration = base::TimeDelta::FromMilliseconds(ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
- config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click();
- config.enable_longpress_drag_selection = false;
- m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config));
+ resetTouchSelectionController();
host()->render_frame_metadata_provider()->AddObserver(this);
host()->render_frame_metadata_provider()->ReportAllFrameSubmissionsForTesting(true);
@@ -247,6 +194,9 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
+ if (host()->delegate())
+ m_touchSelectionControllerClient->resetControls();
+
m_touchSelectionController.reset();
m_touchSelectionControllerClient.reset();
@@ -275,17 +225,43 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC
m_adapterClient = nullptr; });
}
-void RenderWidgetHostViewQt::setGuest(content::RenderWidgetHostImpl *rwh)
+void RenderWidgetHostViewQt::OnInputEventAck(blink::mojom::InputEventResultSource,
+ blink::mojom::InputEventResultState state,
+ const blink::WebInputEvent &event)
{
- rwh->AddInputEventObserver(m_guestInputEventObserver.get());
+ if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel)
+ WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state);
+}
+
+// static
+// Called when new child/guest renderframes created.
+void RenderWidgetHostViewQt::registerInputEventObserver(content::WebContents *webContents,
+ content::RenderFrameHost *rfh)
+{
+ if (static_cast<content::RenderFrameHostImpl *>(rfh)->is_local_root_subframe()) {
+ content::WebContents *parent = webContents->GetOutermostWebContents();
+ QtWebEngineCore::RenderWidgetHostViewQt *mainRwhv =
+ static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(
+ parent->GetRenderWidgetHostView());
+ // Child (originAgentCluster) or guest (pdf) frame that is embedded into the main frame
+ content::RenderWidgetHost *childFrame = rfh->GetRenderWidgetHost();
+ childFrame->AddInputEventObserver(mainRwhv);
+
+ if (webContents->IsInnerWebContentsForGuest()) {
+ // The frame which holds the actual PDF content inside the guest
+ content::RenderWidgetHost *guestFrame = webContents->GetRenderViewHost()->GetWidget();
+ guestFrame->AddInputEventObserver(mainRwhv);
+ }
+ }
}
void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView)
{
}
-void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect& rect)
+void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect& rect, const gfx::Rect& anchorRect)
{
+ Q_UNUSED(anchorRect);
m_delegate->initAsPopup(toQt(rect));
}
@@ -315,11 +291,6 @@ gfx::NativeView RenderWidgetHostViewQt::GetNativeView()
return gfx::NativeView();
}
-gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible()
-{
- return 0;
-}
-
content::WebContentsAccessibility *RenderWidgetHostViewQt::GetWebContentsAccessibility()
{
if (!m_webContentsAccessibility)
@@ -367,8 +338,9 @@ void RenderWidgetHostViewQt::CopyFromSurface(const gfx::Rect &src_rect,
m_delegatedFrameHost->CopyFromCompositingSurface(src_rect, output_size, std::move(callback));
}
-void RenderWidgetHostViewQt::Show()
+void RenderWidgetHostViewQt::ShowWithVisibility(content::PageVisibilityState page_visibility)
{
+ Q_ASSERT(page_visibility != content::PageVisibilityState::kHidden);
if (m_delegate)
m_delegate->show();
else
@@ -395,6 +367,9 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds()
void RenderWidgetHostViewQt::UpdateBackgroundColor()
{
+ if (!m_delegate)
+ return;
+
DCHECK(GetBackgroundColor());
SkColor color = *GetBackgroundColor();
@@ -441,13 +416,13 @@ bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type
{
int resourceId;
// GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels.
- qreal hotspotDpr = m_screenInfo.device_scale_factor <= 1.0f ? 1.0f : 2.0f;
+ qreal hotspotDpr = GetScreenInfo().device_scale_factor <= 1.0f ? 1.0f : 2.0f;
qreal hotX;
qreal hotY;
#if defined(USE_AURA)
gfx::Point hotspot;
- if (!ui::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot))
+ if (!wm::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot))
return false;
hotX = hotspot.x();
hotY = hotspot.y();
@@ -488,7 +463,7 @@ bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type
if (!imageSkia)
return false;
- QImage imageQt = toQImage(imageSkia->GetRepresentation(m_screenInfo.device_scale_factor));
+ QImage imageQt = toQImage(imageSkia->GetRepresentation(GetScreenInfo().device_scale_factor));
// Convert hotspot coordinates into device-independent pixels.
hotX /= hotspotDpr;
@@ -505,14 +480,13 @@ bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type
return true;
}
-void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
+void RenderWidgetHostViewQt::UpdateCursor(const ui::Cursor &webCursor)
{
DisplayCursor(webCursor);
}
-void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
+void RenderWidgetHostViewQt::DisplayCursor(const ui::Cursor &cursorInfo)
{
- const ui::Cursor &cursorInfo = webCursor.cursor();
Qt::CursorShape shape = Qt::ArrowCursor;
switch (cursorInfo.type()) {
case ui::mojom::CursorType::kNull:
@@ -597,6 +571,11 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
if (updateCursorFromResource(cursorInfo.type()))
return;
break;
+ case ui::mojom::CursorType::kEastWestNoResize:
+ case ui::mojom::CursorType::kNorthEastSouthWestNoResize:
+ case ui::mojom::CursorType::kNorthSouthNoResize:
+ case ui::mojom::CursorType::kNorthWestSouthEastNoResize:
+ // Use forbidden cursor matching webcursor_mac.mm and win_cursor_factory.cc
case ui::mojom::CursorType::kNoDrop:
case ui::mojom::CursorType::kNotAllowed:
shape = Qt::ForbiddenCursor;
@@ -636,7 +615,9 @@ void RenderWidgetHostViewQt::ImeCancelComposition()
qApp->inputMethod()->reset();
}
-void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range&, const std::vector<gfx::Rect>&)
+void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range &,
+ const absl::optional<std::vector<gfx::Rect>> &,
+ const absl::optional<std::vector<gfx::Rect>> &)
{
// FIXME: not implemented?
QT_NOT_YET_IMPLEMENTED
@@ -664,22 +645,17 @@ void RenderWidgetHostViewQt::Destroy()
delete this;
}
-void RenderWidgetHostViewQt::SetTooltipText(const base::string16 &tooltip_text)
+void RenderWidgetHostViewQt::UpdateTooltipUnderCursor(const std::u16string &tooltip_text)
{
- DisplayTooltipText(tooltip_text);
+ UpdateTooltip(tooltip_text);
}
-void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_text)
+void RenderWidgetHostViewQt::UpdateTooltip(const std::u16string &tooltip_text)
{
if (host()->delegate() && m_adapterClient)
m_adapterClient->setToolTip(toQt(tooltip_text));
}
-void RenderWidgetHostViewQt::GetScreenInfo(blink::ScreenInfo *results)
-{
- *results = m_screenInfo;
-}
-
gfx::Rect RenderWidgetHostViewQt::GetBoundsInRootWindow()
{
return toGfx(delegateClient()->windowRectInDips());
@@ -709,9 +685,11 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
// In case of text selection, the update is expected in RenderWidgetHostViewQt::selectionChanged().
if (GetSelectedText().empty()) {
- // At this point it is unknown whether the text input state has been updated due to a text selection.
- // Keep the cursor position updated for cursor movements too.
- delegateClient()->setCursorPosition(state->selection.start());
+ if (state->composition.has_value()) {
+ delegateClient()->setCursorPosition(state->composition->start());
+ } else {
+ delegateClient()->setCursorPosition(state->selection.start());
+ }
m_delegate->inputMethodStateChanged(type != ui::TEXT_INPUT_TYPE_NONE, type == ui::TEXT_INPUT_TYPE_PASSWORD);
}
@@ -748,15 +726,22 @@ void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *t
Q_UNUSED(text_input_manager);
Q_UNUSED(updated_view);
- const content::TextInputManager::TextSelection *selection = GetTextInputManager()->GetTextSelection(updated_view);
- if (!selection)
- return;
+ // We obtain the TextSelection from focused RWH which is obtained from the
+ // frame tree.
+ content::RenderWidgetHostViewBase *focused_view =
+ GetFocusedWidget() ? GetFocusedWidget()->GetView() : nullptr;
+
+ if (!focused_view)
+ return;
#if defined(USE_OZONE)
- if (!selection->selected_text().empty() && selection->user_initiated()) {
- // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard.
- ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kSelection);
- clipboard_writer.WriteText(selection->selected_text());
+ if (ui::Clipboard::IsSupportedClipboardBuffer(ui::ClipboardBuffer::kSelection)) {
+ const content::TextInputManager::TextSelection *selection = GetTextInputManager()->GetTextSelection(focused_view);
+ if (selection->selected_text().length() && selection->user_initiated()) {
+ // Set the ClipboardBuffer::kSelection to the ui::Clipboard.
+ ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kSelection);
+ clipboard_writer.WriteText(selection->selected_text());
+ }
}
#endif // defined(USE_OZONE)
@@ -851,11 +836,11 @@ void RenderWidgetHostViewQt::notifyHidden()
m_delegatedFrameHost->DetachFromCompositor();
}
-void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, blink::mojom::InputEventResultState ack_result) {
- Q_UNUSED(touch);
- const bool eventConsumed = ack_result == blink::mojom::InputEventResultState::kConsumed;
- const bool isSetNonBlocking = content::InputEventResultStateIsSetNonBlocking(ack_result);
- m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, isSetNonBlocking);
+void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, blink::mojom::InputEventResultState ack_result)
+{
+ const bool eventConsumed = (ack_result == blink::mojom::InputEventResultState::kConsumed);
+ const bool isSetBlocking = content::InputEventResultStateIsSetBlocking(ack_result);
+ m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, isSetBlocking);
}
void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent)
@@ -877,11 +862,17 @@ bool RenderWidgetHostViewQt::isPopup() const
bool RenderWidgetHostViewQt::updateScreenInfo()
{
- blink::ScreenInfo oldScreenInfo = m_screenInfo;
- QScreen *screen = m_delegate->window() ? m_delegate->window()->screen() : nullptr;
- m_screenInfo = screenInfoFromQScreen(screen);
- return (m_screenInfo != oldScreenInfo);
+ QWindow *window = m_delegate->Window();
+ if (!window)
+ return false;
+
+ display::ScreenInfos newScreenInfos = screenInfosFromQtForUpdate(window->screen());
+ if (screen_infos_ == newScreenInfos)
+ return false;
+
+ screen_infos_ = std::move(newScreenInfos);
+ return true;
}
void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *event)
@@ -918,7 +909,9 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
}
}
-void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event, blink::mojom::InputEventResultState ack_result)
+void RenderWidgetHostViewQt::GestureEventAck(const blink::WebGestureEvent &event,
+ blink::mojom::InputEventResultState ack_result,
+ blink::mojom::ScrollResultDataPtr scroll_result_data)
{
// Forward unhandled scroll events back as wheel events
if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollUpdate)
@@ -988,11 +981,9 @@ void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostVi
{
DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)->IsRenderWidgetHostViewChildFrame());
RenderWidgetHostViewQt *viewQt = static_cast<RenderWidgetHostViewQt *>(view);
- base::Optional<SkColor> color = viewQt->GetBackgroundColor();
- if (color)
- SetBackgroundColor(*color);
+ CopyBackgroundColorIfPresentFrom(*viewQt);
+
m_delegatedFrameHost->TakeFallbackContentFrom(viewQt->m_delegatedFrameHost.get());
- host()->GetContentRenderingTimeoutFrom(viewQt->host());
}
void RenderWidgetHostViewQt::EnsureSurfaceSynchronizedForWebTest()
@@ -1019,17 +1010,22 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation(base::T
m_touchSelectionControllerClient->UpdateClientSelectionBounds(m_selectionStart, m_selectionEnd);
}
- gfx::Vector2dF scrollOffset = metadata.root_scroll_offset.value_or(gfx::Vector2dF());
- gfx::SizeF contentsSize = metadata.root_layer_size;
+ gfx::PointF scrollOffset = gfx::PointF();
+ if (metadata.root_scroll_offset.has_value())
+ scrollOffset = gfx::ScalePoint(metadata.root_scroll_offset.value(),
+ 1 / metadata.device_scale_factor);
std::swap(m_lastScrollOffset, scrollOffset);
- std::swap(m_lastContentsSize, contentsSize);
if (m_adapterClient && scrollOffset != m_lastScrollOffset)
m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset));
+
+ gfx::SizeF contentsSize =
+ gfx::ScaleSize(metadata.root_layer_size, 1 / metadata.device_scale_factor);
+ std::swap(m_lastContentsSize, contentsSize);
if (m_adapterClient && contentsSize != m_lastContentsSize)
m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
}
-void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceId> &childSurfaceId)
+void RenderWidgetHostViewQt::synchronizeVisualProperties(const absl::optional<viz::LocalSurfaceId> &childSurfaceId)
{
if (childSurfaceId)
m_dfhLocalSurfaceIdAllocator.UpdateFromChild(*childSurfaceId);
@@ -1041,7 +1037,7 @@ void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<vi
m_rootLayer->SetBounds(gfx::Rect(gfx::Point(), viewSizeInPixels));
m_uiCompositorLocalSurfaceIdAllocator.GenerateId();
m_uiCompositor->SetScaleAndSize(
- m_screenInfo.device_scale_factor,
+ GetScreenInfo().device_scale_factor,
viewSizeInPixels,
m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId());
m_delegatedFrameHost->EmbedSurface(
@@ -1052,6 +1048,17 @@ void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<vi
host()->SynchronizeVisualProperties();
}
+void RenderWidgetHostViewQt::resetTouchSelectionController()
+{
+ Q_ASSERT(m_touchSelectionControllerClient);
+ m_touchSelectionControllerClient->resetControls();
+ ui::TouchSelectionController::Config config;
+ config.max_tap_duration = base::Milliseconds(ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
+ config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click();
+ config.enable_longpress_drag_selection = false;
+ m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config));
+}
+
std::unique_ptr<content::SyntheticGestureTarget> RenderWidgetHostViewQt::CreateSyntheticGestureTarget()
{
return nullptr;
@@ -1062,9 +1069,9 @@ ui::Compositor *RenderWidgetHostViewQt::GetCompositor()
return m_uiCompositor.get();
}
-base::Optional<content::DisplayFeature> RenderWidgetHostViewQt::GetDisplayFeature()
+absl::optional<content::DisplayFeature> RenderWidgetHostViewQt::GetDisplayFeature()
{
- return base::nullopt;
+ return absl::nullopt;
}
void RenderWidgetHostViewQt::SetDisplayFeatureForTesting(const content::DisplayFeature *)
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 15ef4fa2a..a55e04dd8 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef RENDER_WIDGET_HOST_VIEW_QT_H
#define RENDER_WIDGET_HOST_VIEW_QT_H
@@ -48,18 +12,16 @@
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/host/host_frame_sink_client.h"
-#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/web_contents_accessibility.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
-QT_FORWARD_DECLARE_CLASS(QAccessibleInterface)
-
namespace content {
class RenderFrameHost;
class RenderWidgetHostImpl;
+class WebContents;
}
namespace ui {
@@ -69,7 +31,7 @@ class TouchSelectionController;
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateClient;
-class GuestInputEventObserverQt;
+class InputEventObserverQt;
class TouchSelectionControllerClientQt;
class WebContentsAccessibilityQt;
class WebContentsAdapterClient;
@@ -80,6 +42,7 @@ class RenderWidgetHostViewQt
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
, public content::TextInputManager::Observer
, public content::RenderFrameMetadataProvider::Observer
+ , public content::RenderWidgetHost::InputEventObserver
{
public:
RenderWidgetHostViewQt(content::RenderWidgetHost* widget);
@@ -90,14 +53,14 @@ public:
WebContentsAdapterClient *adapterClient() { return m_adapterClient; }
void setAdapterClient(WebContentsAdapterClient *adapterClient);
RenderWidgetHostViewQtDelegateClient *delegateClient() const { return m_delegateClient.get(); }
- void setGuest(content::RenderWidgetHostImpl *);
+ // Overridden from RenderWidgetHostView:
void InitAsChild(gfx::NativeView) override;
- void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&) override;
+ void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&, const gfx::Rect&) override;
void SetSize(const gfx::Size& size) override;
void SetBounds(const gfx::Rect&) override;
gfx::NativeView GetNativeView() override;
- gfx::NativeViewAccessible GetNativeViewAccessible() override;
+ gfx::NativeViewAccessible GetNativeViewAccessible() override { return nullptr; }
void Focus() override;
bool HasFocus() override;
bool IsMouseLocked() override;
@@ -106,7 +69,7 @@ public:
void CopyFromSurface(const gfx::Rect &src_rect,
const gfx::Size &output_size,
base::OnceCallback<void(const SkBitmap &)> callback) override;
- void Show() override;
+ void ShowWithVisibility(content::PageVisibilityState page_visibility) override;
void Hide() override;
bool IsShowing() override;
gfx::Rect GetViewBounds() override;
@@ -114,29 +77,31 @@ public:
blink::mojom::PointerLockResult LockMouse(bool) override;
blink::mojom::PointerLockResult ChangeMouseLock(bool) override;
void UnlockMouse() override;
- void UpdateCursor(const content::WebCursor&) override;
- void DisplayCursor(const content::WebCursor&) override;
+ void UpdateCursor(const ui::Cursor&) override;
+ void DisplayCursor(const ui::Cursor&) override;
content::CursorManager *GetCursorManager() override;
void SetIsLoading(bool) override;
void ImeCancelComposition() override;
- void ImeCompositionRangeChanged(const gfx::Range&, const std::vector<gfx::Rect>&) override;
+ void ImeCompositionRangeChanged(const gfx::Range &,
+ const absl::optional<std::vector<gfx::Rect>> &,
+ const absl::optional<std::vector<gfx::Rect>> &) override;
void RenderProcessGone() override;
bool TransformPointToCoordSpaceForView(const gfx::PointF &point,
content::RenderWidgetHostViewBase *target_view,
gfx::PointF *transformed_point) override;
void Destroy() override;
- void SetTooltipText(const base::string16 &tooltip_text) override;
- void DisplayTooltipText(const base::string16& tooltip_text) override;
+ void UpdateTooltipUnderCursor(const std::u16string &tooltip_text) override;
+ void UpdateTooltip(const std::u16string& tooltip_text) override;
void WheelEventAck(const blink::WebMouseWheelEvent &event,
blink::mojom::InputEventResultState ack_result) override;
void GestureEventAck(const blink::WebGestureEvent &event,
- blink::mojom::InputEventResultState ack_result) override;
+ blink::mojom::InputEventResultState ack_result,
+ blink::mojom::ScrollResultDataPtr scroll_result_data) override;
content::MouseWheelPhaseHandler *GetMouseWheelPhaseHandler() override;
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata) override;
void OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata);
// Overridden from RenderWidgetHostViewBase:
- void GetScreenInfo(blink::ScreenInfo *results) override;
gfx::Rect GetBoundsInRootWindow() override;
void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch,
blink::mojom::InputEventResultState ack_result) override;
@@ -153,14 +118,25 @@ public:
void DidStopFlinging() override;
std::unique_ptr<content::SyntheticGestureTarget> CreateSyntheticGestureTarget() override;
ui::Compositor *GetCompositor() override;
- base::Optional<content::DisplayFeature> GetDisplayFeature() override;
+ absl::optional<content::DisplayFeature> GetDisplayFeature() override;
void SetDisplayFeatureForTesting(const content::DisplayFeature*) override;
-#if defined(OS_MAC)
+ content::WebContentsAccessibility *GetWebContentsAccessibility() override;
+#if BUILDFLAG(IS_MAC)
+ void ShowSharePicker(
+ const std::string &title,
+ const std::string &text,
+ const std::string &url,
+ const std::vector<std::string> &file_paths,
+ blink::mojom::ShareService::ShareCallback callback) override { QT_NOT_YET_IMPLEMENTED }
void SetActive(bool active) override { QT_NOT_YET_IMPLEMENTED }
void SpeakSelection() override { QT_NOT_YET_IMPLEMENTED }
void ShowDefinitionForSelection() override { QT_NOT_YET_IMPLEMENTED }
void SetWindowFrameInScreen(const gfx::Rect&) override { QT_NOT_YET_IMPLEMENTED }
-#endif // defined(OS_MAC)
+#endif // BUILDFLAG(IS_MAC)
+ void NotifyHostAndDelegateOnWasShown(blink::mojom::RecordContentToVisibleTimeRequestPtr) override { QT_NOT_YET_IMPLEMENTED }
+ void RequestSuccessfulPresentationTimeFromHostOrDelegate(blink::mojom::RecordContentToVisibleTimeRequestPtr) override {}
+ void CancelSuccessfulPresentationTimeRequestForHostAndDelegate() override {}
+ void InvalidateLocalSurfaceIdAndAllocationGroup() override {}
// Overridden from ui::GestureProviderClient.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
@@ -170,15 +146,20 @@ public:
void OnSelectionBoundsChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
void OnTextSelectionChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
- // Overridden from content::BrowserAccessibilityDelegate
- content::WebContentsAccessibility *GetWebContentsAccessibility() override;
-
// Overridden from content::RenderFrameMetadataProvider::Observer
void OnRenderFrameMetadataChangedAfterActivation(base::TimeTicks activation_time) override;
void OnRenderFrameMetadataChangedBeforeActivation(const cc::RenderFrameMetadata &) override {}
void OnRenderFrameSubmission() override {}
void OnLocalSurfaceIdChanged(const cc::RenderFrameMetadata &) override {}
+ // Overridden from content::RenderWidgetHost::InputEventObserver
+ void OnInputEvent(const blink::WebInputEvent &) override { }
+ void OnInputEventAck(blink::mojom::InputEventResultSource,
+ blink::mojom::InputEventResultState state,
+ const blink::WebInputEvent &event) override;
+
+ static void registerInputEventObserver(content::WebContents *, content::RenderFrameHost *);
+
// Called from RenderWidgetHostViewQtDelegateClient.
Compositor::Id compositorId();
void notifyShown();
@@ -190,7 +171,7 @@ public:
// Called from WebContentsAdapter.
gfx::SizeF lastContentsSize() const { return m_lastContentsSize; }
- gfx::Vector2dF lastScrollOffset() const { return m_lastScrollOffset; }
+ gfx::PointF lastScrollOffset() const { return m_lastScrollOffset; }
ui::TouchSelectionController *getTouchSelectionController() const { return m_touchSelectionController.get(); }
TouchSelectionControllerClientQt *getTouchSelectionControllerClient() const { return m_touchSelectionControllerClient.get(); }
@@ -198,7 +179,9 @@ public:
ui::TextInputType getTextInputType() const;
void synchronizeVisualProperties(
- const base::Optional<viz::LocalSurfaceId> &childSurfaceId);
+ const absl::optional<viz::LocalSurfaceId> &childSurfaceId);
+
+ void resetTouchSelectionController();
private:
friend class DelegatedFrameHostClientQt;
@@ -213,7 +196,6 @@ private:
std::unique_ptr<content::CursorManager> m_cursorManager;
ui::FilteredGestureProvider m_gestureProvider;
- std::unique_ptr<GuestInputEventObserverQt> m_guestInputEventObserver;
viz::FrameSinkId m_frameSinkId;
std::unique_ptr<RenderWidgetHostViewQtDelegateClient> m_delegateClient;
@@ -225,12 +207,11 @@ private:
bool m_isMouseLocked = false;
bool m_visible = false;
bool m_deferredShow = false;
- gfx::Vector2dF m_lastScrollOffset;
+ gfx::PointF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
DelegatedFrameHostClientQt m_delegatedFrameHostClient { this };
// VIZ
- blink::ScreenInfo m_screenInfo;
std::unique_ptr<content::DelegatedFrameHost> m_delegatedFrameHost;
std::unique_ptr<ui::Layer> m_rootLayer;
std::unique_ptr<ui::Compositor> m_uiCompositor;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 1df1322c7..b1f33db7a 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -65,7 +29,7 @@ QT_END_NAMESPACE
namespace QtWebEngineCore {
class WebContentsAdapterClient;
-class Q_WEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegate {
+class Q_WEBENGINECORE_EXPORT RenderWidgetHostViewQtDelegate {
public:
virtual ~RenderWidgetHostViewQtDelegate() { }
virtual void initAsPopup(const QRect&) = 0;
@@ -78,7 +42,7 @@ public:
virtual void show() = 0;
virtual void hide() = 0;
virtual bool isVisible() const = 0;
- virtual QWindow* window() const = 0;
+ virtual QWindow *Window() const = 0;
virtual void updateCursor(const QCursor &) = 0;
virtual void resize(int width, int height) = 0;
virtual void move(const QPoint &) = 0;
@@ -86,6 +50,7 @@ public:
virtual void setInputMethodHints(Qt::InputMethodHints hints) = 0;
virtual void setClearColor(const QColor &color) = 0;
virtual void adapterClientChanged(WebContentsAdapterClient *client) = 0;
+ virtual void updateAdapterClientIfNeeded(WebContentsAdapterClient *client) = 0;
virtual void unhandledWheelEvent(QWheelEvent *) {}
};
diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index d28e789ee..3e8cad669 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "render_widget_host_view_qt_delegate_client.h"
@@ -52,8 +16,7 @@
#include <QEvent>
#include <QInputMethodEvent>
-#include <QScopeGuard>
-#include <QSGNode>
+#include <QSet>
#include <QStyleHints>
#include <QTextFormat>
#include <QVariant>
@@ -92,7 +55,7 @@ QList<TouchPoint> RenderWidgetHostViewQtDelegateClient::mapTouchPointIds(const Q
Q_ASSERT(output.size() == std::accumulate(output.cbegin(), output.cend(), QSet<int>(),
[] (QSet<int> s, const TouchPoint &p) { s.insert(p.second.id()); return s; }).size());
- for (auto &&point : qAsConst(input))
+ for (auto &&point : std::as_const(input))
if (point.state() == QEventPoint::Released)
m_touchIdMapping.remove(point.id());
@@ -235,7 +198,7 @@ void RenderWidgetHostViewQtDelegateClient::visualPropertiesChanged()
m_rwhv->host()->SendScreenRects();
if (m_viewRectInDips.size() != oldViewRect.size() || screenInfoChanged)
- m_rwhv->synchronizeVisualProperties(base::nullopt);
+ m_rwhv->synchronizeVisualProperties(absl::nullopt);
}
bool RenderWidgetHostViewQtDelegateClient::forwardEvent(QEvent *event)
@@ -245,7 +208,7 @@ bool RenderWidgetHostViewQtDelegateClient::forwardEvent(QEvent *event)
switch (event->type()) {
case QEvent::ShortcutOverride: {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
-
+ event->ignore();
auto acceptKeyOutOfInputField = [](QKeyEvent *keyEvent) -> bool {
#ifdef Q_OS_MACOS
// Check if a shortcut is registered for this key sequence.
@@ -329,9 +292,13 @@ bool RenderWidgetHostViewQtDelegateClient::forwardEvent(QEvent *event)
handleHoverEvent(static_cast<QHoverEvent *>(event));
break;
case QEvent::FocusIn:
- case QEvent::FocusOut:
- handleFocusEvent(static_cast<QFocusEvent *>(event));
- break;
+ case QEvent::FocusOut: {
+ // Focus in/out events for popup event do not mean 'parent' focus change
+ // and should not be handled by Chromium
+ QFocusEvent *e = static_cast<QFocusEvent *>(event);
+ if (e->reason() != Qt::PopupFocusReason)
+ handleFocusEvent(e);
+ } break;
case QEvent::InputMethod:
handleInputMethodEvent(static_cast<QInputMethodEvent *>(event));
break;
@@ -377,6 +344,7 @@ QVariant RenderWidgetHostViewQtDelegateClient::inputMethodQuery(Qt::InputMethodQ
}
return QVariant();
}
+ case Qt::ImAbsolutePosition:
case Qt::ImCursorPosition:
return m_cursorPosition;
case Qt::ImAnchorPosition:
@@ -441,6 +409,7 @@ void RenderWidgetHostViewQtDelegateClient::handlePointerEvent(T *event)
webEvent.movement_x = event->globalPosition().x() - m_previousMousePosition.x();
webEvent.movement_y = event->globalPosition().y() - m_previousMousePosition.y();
+ webEvent.is_raw_movement_event = true;
if (m_rwhv->IsMouseLocked())
QCursor::setPos(m_previousMousePosition);
@@ -471,12 +440,6 @@ void RenderWidgetHostViewQtDelegateClient::handleMouseEvent(QMouseEvent *event)
if (event->type() == QEvent::MouseButtonRelease)
m_mouseButtonPressed--;
- // Don't forward mouse events synthesized by the system, which are caused by genuine touch
- // events. Chromium would then process for e.g. a mouse click handler twice, once due to the
- // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse
- // transformation done by Chromium.
- if (event->source() == Qt::MouseEventSynthesizedBySystem)
- return;
handlePointerEvent<QMouseEvent>(event);
}
@@ -513,6 +476,9 @@ void RenderWidgetHostViewQtDelegateClient::handleKeyEvent(QKeyEvent *event)
if (event->type() == QEvent::KeyRelease && event->isAutoRepeat())
return;
+ if (!m_rwhv->GetFocusedWidget())
+ return;
+
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(event);
if (webEvent.GetType() == blink::WebInputEvent::Type::kRawKeyDown && !m_editCommand.empty()) {
ui::LatencyInfo latency;
@@ -526,14 +492,14 @@ void RenderWidgetHostViewQtDelegateClient::handleKeyEvent(QKeyEvent *event)
bool keyDownTextInsertion =
webEvent.GetType() == blink::WebInputEvent::Type::kRawKeyDown && webEvent.text[0];
- webEvent.skip_in_browser = keyDownTextInsertion;
+ webEvent.skip_if_unhandled = keyDownTextInsertion;
m_rwhv->GetFocusedWidget()->ForwardKeyboardEvent(webEvent);
if (keyDownTextInsertion) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
// The RawKeyDown is skipped on the way back (see above).
// The same os_event will be set on both NativeWebKeyboardEvents.
- webEvent.skip_in_browser = false;
+ webEvent.skip_if_unhandled = false;
webEvent.SetType(blink::WebInputEvent::Type::kChar);
m_rwhv->GetFocusedWidget()->ForwardKeyboardEvent(webEvent);
}
@@ -556,12 +522,12 @@ void RenderWidgetHostViewQtDelegateClient::handleTouchEvent(QTouchEvent *event)
// Calculate a delta between event timestamps and Now() on the first received event, and
// apply this delta to all successive events. This delta is most likely smaller than it
// should by calculating it here but this will hopefully cause less than one frame of delay.
- base::TimeTicks eventTimestamp = base::TimeTicks() + base::TimeDelta::FromMilliseconds(event->timestamp());
+ base::TimeTicks eventTimestamp = base::TimeTicks() + base::Milliseconds(event->timestamp());
if (m_eventsToNowDelta == 0)
m_eventsToNowDelta = (base::TimeTicks::Now() - eventTimestamp).InMicroseconds();
- eventTimestamp += base::TimeDelta::FromMicroseconds(m_eventsToNowDelta);
+ eventTimestamp += base::Microseconds(m_eventsToNowDelta);
- auto touchPoints = mapTouchPointIds(event->touchPoints());
+ auto touchPoints = mapTouchPointIds(event->points());
// Make sure that POINTER_DOWN action is delivered before MOVE, and MOVE before POINTER_UP
std::sort(touchPoints.begin(), touchPoints.end(), [] (const TouchPoint &l, const TouchPoint &r) {
return l.second.state() < r.second.state();
@@ -570,7 +536,7 @@ void RenderWidgetHostViewQtDelegateClient::handleTouchEvent(QTouchEvent *event)
auto sc = qScopeGuard([&] () {
switch (event->type()) {
case QEvent::TouchCancel:
- for (auto &&it : qAsConst(touchPoints))
+ for (auto &&it : std::as_const(touchPoints))
m_touchIdMapping.remove(it.second.id());
Q_FALLTHROUGH();
@@ -589,13 +555,13 @@ void RenderWidgetHostViewQtDelegateClient::handleTouchEvent(QTouchEvent *event)
// Check first if the touch event should be routed to the selectionController
if (!touchPoints.isEmpty()) {
switch (touchPoints[0].second.state()) {
- case Qt::TouchPointPressed:
+ case QEventPoint::Pressed:
action = ui::MotionEvent::Action::DOWN;
break;
- case Qt::TouchPointMoved:
+ case QEventPoint::Updated:
action = ui::MotionEvent::Action::MOVE;
break;
- case Qt::TouchPointReleased:
+ case QEventPoint::Released:
action = ui::MotionEvent::Action::UP;
break;
default:
diff --git a/src/core/render_widget_host_view_qt_delegate_client.h b/src/core/render_widget_host_view_qt_delegate_client.h
index c56acfcfe..57354f549 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.h
+++ b/src/core/render_widget_host_view_qt_delegate_client.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,6 +17,7 @@
#include "compositor/compositor.h"
+#include <QMap>
#include <QtGui/QCursor>
#include <QtGui/QTouchEvent>
@@ -81,7 +46,7 @@ struct MultipleMouseClickHelper
ulong lastPressTimestamp = 0;
};
-class Q_WEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegateClient
+class Q_WEBENGINECORE_EXPORT RenderWidgetHostViewQtDelegateClient
{
public:
RenderWidgetHostViewQtDelegateClient(RenderWidgetHostViewQt *rwhv);
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
new file mode 100644
index 000000000..23e5bc935
--- /dev/null
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -0,0 +1,455 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "render_widget_host_view_qt_delegate_item.h"
+
+#include "render_widget_host_view_qt_delegate_client.h"
+
+#include <QtGui/qevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qwindow.h>
+#include <QtQuick/qsgimagenode.h>
+
+#if QT_CONFIG(accessibility)
+#include <QtGui/qaccessible.h>
+#endif
+
+namespace QtWebEngineCore {
+
+RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
+ : m_client(client)
+ , m_isPopup(isPopup)
+{
+ setFlag(ItemHasContents);
+ setAcceptedMouseButtons(Qt::AllButtons);
+ setKeepMouseGrab(true);
+ setAcceptHoverEvents(true);
+ setAcceptTouchEvents(true);
+ setKeepTouchGrab(true);
+ if (!isPopup) {
+ setFocus(true);
+ setActiveFocusOnTab(true);
+ }
+ bind(client->compositorId());
+}
+
+RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
+{
+ releaseTextureResources();
+ if (m_widgetDelegate) {
+ m_widgetDelegate->Unbind();
+ m_widgetDelegate->Destroy();
+ }
+}
+
+void RenderWidgetHostViewQtDelegateItem::initAsPopup(const QRect &screenRect)
+{
+ Q_ASSERT(m_isPopup);
+ setSize(screenRect.size());
+ if (m_widgetDelegate)
+ m_widgetDelegate->InitAsPopup(screenRect);
+}
+
+QRectF RenderWidgetHostViewQtDelegateItem::viewGeometry() const
+{
+ // Transform the entire rect to find the correct top left corner.
+ const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
+ const QPointF p2 = mapToGlobal(mapFromScene(QPointF(width(), height())));
+ QRectF geometry = QRectF(p1, p2).normalized();
+ // But keep the size untransformed to behave like other QQuickItems.
+ geometry.setSize(size());
+ return geometry;
+}
+
+QRect RenderWidgetHostViewQtDelegateItem::windowGeometry() const
+{
+ if (!Window())
+ return QRect();
+ return Window()->frameGeometry();
+}
+
+void RenderWidgetHostViewQtDelegateItem::setKeyboardFocus()
+{
+ setFocus(true);
+}
+
+bool RenderWidgetHostViewQtDelegateItem::hasKeyboardFocus()
+{
+ return hasActiveFocus();
+}
+
+void RenderWidgetHostViewQtDelegateItem::lockMouse()
+{
+ grabMouse();
+}
+
+void RenderWidgetHostViewQtDelegateItem::unlockMouse()
+{
+ ungrabMouse();
+}
+
+void RenderWidgetHostViewQtDelegateItem::show()
+{
+ if (isVisible())
+ m_client->notifyShown();
+ else
+ setVisible(true);
+}
+
+void RenderWidgetHostViewQtDelegateItem::hide()
+{
+ if (isVisible())
+ setVisible(false);
+ else
+ m_client->notifyHidden();
+}
+
+bool RenderWidgetHostViewQtDelegateItem::isVisible() const
+{
+ return QQuickItem::isVisible();
+}
+
+QWindow *RenderWidgetHostViewQtDelegateItem::Window() const
+{
+ if (m_widgetDelegate) {
+ if (auto *window = m_widgetDelegate->Window())
+ return window;
+ }
+ return QQuickItem::window();
+}
+
+void RenderWidgetHostViewQtDelegateItem::readyToSwap()
+{
+ // Call update() on UI thread.
+ QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
+}
+
+void RenderWidgetHostViewQtDelegateItem::updateCursor(const QCursor &cursor)
+{
+ setCursor(cursor);
+}
+
+void RenderWidgetHostViewQtDelegateItem::resize(int width, int height)
+{
+ setSize(QSizeF(width, height));
+ if (m_widgetDelegate)
+ m_widgetDelegate->Resize(width, height);
+}
+
+void RenderWidgetHostViewQtDelegateItem::move(const QPoint &point)
+{
+ if (m_widgetDelegate && m_isPopup)
+ m_widgetDelegate->MoveWindow(point);
+}
+
+void RenderWidgetHostViewQtDelegateItem::inputMethodStateChanged(bool editorVisible, bool passwordInput)
+{
+ setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);
+
+ if (parentItem())
+ parentItem()->setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);
+
+ if (m_widgetDelegate)
+ m_widgetDelegate->SetInputMethodEnabled(editorVisible && !passwordInput);
+
+ qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
+ if (qApp->inputMethod()->isVisible() != editorVisible)
+ qApp->inputMethod()->setVisible(editorVisible);
+}
+
+void RenderWidgetHostViewQtDelegateItem::setWidgetDelegate(WidgetDelegate *delegate)
+{
+ Q_ASSERT(!m_widgetDelegate || !delegate);
+ m_widgetDelegate = delegate;
+ if (m_widgetDelegate) {
+ if (m_inputMethodHints)
+ m_widgetDelegate->SetInputMethodHints(m_inputMethodHints);
+ if (m_clearColor.isValid())
+ m_widgetDelegate->SetClearColor(m_clearColor);
+ if (flags().testFlag(QQuickItem::ItemAcceptsInputMethod))
+ m_widgetDelegate->SetInputMethodEnabled(true);
+ if (m_adapterClient)
+ m_widgetDelegate->Bind(m_adapterClient);
+ }
+}
+
+void RenderWidgetHostViewQtDelegateItem::setInputMethodHints(Qt::InputMethodHints hints)
+{
+ m_inputMethodHints = hints;
+ if (m_widgetDelegate)
+ m_widgetDelegate->SetInputMethodHints(hints);
+}
+
+void RenderWidgetHostViewQtDelegateItem::setClearColor(const QColor &color)
+{
+ m_clearColor = color;
+ if (m_widgetDelegate)
+ m_widgetDelegate->SetClearColor(color);
+}
+
+bool RenderWidgetHostViewQtDelegateItem::event(QEvent *event)
+{
+ if (event->type() == QEvent::ShortcutOverride)
+ return m_client->forwardEvent(event);
+
+#if QT_CONFIG(gestures)
+ if (event->type() == QEvent::NativeGesture)
+ return m_client->forwardEvent(event);
+#endif
+
+ return QQuickItem::event(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::focusInEvent(QFocusEvent *event)
+{
+#if QT_CONFIG(accessibility)
+ if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(this)) {
+ if (auto *focusChild = iface->focusChild()) {
+ QAccessibleEvent focusEvent(focusChild, QAccessible::Focus);
+ if (focusEvent.object())
+ focusEvent.setChild(-1);
+ QAccessible::updateAccessibility(&focusEvent);
+ }
+ }
+#endif // QT_CONFIG(accessibility)
+
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::focusOutEvent(QFocusEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::mousePressEvent(QMouseEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate) {
+ if (m_widgetDelegate->ActiveFocusOnPress()) {
+ forceActiveFocus();
+ } else {
+ event->ignore();
+ return;
+ }
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress()) {
+ event->ignore();
+ return;
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress()) {
+ event->ignore();
+ return;
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::keyPressEvent(QKeyEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::keyReleaseEvent(QKeyEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::wheelEvent(QWheelEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::touchEvent(QTouchEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate) {
+ if (event->type() == QEvent::TouchBegin && m_widgetDelegate->ActiveFocusOnPress())
+ forceActiveFocus();
+
+ if (!m_widgetDelegate->ActiveFocusOnPress()) {
+ event->ignore();
+ return;
+ }
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::hoverMoveEvent(QHoverEvent *event)
+{
+ event->ignore();
+ if ((!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress())
+ || event->position() == event->oldPosF()) {
+ return;
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::hoverLeaveEvent(QHoverEvent *event)
+{
+ event->ignore();
+ m_client->forwardEvent(event);
+}
+
+QVariant RenderWidgetHostViewQtDelegateItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ return m_client->inputMethodQuery(query);
+}
+
+void RenderWidgetHostViewQtDelegateItem::inputMethodEvent(QInputMethodEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
+ m_client->visualPropertiesChanged();
+}
+
+void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ QQuickItem::itemChange(change, value);
+ if (change == QQuickItem::ItemSceneChange) {
+ for (const QMetaObject::Connection &c : std::as_const(m_windowConnections))
+ disconnect(c);
+ m_windowConnections.clear();
+ if (value.window) {
+ m_windowConnections.append(connect(value.window, &QQuickWindow::beforeRendering,
+ this, &RenderWidgetHostViewQtDelegateItem::onBeforeRendering, Qt::DirectConnection));
+ m_windowConnections.append(connect(value.window, &QQuickWindow::afterFrameEnd, this,
+ &RenderWidgetHostViewQtDelegateItem::onAfterFrameEnd,
+ Qt::DirectConnection));
+ m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
+ m_windowConnections.append(
+ connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
+ m_windowConnections.append(
+ connect(value.window, &QQuickWindow::sceneGraphAboutToStop, this,
+ &RenderWidgetHostViewQtDelegateItem::releaseTextureResources,
+ Qt::DirectConnection));
+ if (!m_isPopup)
+ m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
+ }
+ m_client->visualPropertiesChanged();
+ } else if (change == QQuickItem::ItemVisibleHasChanged) {
+ if (value.boolValue) {
+ m_client->notifyShown();
+ } else {
+ m_client->notifyHidden();
+ if (!m_isPopup)
+ onHide();
+ }
+ }
+}
+
+QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ auto comp = compositor();
+ if (!comp)
+ return oldNode;
+
+ QQuickWindow *win = QQuickItem::window();
+
+ QSGImageNode *node = nullptr;
+ // Delete old node before swapFrame to decrement refcount of
+ // QImage in software mode.
+ if (comp->type() == Compositor::Type::Software)
+ delete oldNode;
+ else
+ node = static_cast<QSGImageNode*>(oldNode);
+
+ if (!node) {
+ node = win->createImageNode();
+ node->setOwnsTexture(true);
+ }
+
+ comp->swapFrame();
+
+ QSize texSize = comp->size();
+ QSizeF texSizeInDips = QSizeF(texSize) / comp->devicePixelRatio();
+ node->setRect(QRectF(QPointF(0, 0), texSizeInDips));
+
+ QQuickWindow::CreateTextureOptions texOpts;
+ if (comp->requiresAlphaChannel() || m_clearColor.alpha() < 255)
+ texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
+ else
+ texOpts.setFlag(QQuickWindow::TextureIsOpaque);
+ QSGTexture *texture = comp->texture(win, texOpts);
+ if (texture) {
+ node->setTexture(texture);
+ if (comp->textureIsFlipped())
+ node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
+ } else {
+ if (!oldNode || comp->type() == Compositor::Type::Software) {
+ qDebug("Compositor returned null texture");
+ delete node;
+ return nullptr;
+ }
+ }
+
+ return node;
+}
+
+void RenderWidgetHostViewQtDelegateItem::onBeforeRendering()
+{
+ auto comp = compositor();
+ if (!comp || comp->type() == Compositor::Type::Software)
+ return;
+ comp->waitForTexture();
+}
+
+void RenderWidgetHostViewQtDelegateItem::onAfterFrameEnd()
+{
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::Native)
+ return;
+ comp->releaseTexture();
+}
+
+void RenderWidgetHostViewQtDelegateItem::onWindowPosChanged()
+{
+ m_client->visualPropertiesChanged();
+}
+
+void RenderWidgetHostViewQtDelegateItem::onHide()
+{
+ QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
+ m_client->forwardEvent(&event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::releaseTextureResources()
+{
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::Native)
+ return;
+
+ comp->releaseResources();
+}
+
+void RenderWidgetHostViewQtDelegateItem::adapterClientChanged(WebContentsAdapterClient *client)
+{
+ m_adapterClient = client;
+ if (m_widgetDelegate)
+ m_widgetDelegate->Bind(client);
+}
+
+void RenderWidgetHostViewQtDelegateItem::updateAdapterClientIfNeeded(WebContentsAdapterClient *client)
+{
+ if (client == m_adapterClient)
+ return;
+ adapterClientChanged(client);
+}
+
+void RenderWidgetHostViewQtDelegateItem::unhandledWheelEvent(QWheelEvent *ev)
+{
+ if (m_widgetDelegate)
+ m_widgetDelegate->unhandledWheelEvent(ev);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt_delegate_item.h b/src/core/render_widget_host_view_qt_delegate_item.h
new file mode 100644
index 000000000..0da6b4948
--- /dev/null
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -0,0 +1,125 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_ITEM_H
+#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_ITEM_H
+
+#include "compositor/compositor.h"
+#include "render_widget_host_view_qt_delegate.h"
+
+#include <QtQuick/QQuickItem>
+
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineViewPrivate;
+class QWebEngineViewPrivate;
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQtDelegateClient;
+class WebContentsAdapterClient;
+class WebEngineQuickWidget;
+
+class WidgetDelegate
+{
+public:
+ virtual ~WidgetDelegate() = default;
+ virtual void InitAsPopup(const QRect &screenRect) = 0;
+ virtual void SetInputMethodEnabled(bool) { }
+ virtual void SetInputMethodHints(Qt::InputMethodHints) { }
+ virtual void SetClearColor(const QColor &) { }
+ virtual bool ActiveFocusOnPress() = 0;
+ virtual void MoveWindow(const QPoint & ) { }
+ virtual void Bind(WebContentsAdapterClient *) = 0;
+ virtual void Unbind() = 0;
+ virtual void Destroy() = 0;
+ virtual void Resize(int, int) { }
+ virtual QWindow *Window() { return nullptr; }
+ virtual void unhandledWheelEvent(QWheelEvent *) { }
+};
+
+// Useful information keyboard and mouse QEvent propagation.
+// A RenderWidgetHostViewQtDelegateItem instance initialized as a popup will receive
+// no keyboard focus (so all keyboard QEvents will be sent to the parent RWHVQD instance),
+// but will still receive mouse input (all mouse QEvent moves and clicks will be given to the popup
+// RWHVQD instance, and the mouse interaction area covers the surface of the whole parent
+// QWebEngineView, and not only the smaller surface that an HTML select popup would occupy).
+class Q_WEBENGINECORE_EXPORT RenderWidgetHostViewQtDelegateItem
+ : public QQuickItem
+ , public RenderWidgetHostViewQtDelegate
+ , public Compositor::Observer
+{
+ Q_OBJECT
+public:
+ RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
+ ~RenderWidgetHostViewQtDelegateItem();
+
+ void initAsPopup(const QRect&) override;
+ QRectF viewGeometry() const override;
+ QRect windowGeometry() const override;
+ void setKeyboardFocus() override;
+ bool hasKeyboardFocus() override;
+ void lockMouse() override;
+ void unlockMouse() override;
+ void show() override;
+ void hide() override;
+ bool isVisible() const override;
+ QWindow *Window() const override;
+ void updateCursor(const QCursor &) override;
+ void resize(int width, int height) override;
+ void move(const QPoint &screenPos) override;
+ void inputMethodStateChanged(bool editorVisible, bool passwordInput) override;
+ void setInputMethodHints(Qt::InputMethodHints) override;
+ void setClearColor(const QColor &color) override;
+ void unhandledWheelEvent(QWheelEvent *ev) override;
+
+ void readyToSwap() override;
+
+ void setWidgetDelegate(WidgetDelegate *delegate);
+
+protected:
+ bool event(QEvent *event) override;
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void wheelEvent(QWheelEvent *event) override;
+ void touchEvent(QTouchEvent *event) override;
+ void hoverMoveEvent(QHoverEvent *event) override;
+ void hoverLeaveEvent(QHoverEvent *event) override;
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
+ void inputMethodEvent(QInputMethodEvent *event) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+
+ void adapterClientChanged(WebContentsAdapterClient *client) override;
+ void updateAdapterClientIfNeeded(WebContentsAdapterClient *client) override;
+
+private Q_SLOTS:
+ void onBeforeRendering();
+ void onAfterFrameEnd();
+ void onWindowPosChanged();
+ void releaseTextureResources();
+ void onHide();
+
+private:
+ friend QWebEngineViewPrivate;
+ friend QQuickWebEngineViewPrivate;
+ friend WebEngineQuickWidget;
+
+ RenderWidgetHostViewQtDelegateClient *m_client;
+ bool m_isPopup;
+ QColor m_clearColor;
+ Qt::InputMethodHints m_inputMethodHints = {};
+ QList<QMetaObject::Connection> m_windowConnections;
+ WebContentsAdapterClient *m_adapterClient = nullptr;
+ WidgetDelegate *m_widgetDelegate = nullptr;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_ITEM_H
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index f52c17dcf..cc127e55f 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -1,87 +1,56 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "renderer/content_renderer_client_qt.h"
-#include "extensions/buildflags/buildflags.h"
-#include "printing/buildflags/buildflags.h"
#include "renderer/content_settings_observer_qt.h"
-#include "base/strings/string_split.h"
-#if QT_CONFIG(webengine_spellchecker)
-#include "components/spellcheck/renderer/spellcheck.h"
-#include "components/spellcheck/renderer/spellcheck_provider.h"
-#endif
-#include "components/cdm/renderer/external_clear_key_key_system_properties.h"
-#include "components/cdm/renderer/widevine_key_system_properties.h"
+#include "renderer/render_configuration.h"
+#include "renderer/render_frame_observer_qt.h"
+#include "renderer/user_resource_controller.h"
+#include "renderer/web_engine_page_render_frame.h"
+#include "web_engine_library_info.h"
+
+#include "base/task/sequenced_task_runner.h"
+#include "components/autofill/content/renderer/autofill_agent.h"
+#include "components/autofill/content/renderer/password_autofill_agent.h"
+#include "components/autofill/content/renderer/password_generation_agent.h"
+#include "components/cdm/renderer/external_clear_key_key_system_info.h"
+#include "components/cdm/renderer/widevine_key_system_info.h"
#include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h"
+#include "components/grit/components_resources.h"
#include "components/network_hints/renderer/web_prescient_networking_impl.h"
-#if QT_CONFIG(webengine_printing_and_pdf)
-#include "components/printing/renderer/print_render_frame_helper.h"
-#endif
#include "components/visitedlink/renderer/visitedlink_reader.h"
#include "components/web_cache/renderer/web_cache_impl.h"
#include "content/public/renderer/render_frame.h"
-#include "content/public/child/child_thread.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "media/base/key_system_properties.h"
+#include "extensions/buildflags/buildflags.h"
+#include "media/base/key_system_info.h"
+#include "media/cdm/cdm_capability.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "net/base/net_errors.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "ppapi/buildflags/buildflags.h"
+#include "printing/buildflags/buildflags.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/platform/web_url_error.h"
-#include "third_party/blink/public/platform/web_url_request.h"
-#include "third_party/blink/public/web/web_security_policy.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
+#if QT_CONFIG(webengine_spellchecker)
+#include "components/spellcheck/renderer/spellcheck.h"
+#include "components/spellcheck/renderer/spellcheck_provider.h"
+#endif
+
#if QT_CONFIG(webengine_printing_and_pdf)
#include "renderer/print_web_view_helper_delegate_qt.h"
+
+#include "components/pdf/renderer/internal_plugin_renderer_helpers.h"
+#include "components/pdf/renderer/pdf_internal_plugin_delegate.h"
+#include "components/printing/renderer/print_render_frame_helper.h"
#endif
-#include "renderer/render_frame_observer_qt.h"
-#include "renderer/web_engine_page_render_frame.h"
-#include "renderer/render_configuration.h"
-#include "renderer/user_resource_controller.h"
#if QT_CONFIG(webengine_webchannel)
#include "renderer/web_channel_ipc_transport.h"
#endif
@@ -89,39 +58,37 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
#include "extensions/extensions_renderer_client_qt.h"
+
+#include "extensions/common/constants.h"
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
-#endif //ENABLE_EXTENSIONS
+#include "services/service_manager/public/cpp/binder_registry.h"
+#include "third_party/blink/public/web/web_security_policy.h"
+#endif // ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/renderer/render_frame_impl.h"
#include "plugins/loadable_plugin_placeholder_qt.h"
#endif // ENABLE_PLUGINS
-#include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/connector.h"
-
-#include "components/grit/components_resources.h"
-
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "base/feature_list.h"
#include "content/public/renderer/key_system_support.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
+#include "media/cdm/clear_key_cdm_common.h"
#include "third_party/widevine/cdm/buildflags.h"
+#if BUILDFLAG(ENABLE_WIDEVINE)
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#endif
+#endif
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
#include "chrome/renderer/media/webrtc_logging_agent_impl.h"
#endif
-#include "web_engine_library_info.h"
-
namespace QtWebEngineCore {
-static const char kHttpErrorDomain[] = "http";
-
ContentRendererClientQt::ContentRendererClientQt()
{
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -164,30 +131,34 @@ void ContentRendererClientQt::RenderThreadStarted()
void ContentRendererClientQt::ExposeInterfacesToBrowser(mojo::BinderMap* binders)
{
- binders->Add(m_visitedLinkReader->GetBindCallback(), base::SequencedTaskRunnerHandle::Get());
+ binders->Add<visitedlink::mojom::VisitedLinkNotificationSink>(
+ m_visitedLinkReader->GetBindCallback(), base::SingleThreadTaskRunner::GetCurrentDefault());
- binders->Add(base::BindRepeating(&web_cache::WebCacheImpl::BindReceiver,
- base::Unretained(m_webCacheImpl.get())),
- base::SequencedTaskRunnerHandle::Get());
+ binders->Add<web_cache::mojom::WebCache>(
+ base::BindRepeating(&web_cache::WebCacheImpl::BindReceiver,
+ base::Unretained(m_webCacheImpl.get())),
+ base::SingleThreadTaskRunner::GetCurrentDefault());
#if QT_CONFIG(webengine_spellchecker)
- binders->Add(base::BindRepeating(
+ binders->Add<spellcheck::mojom::SpellChecker>(
+ base::BindRepeating(
[](ContentRendererClientQt *client,
mojo::PendingReceiver<spellcheck::mojom::SpellChecker> receiver) {
if (!client->m_spellCheck)
client->InitSpellCheck();
client->m_spellCheck->BindReceiver(std::move(receiver));
}, this),
- base::SequencedTaskRunnerHandle::Get());
+ base::SingleThreadTaskRunner::GetCurrentDefault());
#endif
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
- binders->Add(base::BindRepeating(
+ binders->Add<chrome::mojom::WebRtcLoggingAgent>(
+ base::BindRepeating(
[](ContentRendererClientQt *client,
mojo::PendingReceiver<chrome::mojom::WebRtcLoggingAgent> receiver) {
client->GetWebRtcLoggingAgent()->AddReceiver(std::move(receiver));
}, this),
- base::SequencedTaskRunnerHandle::Get());
+ base::SingleThreadTaskRunner::GetCurrentDefault());
#endif
}
@@ -212,15 +183,37 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
#if QT_CONFIG(webengine_printing_and_pdf)
new printing::PrintRenderFrameHelper(render_frame, base::WrapUnique(new PrintWebViewHelperDelegateQt()));
#endif // QT_CONFIG(webengine_printing_and_pdf)
-#if BUILDFLAG(ENABLE_EXTENSIONS)
+
blink::AssociatedInterfaceRegistry *associated_interfaces = render_frame_observer->associatedInterfaces();
- associated_interfaces->AddInterface(base::BindRepeating(
- &extensions::MimeHandlerViewContainerManager::BindReceiver,
- render_frame->GetRoutingID()));
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ associated_interfaces->AddInterface<extensions::mojom::MimeHandlerViewContainerManager>(
+ base::BindRepeating(
+ &extensions::MimeHandlerViewContainerManager::BindReceiver,
+ render_frame->GetRoutingID()));
auto registry = std::make_unique<service_manager::BinderRegistry>();
ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
#endif
+
+ autofill::PasswordAutofillAgent *password_autofill_agent =
+ new autofill::PasswordAutofillAgent(render_frame, associated_interfaces);
+ autofill::PasswordGenerationAgent *password_generation_agent =
+ new autofill::PasswordGenerationAgent(render_frame, password_autofill_agent,
+ associated_interfaces);
+
+ new autofill::AutofillAgent(render_frame, password_autofill_agent, password_generation_agent,
+ associated_interfaces);
+}
+
+void ContentRendererClientQt::WebViewCreated(blink::WebView *web_view,
+ bool was_created_by_renderer,
+ const url::Origin *outermost_origin)
+{
+ Q_UNUSED(was_created_by_renderer);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ExtensionsRendererClientQt::GetInstance()->WebViewCreated(web_view, outermost_origin);
+#endif
}
void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame *render_frame)
@@ -258,11 +251,13 @@ void ContentRendererClientQt::RunScriptsAtDocumentIdle(content::RenderFrame *ren
void ContentRendererClientQt::PrepareErrorPage(content::RenderFrame *renderFrame,
const blink::WebURLError &web_error,
const std::string &httpMethod,
+ content::mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info,
std::string *errorHtml)
{
GetNavigationErrorStringsInternal(
renderFrame, httpMethod,
- error_page::Error::NetError((GURL)web_error.url(), web_error.reason(), net::ResolveErrorInfo(), web_error.has_copy_in_cache()),
+ error_page::Error::NetError((GURL)web_error.url(), web_error.reason(), web_error.extended_reason(),
+ net::ResolveErrorInfo(), web_error.has_copy_in_cache()),
errorHtml);
}
@@ -270,6 +265,7 @@ void ContentRendererClientQt::PrepareErrorPageForHttpStatusError(content::Render
const blink::WebURLError &error,
const std::string &httpMethod,
int http_status,
+ content::mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info,
std::string *errorHtml)
{
GetNavigationErrorStringsInternal(renderFrame, httpMethod,
@@ -293,11 +289,12 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
// TODO(elproxy): We could potentially get better diagnostics here by first calling
// NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle.
+ base::Value::Dict error_page_params;
error_page::LocalizedError::PageState errorPageState =
error_page::LocalizedError::GetPageState(
error.reason(), error.domain(), error.url(), isPost, false,
error.stale_copy_in_cache(), false,
- RenderConfiguration::is_incognito_process(), false, false, false, locale);
+ RenderConfiguration::is_incognito_process(), false, false, false, locale, false, &error_page_params);
resourceId = IDR_NET_ERROR_HTML;
@@ -306,7 +303,7 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
if (template_html.empty())
NOTREACHED() << "unable to load template. ID: " << resourceId;
else // "t" is the id of the templates root node.
- *errorHtml = webui::GetTemplatesHtml(template_html, &errorPageState.strings, "t");
+ *errorHtml = webui::GetTemplatesHtml(template_html, errorPageState.strings, "t");
}
}
@@ -325,6 +322,66 @@ std::unique_ptr<blink::WebPrescientNetworking> ContentRendererClientQt::CreatePr
return std::make_unique<network_hints::WebPrescientNetworkingImpl>(render_frame);
}
+namespace {
+bool IsPdfExtensionOrigin(const url::Origin &origin)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ return origin.scheme() == extensions::kExtensionScheme &&
+ origin.host() == extension_misc::kPdfExtensionId;
+#else
+ return false;
+#endif
+}
+
+#if BUILDFLAG(ENABLE_PLUGINS)
+void AppendParams(const std::vector<content::WebPluginMimeType::Param> &additional_params,
+ blink::WebVector<blink::WebString> *existing_names,
+ blink::WebVector<blink::WebString> *existing_values)
+{
+ DCHECK(existing_names->size() == existing_values->size());
+ size_t existing_size = existing_names->size();
+ size_t total_size = existing_size + additional_params.size();
+
+ blink::WebVector<blink::WebString> names(total_size);
+ blink::WebVector<blink::WebString> values(total_size);
+
+ for (size_t i = 0; i < existing_size; ++i) {
+ names[i] = (*existing_names)[i];
+ values[i] = (*existing_values)[i];
+ }
+
+ for (size_t i = 0; i < additional_params.size(); ++i) {
+ names[existing_size + i] = blink::WebString::FromUTF16(additional_params[i].name);
+ values[existing_size + i] = blink::WebString::FromUTF16(additional_params[i].value);
+ }
+
+ existing_names->Swap(names);
+ existing_values->Swap(values);
+}
+#endif // BUILDFLAG(ENABLE_PLUGINS)
+
+#if QT_CONFIG(webengine_printing_and_pdf)
+// based on chrome/renderer/pdf/chrome_pdf_internal_plugin_delegate.cc:
+class PdfInternalPluginDelegateQt final
+ : public pdf::PdfInternalPluginDelegate
+{
+public:
+ PdfInternalPluginDelegateQt() = default;
+ PdfInternalPluginDelegateQt(const PdfInternalPluginDelegateQt &) = delete;
+ PdfInternalPluginDelegateQt& operator=(const PdfInternalPluginDelegateQt &) = delete;
+ ~PdfInternalPluginDelegateQt() override = default;
+
+ // `pdf::PdfInternalPluginDelegate`:
+ bool IsAllowedOrigin(const url::Origin &origin) const override;
+};
+
+bool PdfInternalPluginDelegateQt::IsAllowedOrigin(const url::Origin &origin) const
+{
+ return IsPdfExtensionOrigin(origin);
+}
+#endif
+} // namespace
+
bool ContentRendererClientQt::IsPluginHandledExternally(content::RenderFrame *render_frame,
const blink::WebElement &plugin_element,
const GURL &original_url,
@@ -336,10 +393,11 @@ bool ContentRendererClientQt::IsPluginHandledExternally(content::RenderFrame *re
std::string mime_type;
static_cast<content::RenderFrameImpl *>(render_frame)->GetPepperHost()->GetPluginInfo(
- original_url, render_frame->GetWebFrame()->Top()->GetSecurityOrigin(),
- original_mime_type, &found, &plugin_info, &mime_type);
+ original_url, original_mime_type, &found, &plugin_info, &mime_type);
if (!found)
return false;
+ if (IsPdfExtensionOrigin(render_frame->GetWebFrame()->GetSecurityOrigin()))
+ return true;
return extensions::MimeHandlerViewContainerManager::Get(
content::RenderFrame::FromWebFrame(
plugin_element.GetDocument().GetFrame()),
@@ -357,7 +415,7 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
#if BUILDFLAG(ENABLE_EXTENSIONS)
if (!ExtensionsRendererClientQt::GetInstance()->OverrideCreatePlugin(render_frame, params))
return false;
-#endif //ENABLE_EXTENSIONS
+#endif // ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
content::WebPluginInfo info;
@@ -365,13 +423,26 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
bool found = false;
static_cast<content::RenderFrameImpl *>(render_frame)->GetPepperHost()->GetPluginInfo(
- params.url, render_frame->GetWebFrame()->Top()->GetSecurityOrigin(),
- params.mime_type.Utf8(), &found, &info, &mime_type);
- if (!found)
+ params.url, params.mime_type.Utf8(), &found, &info, &mime_type);
+ if (!found) {
*plugin = LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, params)->plugin();
- else
- *plugin = render_frame->CreatePlugin(info, params);
-#endif // BUILDFLAG(ENABLE_PLUGINS)
+ return true;
+ }
+ if (info.name == u"Chromium PDF Viewer") {
+ blink::WebPluginParams new_params(params);
+ for (const auto& mime_type : info.mime_types) {
+ if (mime_type.mime_type == params.mime_type.Utf8()) {
+ AppendParams(mime_type.additional_params, &new_params.attribute_names,
+ &new_params.attribute_values);
+ break;
+ }
+ }
+
+ *plugin = pdf::CreateInternalPlugin(std::move(new_params), render_frame, std::make_unique<PdfInternalPluginDelegateQt>());
+ return true;
+ }
+ *plugin = render_frame->CreatePlugin(info, params);
+#endif // BUILDFLAG(ENABLE_PLUGINS)
return true;
}
@@ -403,129 +474,125 @@ void ContentRendererClientQt::GetInterface(const std::string &interface_name, mo
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// External Clear Key (used for testing).
-static void AddExternalClearKey(std::vector<std::unique_ptr<media::KeySystemProperties>> *concrete_key_systems)
-{
- // TODO(xhwang): Move these into an array so we can use a for loop to add
- // supported key systems below.
- static const char kExternalClearKeyKeySystem[] =
- "org.chromium.externalclearkey";
- static const char kExternalClearKeyDecryptOnlyKeySystem[] =
- "org.chromium.externalclearkey.decryptonly";
- static const char kExternalClearKeyMessageTypeTestKeySystem[] =
- "org.chromium.externalclearkey.messagetypetest";
- static const char kExternalClearKeyFileIOTestKeySystem[] =
- "org.chromium.externalclearkey.fileiotest";
- static const char kExternalClearKeyOutputProtectionTestKeySystem[] =
- "org.chromium.externalclearkey.outputprotectiontest";
- static const char kExternalClearKeyPlatformVerificationTestKeySystem[] =
- "org.chromium.externalclearkey.platformverificationtest";
- static const char kExternalClearKeyInitializeFailKeySystem[] =
- "org.chromium.externalclearkey.initializefail";
- static const char kExternalClearKeyCrashKeySystem[] =
- "org.chromium.externalclearkey.crash";
- static const char kExternalClearKeyVerifyCdmHostTestKeySystem[] =
- "org.chromium.externalclearkey.verifycdmhosttest";
- static const char kExternalClearKeyStorageIdTestKeySystem[] =
- "org.chromium.externalclearkey.storageidtest";
- static const char kExternalClearKeyDifferentGuidTestKeySystem[] =
- "org.chromium.externalclearkey.differentguid";
- static const char kExternalClearKeyCdmProxyTestKeySystem[] =
- "org.chromium.externalclearkey.cdmproxytest";
-
- media::mojom::KeySystemCapabilityPtr capability;
- if (!content::IsKeySystemSupported(kExternalClearKeyKeySystem, &capability)) {
- DVLOG(1) << "External Clear Key not supported";
+static void AddExternalClearKey(const media::mojom::KeySystemCapabilityPtr &capability,
+ media::KeySystemInfos* key_systems)
+{
+ Q_UNUSED(capability);
+ if (!base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting)) {
+ DLOG(ERROR) << "ExternalClearKey supported despite not enabled.";
return;
}
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyKeySystem));
-
- // Add support of decrypt-only mode in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyDecryptOnlyKeySystem));
-
- // A key system that triggers various types of messages in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyMessageTypeTestKeySystem));
-
- // A key system that triggers the FileIO test in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyFileIOTestKeySystem));
-
- // A key system that triggers the output protection test in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyOutputProtectionTestKeySystem));
-
- // A key system that triggers the platform verification test in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyPlatformVerificationTestKeySystem));
+ // TODO(xhwang): Actually use `capability` to determine capabilities.
+ key_systems->push_back(std::make_unique<cdm::ExternalClearKeyKeySystemInfo>());
+}
- // A key system that Chrome thinks is supported by ClearKeyCdm, but actually
- // will be refused by ClearKeyCdm. This is to test the CDM initialization
- // failure case.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyInitializeFailKeySystem));
+#if BUILDFLAG(ENABLE_WIDEVINE)
+media::SupportedCodecs GetVP9Codecs(const base::flat_set<media::VideoCodecProfile> &profiles)
+{
+ if (profiles.empty()) {
+ // If no profiles are specified, then all are supported.
+ return media::EME_CODEC_VP9_PROFILE0 | media::EME_CODEC_VP9_PROFILE2;
+ }
- // A key system that triggers a crash in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyCrashKeySystem));
+ media::SupportedCodecs supported_vp9_codecs = media::EME_CODEC_NONE;
+ for (const auto& profile : profiles) {
+ switch (profile) {
+ case media::VP9PROFILE_PROFILE0:
+ supported_vp9_codecs |= media::EME_CODEC_VP9_PROFILE0;
+ break;
+ case media::VP9PROFILE_PROFILE2:
+ supported_vp9_codecs |= media::EME_CODEC_VP9_PROFILE2;
+ break;
+ default:
+ DVLOG(1) << "Unexpected " << media::GetCodecName(media::VideoCodec::kVP9)
+ << " profile: " << media::GetProfileName(profile);
+ break;
+ }
+ }
- // A key system that triggers the verify host files test in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyVerifyCdmHostTestKeySystem));
+ return supported_vp9_codecs;
+}
- // A key system that fetches the Storage ID in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyStorageIdTestKeySystem));
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+media::SupportedCodecs GetHevcCodecs(const base::flat_set<media::VideoCodecProfile> &profiles)
+{
+ // If no profiles are specified, then all are supported.
+ if (profiles.empty()) {
+ return media::EME_CODEC_HEVC_PROFILE_MAIN |
+ media::EME_CODEC_HEVC_PROFILE_MAIN10;
+ }
- // A key system that is registered with a different CDM GUID.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyDifferentGuidTestKeySystem));
+ media::SupportedCodecs supported_hevc_codecs = media::EME_CODEC_NONE;
+ for (const auto& profile : profiles) {
+ switch (profile) {
+ case media::HEVCPROFILE_MAIN:
+ supported_hevc_codecs |= media::EME_CODEC_HEVC_PROFILE_MAIN;
+ break;
+ case media::HEVCPROFILE_MAIN10:
+ supported_hevc_codecs |= media::EME_CODEC_HEVC_PROFILE_MAIN10;
+ break;
+ default:
+ DVLOG(1) << "Unexpected " << media::GetCodecName(media::VideoCodec::kHEVC)
+ << " profile: " << media::GetProfileName(profile);
+ break;
+ }
+ }
- // A key system that triggers CDM Proxy test in ClearKeyCdm.
- concrete_key_systems->emplace_back(
- new cdm::ExternalClearKeyProperties(kExternalClearKeyCdmProxyTestKeySystem));
+ return supported_hevc_codecs;
}
+#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
-#if BUILDFLAG(ENABLE_WIDEVINE)
-static media::SupportedCodecs GetSupportedCodecs(const std::vector<media::VideoCodec> &supported_video_codecs,
+static media::SupportedCodecs GetSupportedCodecs(const media::CdmCapability& capability,
bool is_secure)
{
media::SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
- // Audio codecs are always supported because the CDM only does decrypt-only
- // for audio. The only exception is when |is_secure| is true and there's no
- // secure video decoder available, which is a signal that secure hardware
- // decryption is not available either.
- // TODO(sandersd): Distinguish these from those that are directly supported,
- // as those may offer a higher level of protection.
- if (!supported_video_codecs.empty() || !is_secure) {
- supported_codecs |= media::EME_CODEC_OPUS;
- supported_codecs |= media::EME_CODEC_VORBIS;
- supported_codecs |= media::EME_CODEC_FLAC;
+ for (const auto& codec : capability.audio_codecs) {
+ switch (codec) {
+ case media::AudioCodec::kOpus:
+ supported_codecs |= media::EME_CODEC_OPUS;
+ break;
+ case media::AudioCodec::kVorbis:
+ supported_codecs |= media::EME_CODEC_VORBIS;
+ break;
+ case media::AudioCodec::kFLAC:
+ supported_codecs |= media::EME_CODEC_FLAC;
+ break;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
- supported_codecs |= media::EME_CODEC_AAC;
-#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
+ case media::AudioCodec::kAAC:
+ supported_codecs |= media::EME_CODEC_AAC;
+ break;
+#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
+ default:
+ DVLOG(1) << "Unexpected supported codec: " << GetCodecName(codec);
+ break;
+ }
}
- // Video codecs are determined by what was registered for the CDM.
- for (const auto &codec : supported_video_codecs) {
- switch (codec) {
- case media::VideoCodec::kCodecVP8:
+ for (const auto &codec : capability.video_codecs) {
+ switch (codec.first) {
+ case media::VideoCodec::kVP8:
supported_codecs |= media::EME_CODEC_VP8;
break;
- case media::VideoCodec::kCodecVP9:
- supported_codecs |= media::EME_CODEC_VP9_PROFILE0;
- supported_codecs |= media::EME_CODEC_VP9_PROFILE2;
+ case media::VideoCodec::kVP9:
+ supported_codecs |= GetVP9Codecs(codec.second.supported_profiles);
+ break;
+ case media::VideoCodec::kAV1:
+ supported_codecs |= media::EME_CODEC_AV1;
break;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
- case media::VideoCodec::kCodecH264:
+ case media::VideoCodec::kH264:
supported_codecs |= media::EME_CODEC_AVC1;
break;
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+ case media::VideoCodec::kHEVC:
+ supported_codecs |= GetHevcCodecs(codec.second.supported_profiles);
+ break;
+#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
default:
- DVLOG(1) << "Unexpected supported codec: " << GetCodecName(codec);
+ DVLOG(1) << "Unexpected supported codec: " << GetCodecName(codec.first);
break;
}
}
@@ -533,23 +600,36 @@ static media::SupportedCodecs GetSupportedCodecs(const std::vector<media::VideoC
return supported_codecs;
}
-static void AddWidevine(std::vector<std::unique_ptr<media::KeySystemProperties>> *concrete_key_systems)
+static void AddWidevine(const media::mojom::KeySystemCapabilityPtr &capability,
+ media::KeySystemInfos *key_systems)
{
- media::mojom::KeySystemCapabilityPtr capability;
- if (!content::IsKeySystemSupported(kWidevineKeySystem, &capability)) {
- DVLOG(1) << "Widevine CDM is not currently available.";
- return;
+ // Codecs and encryption schemes.
+ media::SupportedCodecs codecs = media::EME_CODEC_NONE;
+ media::SupportedCodecs hw_secure_codecs = media::EME_CODEC_NONE;
+ base::flat_set<media::EncryptionScheme> encryption_schemes;
+ base::flat_set<media::EncryptionScheme> hw_secure_encryption_schemes;
+ base::flat_set<media::CdmSessionType> session_types;
+ base::flat_set<media::CdmSessionType> hw_secure_session_types;
+ if (capability->sw_secure_capability) {
+ codecs = GetSupportedCodecs(capability->sw_secure_capability.value(), /*is_secure=*/false);
+ encryption_schemes = capability->sw_secure_capability->encryption_schemes;
+ if (!base::Contains(capability->sw_secure_capability->session_types, media::CdmSessionType::kTemporary)) {
+ DVLOG(1) << "Temporary sessions must be supported.";
+ return;
+ }
}
- // Codecs and encryption schemes.
- auto codecs = GetSupportedCodecs(capability->video_codecs, /*is_secure=*/false);
- const auto &encryption_schemes = capability->encryption_schemes;
- auto hw_secure_codecs = GetSupportedCodecs(capability->hw_secure_video_codecs,
- /*is_secure=*/true);
- const auto &hw_secure_encryption_schemes = capability->hw_secure_encryption_schemes;
+ if (capability->hw_secure_capability) {
+ hw_secure_codecs = GetSupportedCodecs(capability->hw_secure_capability.value(), /*is_secure=*/true);
+ hw_secure_encryption_schemes = capability->hw_secure_capability->encryption_schemes;
+ if (!base::Contains(capability->hw_secure_capability->session_types, media::CdmSessionType::kTemporary)) {
+ DVLOG(1) << "Temporary sessions must be supported.";
+ return;
+ }
+ }
// Robustness.
- using Robustness = cdm::WidevineKeySystemProperties::Robustness;
+ using Robustness = cdm::WidevineKeySystemInfo::Robustness;
auto max_audio_robustness = Robustness::SW_SECURE_CRYPTO;
auto max_video_robustness = Robustness::SW_SECURE_DECODE;
@@ -558,40 +638,52 @@ static void AddWidevine(std::vector<std::unique_ptr<media::KeySystemProperties>>
max_video_robustness = Robustness::HW_SECURE_ALL;
}
- // Session types.
- bool cdm_supports_temporary_session = base::Contains(capability->session_types, media::CdmSessionType::kTemporary);
- if (!cdm_supports_temporary_session) {
- DVLOG(1) << "Temporary session must be supported.";
- return;
- }
-
- auto persistent_license_support = media::EmeSessionTypeSupport::NOT_SUPPORTED;
- auto persistent_usage_record_support = media::EmeSessionTypeSupport::NOT_SUPPORTED;
-
// Others.
auto persistent_state_support = media::EmeFeatureSupport::REQUESTABLE;
auto distinctive_identifier_support = media::EmeFeatureSupport::NOT_SUPPORTED;
- concrete_key_systems->emplace_back(new cdm::WidevineKeySystemProperties(
- codecs, encryption_schemes, hw_secure_codecs,
- hw_secure_encryption_schemes, max_audio_robustness, max_video_robustness,
- persistent_license_support, persistent_usage_record_support,
- persistent_state_support, distinctive_identifier_support));
+ key_systems->emplace_back(new cdm::WidevineKeySystemInfo(
+ codecs, std::move(encryption_schemes), std::move(session_types),
+ hw_secure_codecs, std::move(hw_secure_encryption_schemes),
+ std::move(hw_secure_session_types),
+ max_audio_robustness, max_video_robustness,
+ persistent_state_support,
+ distinctive_identifier_support));
}
#endif // BUILDFLAG(ENABLE_WIDEVINE)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
-void ContentRendererClientQt::AddSupportedKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>> *key_systems)
+void OnKeySystemSupportUpdated(media::GetSupportedKeySystemsCB cb,
+ content::KeySystemCapabilityPtrMap key_system_capabilities)
{
+ media::KeySystemInfos key_systems;
+ for (const auto &entry : key_system_capabilities) {
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
- if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting))
- AddExternalClearKey(key_systems);
-
+ const auto &key_system = entry.first;
+ const auto &capability = entry.second;
#if BUILDFLAG(ENABLE_WIDEVINE)
- AddWidevine(key_systems);
+ if (key_system == kWidevineKeySystem) {
+ AddWidevine(capability, &key_systems);
+ continue;
+ }
#endif // BUILDFLAG(ENABLE_WIDEVINE)
+ if (key_system == media::kExternalClearKeyKeySystem) {
+ AddExternalClearKey(capability, &key_systems);
+ continue;
+ }
+
+ DLOG(ERROR) << "Unrecognized key system: " << key_system;
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
+ }
+
+ cb.Run(std::move(key_systems));
+}
+
+void ContentRendererClientQt::GetSupportedKeySystems(media::GetSupportedKeySystemsCB cb)
+{
+ content::ObserveKeySystemSupportUpdate(
+ base::BindRepeating(&OnKeySystemSupportUpdated, std::move(cb)));
}
#if QT_CONFIG(webengine_spellchecker)
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index 4e1759759..b2231f00a 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -1,57 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CONTENT_RENDERER_CLIENT_QT_H
#define CONTENT_RENDERER_CLIENT_QT_H
#include "qtwebenginecoreglobal_p.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "components/spellcheck/spellcheck_buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/local_interface_provider.h"
-#include "ppapi/buildflags/buildflags.h"
-
-#if BUILDFLAG(ENABLE_PLUGINS)
-#include "third_party/blink/public/web/web_plugin_params.h"
-#endif
#include <QScopedPointer>
+namespace blink {
+class WebPlugin;
+struct WebPluginParams;
+}
+
namespace chrome {
class WebRtcLoggingAgentImpl;
}
@@ -72,10 +35,6 @@ class WebCacheImpl;
class SpellCheck;
#endif
-namespace content {
-struct WebPluginInfo;
-}
-
namespace QtWebEngineCore {
class UserResourceController;
@@ -92,22 +51,25 @@ public:
void RenderThreadStarted() override;
void ExposeInterfacesToBrowser(mojo::BinderMap* binders) override;
void RenderFrameCreated(content::RenderFrame *render_frame) override;
+ void WebViewCreated(blink::WebView *web_view,
+ bool was_created_by_renderer,
+ const url::Origin *outermost_origin) override;
void PrepareErrorPage(content::RenderFrame *render_frame,
const blink::WebURLError &error,
const std::string &http_method,
+ content::mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info,
std::string *error_html) override;
void PrepareErrorPageForHttpStatusError(content::RenderFrame *render_frame,
const blink::WebURLError &error,
const std::string &http_method,
int http_status,
+ content::mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info,
std::string *error_html) override;
-
uint64_t VisitedLinkHash(const char *canonical_url, size_t length) override;
bool IsLinkVisited(uint64_t linkHash) override;
std::unique_ptr<blink::WebPrescientNetworking> CreatePrescientNetworking(content::RenderFrame *render_frame) override;
- void AddSupportedKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>> *key_systems) override;
-
+ void GetSupportedKeySystems(media::GetSupportedKeySystemsCB cb) override;
void RunScriptsAtDocumentStart(content::RenderFrame *render_frame) override;
void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame) override;
void RunScriptsAtDocumentIdle(content::RenderFrame *render_frame) override;
@@ -133,7 +95,7 @@ public:
private:
-#if BUILDFLAG(ENABLE_SPELLCHECK)
+#if QT_CONFIG(webengine_spellchecker)
void InitSpellCheck();
#endif
// service_manager::LocalInterfaceProvider:
@@ -152,8 +114,6 @@ private:
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
std::unique_ptr<chrome::WebRtcLoggingAgentImpl> m_webrtcLoggingAgentImpl;
#endif
-
- DISALLOW_COPY_AND_ASSIGN(ContentRendererClientQt);
};
} // namespace
diff --git a/src/core/renderer/content_settings_observer_qt.cpp b/src/core/renderer/content_settings_observer_qt.cpp
index 18d52b50a..3e3c159f5 100644
--- a/src/core/renderer/content_settings_observer_qt.cpp
+++ b/src/core/renderer/content_settings_observer_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Based on chrome/renderer/content_settings_observer.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -46,15 +10,12 @@
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/web/web_plugin_document.h"
+#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "url/origin.h"
#include "common/qt_messages.h"
-using blink::WebSecurityOrigin;
-using blink::WebString;
-
namespace {
bool IsUniqueFrame(blink::WebFrame *frame)
diff --git a/src/core/renderer/content_settings_observer_qt.h b/src/core/renderer/content_settings_observer_qt.h
index 9268b4982..415d0b6b7 100644
--- a/src/core/renderer/content_settings_observer_qt.h
+++ b/src/core/renderer/content_settings_observer_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -50,10 +14,6 @@
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "url/gurl.h"
-namespace blink {
-class WebSecurityOrigin;
-}
-
namespace QtWebEngineCore {
// Handles blocking content per content settings for each RenderFrame.
@@ -89,10 +49,8 @@ private:
int m_currentRequestId;
base::flat_map<int, base::OnceCallback<void(bool)>> m_permissionRequests;
-
- DISALLOW_COPY_AND_ASSIGN(ContentSettingsObserverQt);
};
} // namespace QtWebEngineCore
-#endif // RENDERER_CONTENT_SETTINGS_OBSERVER_QT_H
+#endif // CONTENT_SETTINGS_OBSERVER_QT_H
diff --git a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
index d49845f55..191e36d04 100644
--- a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
+++ b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "extensions_dispatcher_delegate_qt.h"
diff --git a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
index 1a19bcbbb..42ae165d1 100644
--- a/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
+++ b/src/core/renderer/extensions/extensions_dispatcher_delegate_qt.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef EXTENSIONSDISPATCHERDELEGATEQT_H
#define EXTENSIONSDISPATCHERDELEGATEQT_H
-#include "base/macros.h"
#include "extensions/renderer/dispatcher_delegate.h"
namespace QtWebEngineCore {
@@ -54,8 +17,6 @@ public:
private:
// extensions::DispatcherDelegate implementation.
void PopulateSourceMap(extensions::ResourceBundleSourceMap *source_map) override;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionsDispatcherDelegateQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
index b1998e027..b36ed9e8b 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/renderer/extensions/chrome_extensions_renderer_client.cc:
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
@@ -51,6 +15,8 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/stl_util.h"
+#include "base/types/optional_util.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
@@ -61,8 +27,8 @@
#include "extensions/common/switches.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/extension_frame_helper.h"
+#include "extensions/renderer/extension_web_view_helper.h"
#include "extensions/renderer/extensions_render_frame_observer.h"
-#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
#include "extensions/renderer/renderer_extension_registry.h"
#include "extensions/renderer/script_context.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -70,7 +36,6 @@
namespace chrome {
const char kExtensionInvalidRequestURL[] = "chrome-extension://invalid/";
-const char kExtensionResourceInvalidRequestURL[] = "chrome-extension-resource://invalid/";
}
namespace QtWebEngineCore {
@@ -147,10 +112,13 @@ void ExtensionsRendererClientQt::RenderThreadStarted()
extension_dispatcher_->OnRenderThreadStarted(thread);
permissions_policy_delegate_.reset(new RendererPermissionsPolicyDelegateQt(extension_dispatcher_.get()));
resource_request_policy_.reset(new extensions::ResourceRequestPolicyQt(extension_dispatcher_.get()));
- guest_view_container_dispatcher_.reset(new extensions::ExtensionsGuestViewContainerDispatcher());
thread->AddObserver(extension_dispatcher_.get());
- thread->AddObserver(guest_view_container_dispatcher_.get());
+}
+
+void ExtensionsRendererClientQt::WebViewCreated(blink::WebView *web_view, const url::Origin *outermost_origin)
+{
+ new extensions::ExtensionWebViewHelper(web_view, outermost_origin);
}
void ExtensionsRendererClientQt::RenderFrameCreated(content::RenderFrame *render_frame,
diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.h b/src/core/renderer/extensions/extensions_renderer_client_qt.h
index d73456643..163819cbc 100644
--- a/src/core/renderer/extensions/extensions_renderer_client_qt.h
+++ b/src/core/renderer/extensions/extensions_renderer_client_qt.h
@@ -1,49 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef EXTENSIONSRENDERERCLIENTQT_H
#define EXTENSIONSRENDERERCLIENTQT_H
#include <memory>
-#include <string>
-#include "base/macros.h"
#include "extensions/renderer/extensions_renderer_client.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "ui/base/page_transition_types.h"
@@ -54,13 +16,11 @@ namespace blink {
class WebLocalFrame;
struct WebPluginParams;
class WebURL;
+class WebView;
}
namespace content {
-class BrowserPluginDelegate;
class RenderFrame;
-class RenderView;
-struct WebPluginInfo;
}
namespace net {
@@ -73,7 +33,6 @@ class Origin;
namespace extensions {
class Dispatcher;
-class ExtensionsGuestViewContainerDispatcher;
class ResourceRequestPolicyQt;
}
@@ -97,6 +56,8 @@ public:
// Match ContentRendererClientQt's method names...
void RenderThreadStarted();
+ void WebViewCreated(blink::WebView *web_view,
+ const url::Origin *outermost_origin);
void RenderFrameCreated(content::RenderFrame *, service_manager::BinderRegistry *);
bool OverrideCreatePlugin(content::RenderFrame *render_frame,
const blink::WebPluginParams &params);
@@ -128,7 +89,6 @@ private:
std::unique_ptr<ExtensionsDispatcherDelegateQt> extension_dispatcher_delegate_;
std::unique_ptr<RendererPermissionsPolicyDelegateQt> permissions_policy_delegate_;
std::unique_ptr<extensions::Dispatcher> extension_dispatcher_;
- std::unique_ptr<extensions::ExtensionsGuestViewContainerDispatcher> guest_view_container_dispatcher_;
std::unique_ptr<extensions::ResourceRequestPolicyQt> resource_request_policy_;
};
diff --git a/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp
index aef4903b7..fdfbe463b 100644
--- a/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp
+++ b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "renderer_permissions_policy_delegate_qt.h"
diff --git a/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h
index 385b7a4b0..23bfa8c88 100644
--- a/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h
+++ b/src/core/renderer/extensions/renderer_permissions_policy_delegate_qt.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef RENDERERPERMISSIONSPOLICYDELEGATEQT_H
#define RENDERERPERMISSIONSPOLICYDELEGATEQT_H
-#include "base/macros.h"
#include "extensions/common/permissions/permissions_data.h"
namespace extensions {
@@ -56,9 +19,6 @@ public:
~RendererPermissionsPolicyDelegateQt() override;
bool IsRestrictedUrl(const GURL &, std::string *) override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(RendererPermissionsPolicyDelegateQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/extensions/resource_request_policy_qt.cpp b/src/core/renderer/extensions/resource_request_policy_qt.cpp
index 70e97819c..a61e53310 100644
--- a/src/core/renderer/extensions/resource_request_policy_qt.cpp
+++ b/src/core/renderer/extensions/resource_request_policy_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/renderer/extensions/resource_request_policy.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -63,8 +27,9 @@ ResourceRequestPolicyQt::ResourceRequestPolicyQt(Dispatcher *dispatcher)
void ResourceRequestPolicyQt::OnExtensionLoaded(const Extension &extension)
{
- if (WebAccessibleResourcesInfo::HasWebAccessibleResources(&extension)
- || WebviewInfo::HasWebviewAccessibleResources(extension, m_dispatcher->webview_partition_id())
+ if (WebAccessibleResourcesInfo::HasWebAccessibleResources(&extension) ||
+ WebviewInfo::HasWebviewAccessibleResources(extension,
+ m_dispatcher->webview_partition_id().value_or(std::string()))
// // Hosted app icons are accessible.
// // TODO(devlin): Should we incorporate this into
// // WebAccessibleResourcesInfo?
@@ -86,7 +51,7 @@ void ResourceRequestPolicyQt::OnExtensionUnloaded(const ExtensionId &extension_i
bool ResourceRequestPolicyQt::CanRequestResource(const GURL &resource_url,
blink::WebLocalFrame *frame,
ui::PageTransition transition_type,
- const base::Optional<url::Origin>& initiator_origin)
+ const absl::optional<url::Origin>& initiator_origin)
{
CHECK(resource_url.SchemeIs(kExtensionScheme));
@@ -97,7 +62,7 @@ bool ResourceRequestPolicyQt::CanRequestResource(const GURL &resource_url,
// current extension or has a devtools scheme.
GURL page_origin = url::Origin(frame->Top()->GetSecurityOrigin()).GetURL();
- GURL extension_origin = resource_url.GetOrigin();
+ GURL extension_origin = resource_url.DeprecatedGetOriginAsURL();
// We always allow loads in the following cases, regardless of web accessible
// resources:
@@ -113,7 +78,7 @@ bool ResourceRequestPolicyQt::CanRequestResource(const GURL &resource_url,
// of the frame, to account for about:blank subframes being scripted by an
// extension parent (though we'll still need the frame origin check for
// sandboxed frames).
- if (frame_url.GetOrigin() == extension_origin || page_origin == extension_origin)
+ if (frame_url.DeprecatedGetOriginAsURL() == extension_origin || page_origin == extension_origin)
return true;
if (!ui::PageTransitionIsWebTriggerable(transition_type))
@@ -167,7 +132,9 @@ bool ResourceRequestPolicyQt::CanRequestResource(const GURL &resource_url,
// Disallow loading of extension resources which are not explicitly listed
// as web or WebView accessible if the manifest version is 2 or greater.
if (!WebAccessibleResourcesInfo::IsResourceWebAccessible(extension, resource_url.path(), initiator_origin) &&
- !WebviewInfo::IsResourceWebviewAccessible(extension, m_dispatcher->webview_partition_id(), resource_url.path()))
+ !WebviewInfo::IsResourceWebviewAccessible(extension,
+ m_dispatcher->webview_partition_id().value_or(std::string()),
+ resource_url.path()))
{
std::string message = base::StringPrintf(
"Denying load of %s. Resources must be listed in the "
diff --git a/src/core/renderer/extensions/resource_request_policy_qt.h b/src/core/renderer/extensions/resource_request_policy_qt.h
index 567eefaeb..ec108519f 100644
--- a/src/core/renderer/extensions/resource_request_policy_qt.h
+++ b/src/core/renderer/extensions/resource_request_policy_qt.h
@@ -1,50 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef RESOURCEREQUESTPOLICYQT_H
#define RESOURCEREQUESTPOLICYQT_H
#include <set>
-#include "base/macros.h"
-#include "base/optional.h"
#include "extensions/common/extension_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/page_transition_types.h"
#include "url/origin.h"
@@ -76,7 +39,7 @@ public:
bool CanRequestResource(const GURL &resource_url,
blink::WebLocalFrame *frame,
ui::PageTransition transition_type,
- const base::Optional<url::Origin> &initiator_origin);
+ const absl::optional<url::Origin> &initiator_origin);
private:
Dispatcher *m_dispatcher;
@@ -84,8 +47,6 @@ private:
// The set of extension IDs with any potentially web- or webview-accessible
// resources.
std::set<ExtensionId> m_web_accessible_ids;
-
- DISALLOW_COPY_AND_ASSIGN(ResourceRequestPolicyQt);
};
} // namespace extensions
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
index 83dcf8157..d0daea8c2 100644
--- a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// This is based on chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -45,18 +9,10 @@
#include "pepper_renderer_host_factory_qt.h"
#include "qtwebenginecoreglobal_p.h"
-#include "base/memory/ptr_util.h"
-#include "chrome/renderer/pepper/pepper_flash_font_file_host.h"
-#include "chrome/renderer/pepper/pepper_uma_host.h"
-#if QT_CONFIG(webengine_printing_and_pdf)
-#include "components/pdf/renderer/pepper_pdf_host.h"
-#endif // QT_CONFIG(webengine_printing_and_pdf)
#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 {
@@ -81,31 +37,6 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateRe
if (!host_->IsValidInstance(instance))
return nullptr;
- // TODO(raymes): PDF also needs access to the FlashFontFileHost currently.
- // We should either rename PPB_FlashFont_File to PPB_FontFile_Private or get
- // rid of its use in PDF if possible.
- if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)
- || host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_PDF)) {
- switch (message.type()) {
- case PpapiHostMsg_FlashFontFile_Create::ID: {
- ppapi::proxy::SerializedFontDescription description;
- PP_PrivateFontCharset charset;
- if (ppapi::UnpackMessage<PpapiHostMsg_FlashFontFile_Create>(message, &description, &charset))
- return base::WrapUnique(new PepperFlashFontFileHost(host_, instance, resource, description, charset));
- break;
- }
- }
- }
-
-#if QT_CONFIG(webengine_printing_and_pdf)
- if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_PDF)) {
- switch (message.type()) {
- case PpapiHostMsg_PDF_Create::ID:
- return std::make_unique<pdf::PepperPDFHost>(host_, instance, resource);
- }
- }
-#endif // QT_CONFIG(webengine_printing_and_pdf)
-
// Create a default ResourceHost for this message type to suppress
// "Failed to create PPAPI resource host" console error message.
switch (message.type()) {
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
index ec3440a08..c31aa23d7 100644
--- a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef PEPPER_RENDERER_HOST_FACTORY_QT_H
#define PEPPER_RENDERER_HOST_FACTORY_QT_H
@@ -65,8 +29,6 @@ public:
private:
// Not owned by this object.
content::RendererPpapiHost* host_;
-
- DISALLOW_COPY_AND_ASSIGN(PepperRendererHostFactoryQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
index f3604d1ec..06fd4f71f 100644
--- a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
+++ b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -61,7 +25,7 @@ gin::WrapperInfo LoadablePluginPlaceholderQt::kWrapperInfo = {gin::kEmbedderNati
LoadablePluginPlaceholderQt::LoadablePluginPlaceholderQt(content::RenderFrame* render_frame,
const blink::WebPluginParams& params,
const std::string& html_data,
- const base::string16& title)
+ const std::u16string& title)
: plugins::LoadablePluginPlaceholder(render_frame, params, html_data)
{}
@@ -76,11 +40,11 @@ LoadablePluginPlaceholderQt* LoadablePluginPlaceholderQt::CreateLoadableMissingP
{
std::string template_html(ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(IDR_BLOCKED_PLUGIN_HTML));
- base::DictionaryValue values;
- values.SetString("name", "");
- values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
+ base::Value::Dict values;
+ values.Set("name", "");
+ values.Set("message", l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
- const std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
+ const std::string html_data = webui::GetI18nTemplateHtml(template_html, std::move(values));
// Will destroy itself when its WebViewPlugin is going away.
return new LoadablePluginPlaceholderQt(render_frame, params, html_data, params.mime_type.Utf16());
diff --git a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.h b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.h
index 4c3b7ec88..9b9d1bca8 100644
--- a/src/core/renderer/plugins/loadable_plugin_placeholder_qt.h
+++ b/src/core/renderer/plugins/loadable_plugin_placeholder_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -44,7 +8,6 @@
#ifndef LOADALBLE_PLUGIN_PLACEHOLDER_QT_H
#define LOADALBLE_PLUGIN_PLACEHOLDER_QT_H
-#include "base/macros.h"
#include "components/plugins/renderer/loadable_plugin_placeholder.h"
namespace QtWebEngineCore {
@@ -63,18 +26,14 @@ private:
LoadablePluginPlaceholderQt(content::RenderFrame* render_frame,
const blink::WebPluginParams& params,
const std::string& html_data,
- const base::string16& title);
+ const std::u16string& title);
~LoadablePluginPlaceholderQt() override;
// content::LoadablePluginPlaceholder overrides.
blink::WebPlugin* CreatePlugin() override;
- void OnBlockedContent(content::RenderFrame::PeripheralContentStatus status,
- bool is_same_origin) override {}
// WebViewPlugin::Delegate (via PluginPlaceholder) methods:
v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) override;
-
- DISALLOW_COPY_AND_ASSIGN(LoadablePluginPlaceholderQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.cpp b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
index beae6ecfa..f01568e65 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.cpp
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
@@ -1,69 +1,40 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2015 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.Chromium file.
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_view.h"
+#include "extensions/buildflags/buildflags.h"
#include "extensions/common/constants.h"
-#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "url/origin.h"
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "chrome/common/webui_url_constants.h"
+#include "extensions/common/constants.h"
+#include "third_party/blink/public/web/web_document.h"
+#include "extensions/renderer/guest_view/mime_handler_view/post_message_support.h"
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+#include "pdf_util_qt.h"
#include "print_web_view_helper_delegate_qt.h"
#include "web_engine_library_info.h"
namespace QtWebEngineCore {
+
PrintWebViewHelperDelegateQt::~PrintWebViewHelperDelegateQt() {}
blink::WebElement PrintWebViewHelperDelegateQt::GetPdfElement(blink::WebLocalFrame *frame)
{
- GURL url = frame->GetDocument().Url();
- if (url.SchemeIs(extensions::kExtensionScheme) && url.host() == extension_misc::kPdfExtensionId) {
- // <object> with id="plugin" is created in
- // chrome/browser/resources/pdf/pdf.js.
- auto plugin_element = frame->GetDocument().GetElementById("plugin");
- CHECK(!plugin_element.IsNull());
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (frame->Parent() && IsPdfInternalPluginAllowedOrigin(frame->Parent()->GetSecurityOrigin())) {
+ auto plugin_element = frame->GetDocument().QuerySelector("embed");
+ DCHECK(!plugin_element.IsNull());
return plugin_element;
}
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
return blink::WebElement();
}
@@ -77,7 +48,7 @@ bool PrintWebViewHelperDelegateQt::OverridePrint(blink::WebLocalFrame *frame)
return false;
}
-}
+} // namespace QtWebEngineCore
namespace printing {
// std::string PrintingContextDelegate::GetAppLocale()
diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.h b/src/core/renderer/print_web_view_helper_delegate_qt.h
index 2cbc171a6..5c7dd2431 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.h
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -46,8 +10,8 @@
#include "components/printing/renderer/print_render_frame_helper.h"
-namespace content {
-class RenderView;
+namespace blink {
+class WebLocalFrame;
}
namespace QtWebEngineCore {
@@ -62,7 +26,8 @@ public:
bool IsPrintPreviewEnabled() override;
bool OverridePrint(blink::WebLocalFrame *frame) override;
-}; // class PrintWebViewHelperDelegateQt
-}
+};
+
+} // namespace QtWebEngineCore
#endif // PRINT_WEB_VIEW_HELPER_DELEGATE_QT_H
diff --git a/src/core/renderer/render_configuration.cpp b/src/core/renderer/render_configuration.cpp
index ef9da7af7..7b35cdd48 100644
--- a/src/core/renderer/render_configuration.cpp
+++ b/src/core/renderer/render_configuration.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// based on chrome/renderer/chrome_render_thread_observer.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -43,7 +7,6 @@
// found in the LICENSE file.
#include "renderer/render_configuration.h"
-#include "user_resource_controller.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
namespace QtWebEngineCore {
@@ -53,9 +16,9 @@ bool RenderConfiguration::m_isIncognitoProcess = false;
void RenderConfiguration::RegisterMojoInterfaces(
blink::AssociatedInterfaceRegistry *associated_interfaces)
{
- associated_interfaces->AddInterface(
- base::Bind(&RenderConfiguration::OnRendererConfigurationAssociatedRequest,
- base::Unretained(this)));
+ associated_interfaces->AddInterface<qtwebengine::mojom::RendererConfiguration>(
+ base::BindRepeating(&RenderConfiguration::OnRendererConfigurationAssociatedRequest,
+ base::Unretained(this)));
}
void RenderConfiguration::UnregisterMojoInterfaces(
diff --git a/src/core/renderer/render_configuration.h b/src/core/renderer/render_configuration.h
index 138a85bdc..d9c867e02 100644
--- a/src/core/renderer/render_configuration.h
+++ b/src/core/renderer/render_configuration.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef RENDER_CONFIGURATION_H
#define RENDER_CONFIGURATION_H
@@ -71,8 +35,6 @@ private:
mojo::AssociatedReceiverSet<qtwebengine::mojom::RendererConfiguration>
m_rendererConfigurationReceivers;
-
- DISALLOW_COPY_AND_ASSIGN(RenderConfiguration);
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp
index 77d325f3c..e6489eefb 100644
--- a/src/core/renderer/render_frame_observer_qt.cpp
+++ b/src/core/renderer/render_frame_observer_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// This is based on chrome/renderer/pepper/pepper_helper.cc:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
@@ -44,14 +8,18 @@
#include "render_frame_observer_qt.h"
-#include "base/memory/ptr_util.h"
-#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h"
#include "components/web_cache/renderer/web_cache_impl.h"
#include "content/public/renderer/render_frame.h"
+#include "third_party/blink/public/web/web_document_loader.h"
+
+#if QT_CONFIG(webengine_pepper_plugins)
+#include "base/memory/ptr_util.h"
+#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "ppapi/host/ppapi_host.h"
#include "renderer/pepper/pepper_renderer_host_factory_qt.h"
+#endif
namespace QtWebEngineCore {
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
index 8803dde89..8cab3bd9a 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -1,50 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef RENDER_FRAME_OBSERVER_QT_H
#define RENDER_FRAME_OBSERVER_QT_H
#include "qtwebenginecoreglobal_p.h"
-#include "base/compiler_specific.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
-#include "ppapi/buildflags/buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
@@ -82,8 +44,6 @@ public:
}
private:
- DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt);
-
void ReadyToCommitNavigation(blink::WebDocumentLoader *) override;
bool m_isFrameDetached;
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
index 029d02c8c..eff304981 100644
--- a/src/core/renderer/user_resource_controller.cpp
+++ b/src/core/renderer/user_resource_controller.cpp
@@ -1,58 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "user_resource_controller.h"
#include "base/memory/weak_ptr.h"
-#include "base/pending_task.h"
#include "base/strings/pattern.h"
+#include "base/task/single_thread_task_runner.h"
#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_frame_observer.h"
#include "extensions/common/url_pattern.h"
-#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_script_source.h"
-#include "third_party/blink/public/web/web_view.h"
-#include "v8/include/v8.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "qtwebengine/userscript/user_script_data.h"
@@ -149,7 +108,7 @@ public:
private:
// RenderFrameObserver implementation.
void DidCommitProvisionalLoad(ui::PageTransition transition) override;
- void DidFinishDocumentLoad() override;
+ void DidDispatchDOMContentLoadedEvent() override;
void DidFinishLoad() override;
void WillDetach() override;
void OnDestruct() override;
@@ -199,7 +158,7 @@ void UserResourceController::runScripts(QtWebEngineCore::UserScriptData::Injecti
QList<uint64_t> scriptsToRun = m_frameUserScriptMap.value(globalScriptsIndex);
scriptsToRun.append(m_frameUserScriptMap.value(renderFrame));
- for (uint64_t id : qAsConst(scriptsToRun)) {
+ for (uint64_t id : std::as_const(scriptsToRun)) {
const QtWebEngineCore::UserScriptData &script = m_scripts.value(id);
if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame))
continue;
@@ -207,7 +166,7 @@ void UserResourceController::runScripts(QtWebEngineCore::UserScriptData::Injecti
continue;
blink::WebScriptSource source(blink::WebString::FromUTF8(script.source), script.url);
if (script.worldId)
- frame->ExecuteScriptInIsolatedWorld(script.worldId, source);
+ frame->ExecuteScriptInIsolatedWorld(script.worldId, source, blink::BackForwardCacheAware::kAllow); // FIXME, check
else
frame->ExecuteScript(source);
}
@@ -224,7 +183,7 @@ UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(
, m_binding(this)
, m_userResourceController(controller)
{
- render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebengine::mojom::UserResourceControllerRenderFrame>(
base::BindRepeating(&UserResourceController::RenderFrameObserverHelper::BindReceiver,
base::Unretained(this)));
}
@@ -245,28 +204,28 @@ void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad
m_runner.reset(new Runner(render_frame()->GetWebFrame(), m_userResourceController));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
+ base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(&Runner::run, m_runner->AsWeakPtr(),
QtWebEngineCore::UserScriptData::DocumentElementCreation));
}
-void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad()
+void UserResourceController::RenderFrameObserverHelper::DidDispatchDOMContentLoadedEvent()
{
// Don't run scripts if provisional load failed (DidFailProvisionalLoad
// called instead of DidCommitProvisionalLoad).
if (m_runner)
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&Runner::run, m_runner->AsWeakPtr(),
QtWebEngineCore::UserScriptData::AfterLoad),
- base::TimeDelta::FromMilliseconds(afterLoadTimeout));
+ base::Milliseconds(afterLoadTimeout));
}
void UserResourceController::RenderFrameObserverHelper::DidFinishLoad()
{
if (m_runner)
- base::ThreadTaskRunnerHandle::Get()->PostTask(
+ base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(&Runner::run, m_runner->AsWeakPtr(),
QtWebEngineCore::UserScriptData::AfterLoad));
@@ -331,10 +290,11 @@ void UserResourceController::renderFrameDestroyed(content::RenderFrame *renderFr
FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(renderFrame);
if (it == m_frameUserScriptMap.end()) // ASSERT maybe?
return;
- for (uint64_t id : qAsConst(it.value())) {
- m_scripts.remove(id);
+ if (renderFrame->IsMainFrame()) {
+ for (uint64_t id : std::as_const(it.value()))
+ m_scripts.remove(id);
}
- m_frameUserScriptMap.remove(renderFrame);
+ m_frameUserScriptMap.erase(it);
}
void UserResourceController::addScriptForFrame(const QtWebEngineCore::UserScriptData &script,
@@ -342,11 +302,12 @@ void UserResourceController::addScriptForFrame(const QtWebEngineCore::UserScript
{
FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
if (it == m_frameUserScriptMap.end())
- it = m_frameUserScriptMap.insert(frame, UserScriptSet());
+ it = m_frameUserScriptMap.insert(frame, UserScriptList());
if (!(*it).contains(script.scriptId))
(*it).append(script.scriptId);
- m_scripts.insert(script.scriptId, script);
+ if (!frame || frame->IsMainFrame())
+ m_scripts.insert(script.scriptId, script);
}
void UserResourceController::removeScriptForFrame(const QtWebEngineCore::UserScriptData &script,
@@ -357,7 +318,8 @@ void UserResourceController::removeScriptForFrame(const QtWebEngineCore::UserScr
return;
(*it).removeOne(script.scriptId);
- m_scripts.remove(script.scriptId);
+ if (!frame || frame->IsMainFrame())
+ m_scripts.remove(script.scriptId);
}
void UserResourceController::clearScriptsForFrame(content::RenderFrame *frame)
@@ -365,8 +327,10 @@ void UserResourceController::clearScriptsForFrame(content::RenderFrame *frame)
FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame);
if (it == m_frameUserScriptMap.end())
return;
- for (uint64_t id : qAsConst(it.value()))
- m_scripts.remove(id);
+ if (!frame || frame->IsMainFrame()) {
+ for (uint64_t id : std::as_const(it.value()))
+ m_scripts.remove(id);
+ }
m_frameUserScriptMap.remove(frame);
}
@@ -389,8 +353,8 @@ void UserResourceController::ClearScripts()
void UserResourceController::RegisterMojoInterfaces(
blink::AssociatedInterfaceRegistry *associated_interfaces)
{
- associated_interfaces->AddInterface(
- base::Bind(&UserResourceController::BindReceiver, base::Unretained(this)));
+ associated_interfaces->AddInterface<qtwebengine::mojom::UserResourceController>(
+ base::BindRepeating(&UserResourceController::BindReceiver, base::Unretained(this)));
}
void UserResourceController::UnregisterMojoInterfaces(
diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h
index 37e7175a4..a5dab73f1 100644
--- a/src/core/renderer/user_resource_controller.h
+++ b/src/core/renderer/user_resource_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef USER_RESOURCE_CONTROLLER_H
#define USER_RESOURCE_CONTROLLER_H
@@ -46,7 +10,7 @@
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include <QtCore/QHash>
-#include <QtCore/QSet>
+#include <QtCore/QList>
namespace blink {
class WebLocalFrame;
@@ -54,7 +18,6 @@ class WebLocalFrame;
namespace content {
class RenderFrame;
-class RenderView;
}
namespace QtWebEngineCore {
@@ -83,7 +46,6 @@ private:
void UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override;
class RenderFrameObserverHelper;
- class RenderViewObserverHelper;
void AddScript(const QtWebEngineCore::UserScriptData &data) override;
void RemoveScript(const QtWebEngineCore::UserScriptData &data) override;
@@ -91,12 +53,13 @@ private:
void runScripts(QtWebEngineCore::UserScriptData::InjectionPoint, blink::WebLocalFrame *);
- typedef QList<uint64_t> UserScriptSet;
- typedef QHash<const content::RenderFrame *, UserScriptSet> FrameUserScriptMap;
+ typedef QList<uint64_t> UserScriptList;
+ typedef QHash<const content::RenderFrame *, UserScriptList> FrameUserScriptMap;
FrameUserScriptMap m_frameUserScriptMap;
QHash<uint64_t, QtWebEngineCore::UserScriptData> m_scripts;
mojo::AssociatedReceiver<qtwebengine::mojom::UserResourceController> m_binding;
friend class RenderFrameObserverHelper;
};
-} // namespace
+
+} // namespace QtWebEngineCore
#endif // USER_RESOURCE_CONTROLLER_H
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
index c86888a2d..89b20c7d1 100644
--- a/src/core/renderer/web_channel_ipc_transport.cpp
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// 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.Chromium file.
@@ -52,11 +16,8 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "v8/include/v8.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "qtwebengine/browser/qtwebchannel.mojom.h"
-#include <QJsonDocument>
-
namespace QtWebEngineCore {
class WebChannelTransport : public gin::Wrappable<WebChannelTransport>
@@ -74,7 +35,6 @@ private:
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override;
mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportHost> m_remote;
content::RenderFrame *m_renderFrame = nullptr;
- DISALLOW_COPY_AND_ASSIGN(WebChannelTransport);
};
gin::WrapperInfo WebChannelTransport::kWrapperInfo = { gin::kEmbedderNativeGin };
@@ -88,20 +48,23 @@ void WebChannelTransport::Install(blink::WebLocalFrame *frame, uint worldId)
context = frame->MainWorldScriptContext();
else
context = frame->IsolatedWorldScriptContext(worldId);
+ if (context.IsEmpty())
+ return;
v8::Context::Scope contextScope(context);
gin::Handle<WebChannelTransport> transport = gin::CreateHandle(isolate, new WebChannelTransport);
+ if (transport.IsEmpty())
+ return;
v8::Local<v8::Object> global = context->Global();
- v8::Local<v8::Value> qtObjectValue;
v8::Local<v8::Object> qtObject;
- if (!global->Get(context, gin::StringToV8(isolate, "qt")).ToLocal(&qtObjectValue) || !qtObjectValue->IsObject()) {
- qtObject = v8::Object::New(isolate);
- global->Set(context, gin::StringToV8(isolate, "qt"), qtObject).Check();
- } else {
- qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
- }
- qtObject->Set(context, gin::StringToV8(isolate, "webChannelTransport"), transport.ToV8()).Check();
+ qtObject = v8::Object::New(isolate);
+ global->CreateDataProperty(context,
+ gin::StringToSymbol(isolate, "qt"),
+ qtObject).Check();
+ qtObject->CreateDataProperty(context,
+ gin::StringToSymbol(isolate, "webChannelTransport"),
+ transport.ToV8()).Check();
}
void WebChannelTransport::Uninstall(blink::WebLocalFrame *frame, uint worldId)
@@ -113,6 +76,8 @@ void WebChannelTransport::Uninstall(blink::WebLocalFrame *frame, uint worldId)
context = frame->MainWorldScriptContext();
else
context = frame->IsolatedWorldScriptContext(worldId);
+ if (context.IsEmpty())
+ return;
v8::Context::Scope contextScope(context);
v8::Local<v8::Object> global(context->Global());
@@ -171,7 +136,7 @@ WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame
, m_worldInitialized(false)
, m_binding(this)
{
- renderFrame->GetAssociatedInterfaceRegistry()->AddInterface(
+ renderFrame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebchannel::mojom::WebChannelTransportRender>(
base::BindRepeating(&WebChannelIPCTransport::BindReceiver, base::Unretained(this)));
}
@@ -224,17 +189,18 @@ void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t
v8::Context::Scope contextScope(context);
v8::Local<v8::Object> global(context->Global());
- v8::MaybeLocal<v8::Value> qtObjectValue(global->Get(context, gin::StringToV8(isolate, "qt")));
- if (qtObjectValue.IsEmpty() || !qtObjectValue.ToLocalChecked()->IsObject())
+ v8::Local<v8::Value> qtObjectValue;
+ if (!global->Get(context, gin::StringToV8(isolate, "qt")).ToLocal(&qtObjectValue) || !qtObjectValue->IsObject())
return;
- v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue.ToLocalChecked());
- v8::MaybeLocal<v8::Value> webChannelObjectValue(
- qtObject->Get(context, gin::StringToV8(isolate, "webChannelTransport")));
- if (webChannelObjectValue.IsEmpty() || !webChannelObjectValue.ToLocalChecked()->IsObject())
+ v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
+ v8::Local<v8::Value> webChannelObjectValue;
+ if (!qtObject->Get(context, gin::StringToV8(isolate, "webChannelTransport")).ToLocal(&webChannelObjectValue)
+ || !webChannelObjectValue->IsObject())
return;
- v8::Local<v8::Object> webChannelObject = v8::Local<v8::Object>::Cast(webChannelObjectValue.ToLocalChecked());
- v8::MaybeLocal<v8::Value> callbackValue(webChannelObject->Get(context, gin::StringToV8(isolate, "onmessage")));
- if (callbackValue.IsEmpty() || !callbackValue.ToLocalChecked()->IsFunction()) {
+ v8::Local<v8::Object> webChannelObject = v8::Local<v8::Object>::Cast(webChannelObjectValue);
+ v8::Local<v8::Value> callbackValue;
+ if (!webChannelObject->Get(context, gin::StringToV8(isolate, "onmessage")).ToLocal(&callbackValue)
+ || !callbackValue->IsFunction()) {
LOG(WARNING) << "onmessage is not a callable property of qt.webChannelTransport. Some things might not work as "
"expected.";
return;
@@ -249,7 +215,7 @@ void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t
v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
DCHECK(!wasSet.IsNothing() && wasSet.FromJust());
- v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(callbackValue.ToLocalChecked());
+ v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(callbackValue);
v8::Local<v8::Value> argv[] = { messageObject };
frame->CallFunctionEvenIfScriptDisabled(callback, webChannelObject, 1, argv);
}
diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h
index f048a26d8..95aa39850 100644
--- a/src/core/renderer/web_channel_ipc_transport.h
+++ b/src/core/renderer/web_channel_ipc_transport.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_CHANNEL_IPC_TRANSPORT_H
#define WEB_CHANNEL_IPC_TRANSPORT_H
#include "content/public/renderer/render_frame_observer.h"
-#include "services/service_manager/public/cpp/binder_registry.h"
-#include "mojo/public/cpp/bindings/associated_receiver_set.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "qtwebengine/browser/qtwebchannel.mojom.h"
diff --git a/src/core/renderer/web_engine_page_render_frame.cpp b/src/core/renderer/web_engine_page_render_frame.cpp
index e230e7fa3..1e7ac62fc 100644
--- a/src/core/renderer/web_engine_page_render_frame.cpp
+++ b/src/core/renderer/web_engine_page_render_frame.cpp
@@ -1,61 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "renderer/web_engine_page_render_frame.h"
#include "content/public/renderer/render_frame.h"
-#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
-#include "third_party/blink/public/web/web_document.h"
-#include "third_party/blink/public/web/web_element.h"
-#include "third_party/blink/public/web/web_frame.h"
+#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_frame_content_dumper.h"
-#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
namespace QtWebEngineCore {
WebEnginePageRenderFrame::WebEnginePageRenderFrame(content::RenderFrame *render_frame)
- : content::RenderFrameObserver(render_frame), m_binding(this)
+ : content::RenderFrameObserver(render_frame), m_binding(this), m_ready(false)
{
- render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
+ render_frame->GetAssociatedInterfaceRegistry()->AddInterface<qtwebenginepage::mojom::WebEnginePageRenderFrame>(
base::BindRepeating(&WebEnginePageRenderFrame::BindReceiver, base::Unretained(this)));
}
@@ -68,22 +28,30 @@ void WebEnginePageRenderFrame::BindReceiver(
void WebEnginePageRenderFrame::FetchDocumentMarkup(uint64_t requestId,
FetchDocumentMarkupCallback callback)
{
- blink::WebString markup = blink::WebFrameContentDumper::DumpAsMarkup(
- render_frame()->GetWebFrame()) ;
+ blink::WebLocalFrame *frame = render_frame()->GetWebFrame();
+ blink::WebString markup;
+ if (m_ready)
+ markup = blink::WebFrameContentDumper::DumpAsMarkup(frame);
+ else
+ markup = blink::WebString::FromUTF8("<html><head></head><body></body></html>");
std::move(callback).Run(requestId, markup.Utf8());
}
void WebEnginePageRenderFrame::FetchDocumentInnerText(uint64_t requestId,
FetchDocumentInnerTextCallback callback)
{
- blink::WebString text = blink::WebFrameContentDumper::DumpFrameTreeAsText(
- render_frame()->GetWebFrame(), std::numeric_limits<std::size_t>::max());
+ blink::WebLocalFrame *frame = render_frame()->GetWebFrame();
+ blink::WebString text;
+ if (m_ready) {
+ text = blink::WebFrameContentDumper::DumpFrameTreeAsText(
+ frame, std::numeric_limits<int32_t>::max());
+ }
std::move(callback).Run(requestId, text.Utf8());
}
void WebEnginePageRenderFrame::SetBackgroundColor(uint32_t color)
{
- render_frame()->GetWebFrame()->View()->SetBaseBackgroundColorOverride(color);
+ render_frame()->GetWebFrame()->View()->SetBaseBackgroundColorOverrideForInspector(color);
}
void WebEnginePageRenderFrame::OnDestruct()
@@ -91,4 +59,8 @@ void WebEnginePageRenderFrame::OnDestruct()
delete this;
}
+void WebEnginePageRenderFrame::DidFinishLoad()
+{
+ m_ready = true;
+}
}
diff --git a/src/core/renderer/web_engine_page_render_frame.h b/src/core/renderer/web_engine_page_render_frame.h
index 3fb4657c5..7d0e25267 100644
--- a/src/core/renderer/web_engine_page_render_frame.h
+++ b/src/core/renderer/web_engine_page_render_frame.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_ENGINE_PAGE_RENDER_FRAME_H
#define WEB_ENGINE_PAGE_RENDER_FRAME_H
@@ -63,13 +27,15 @@ private:
FetchDocumentInnerTextCallback callback) override;
void SetBackgroundColor(uint32_t color) override;
void OnDestruct() override;
+ void DidFinishLoad() override;
void
BindReceiver(mojo::PendingAssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame>
receiver);
private:
mojo::AssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> m_binding;
+ bool m_ready;
};
-} // namespace
+} // namespace QtWebEngineCore
#endif // WEB_ENGINE_PAGE_RENDER_FRAME_H
diff --git a/src/core/renderer_host/pepper/pepper_host_factory_qt.cpp b/src/core/renderer_host/pepper/pepper_host_factory_qt.cpp
deleted file mode 100644
index 6686f8b12..000000000
--- a/src/core/renderer_host/pepper/pepper_host_factory_qt.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// This is based on chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc:
-// 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.Chromium file.
-
-#include "pepper_host_factory_qt.h"
-
-#include "base/memory/ptr_util.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_isolated_file_system_message_filter.h"
-
-using ppapi::host::MessageFilterHost;
-using ppapi::host::ResourceMessageFilter;
-
-namespace QtWebEngineCore {
-
-PepperHostFactoryQt::PepperHostFactoryQt(content::BrowserPpapiHost* host)
- : host_(host)
-{
-}
-
-PepperHostFactoryQt::~PepperHostFactoryQt() {}
-
-std::unique_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 nullptr;
-
- // Permissions for the following interfaces will be checked at the
- // time of the corresponding instance's methods calls (because
- // permission check can be performed only on the UI
- // thread). Currently these interfaces are available only for
- // whitelisted apps which may not have access to the other private
- // interfaces.
- if (message.type() == PpapiHostMsg_IsolatedFileSystem_Create::ID) {
- PepperIsolatedFileSystemMessageFilter* isolated_fs_filter = PepperIsolatedFileSystemMessageFilter::Create(instance, host_);
- if (!isolated_fs_filter)
- return nullptr;
- return base::WrapUnique(
- new MessageFilterHost(host_->GetPpapiHost(), instance, resource, isolated_fs_filter));
- }
-
- return nullptr;
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/renderer_host/pepper/pepper_host_factory_qt.h b/src/core/renderer_host/pepper/pepper_host_factory_qt.h
deleted file mode 100644
index 0446cf9e3..000000000
--- a/src/core/renderer_host/pepper/pepper_host_factory_qt.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.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 std::unique_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_host/pepper/pepper_isolated_file_system_message_filter.cpp b/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp
deleted file mode 100644
index f61c06ea9..000000000
--- a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// This is based on chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc:
-// Copyright 2013 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.Chromium file.
-
-#include "pepper_isolated_file_system_message_filter.h"
-
-#include "base/macros.h"
-#include "base/task/post_task.h"
-#include "chrome/common/chrome_switches.h"
-#include "content/public/browser/browser_ppapi_host.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/render_view_host.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/host/dispatch_host_message.h"
-#include "ppapi/host/host_message_context.h"
-#include "ppapi/host/ppapi_host.h"
-#include "ppapi/proxy/ppapi_messages.h"
-#include "ppapi/shared_impl/file_system_util.h"
-#include "storage/browser/file_system/isolated_context.h"
-
-namespace QtWebEngineCore {
-
-// static
-PepperIsolatedFileSystemMessageFilter* PepperIsolatedFileSystemMessageFilter::Create(PP_Instance instance, content::BrowserPpapiHost *host)
-{
- int render_process_id;
- int unused_render_frame_id;
- if (!host->GetRenderFrameIDsForInstance(instance, &render_process_id, &unused_render_frame_id))
- return nullptr;
- return new PepperIsolatedFileSystemMessageFilter(render_process_id, host->GetPpapiHost());
-}
-
-PepperIsolatedFileSystemMessageFilter::PepperIsolatedFileSystemMessageFilter(int render_process_id,
- ppapi::host::PpapiHost *ppapi_host)
- : m_render_process_id(render_process_id),
- m_ppapi_host(ppapi_host)
-{}
-
-PepperIsolatedFileSystemMessageFilter::~PepperIsolatedFileSystemMessageFilter()
-{}
-
-scoped_refptr<base::SequencedTaskRunner> PepperIsolatedFileSystemMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message &)
-{
- // In order to reach ExtensionSystem, we need to get ProfileManager first.
- // ProfileManager lives in UI thread, so we need to do this in UI thread.
- return base::CreateSingleThreadTaskRunner({content::BrowserThread::UI});
-}
-
-int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived(const IPC::Message& msg, ppapi::host::HostMessageContext *context)
-{
- PPAPI_BEGIN_MESSAGE_MAP(PepperIsolatedFileSystemMessageFilter, msg)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_IsolatedFileSystem_BrowserOpen, OnOpenFileSystem)
- PPAPI_END_MESSAGE_MAP()
- return PP_ERROR_FAILED;
-}
-
-int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem(ppapi::host::HostMessageContext *context,
- PP_IsolatedFileSystemType_Private type)
-{
- switch (type) {
- case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID:
- break;
- case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX:
- return PP_ERROR_NOTSUPPORTED;
- case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE:
- return OpenPluginPrivateFileSystem(context);
- }
- NOTREACHED();
- context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(std::string());
- return PP_ERROR_FAILED;
-}
-
-int32_t PepperIsolatedFileSystemMessageFilter::OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext *context)
-{
- DCHECK(m_ppapi_host);
- // Only plugins with private permission can open the filesystem.
- if (!m_ppapi_host->permissions().HasPermission(ppapi::PERMISSION_PRIVATE))
- return PP_ERROR_NOACCESS;
-
- const std::string& root_name = ppapi::IsolatedFileSystemTypeToRootName(PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE);
- const std::string& fsid =
- storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
- storage::kFileSystemTypePluginPrivate, root_name, base::FilePath());
-
- // Grant full access of isolated filesystem to renderer process.
- content::ChildProcessSecurityPolicy* policy = content::ChildProcessSecurityPolicy::GetInstance();
- policy->GrantCreateReadWriteFileSystem(m_render_process_id, fsid);
-
- context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(fsid);
- return PP_OK;
-}
-
-} // namespace chrome
diff --git a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.h b/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.h
deleted file mode 100644
index 27c23d8e0..000000000
--- a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H
-#define PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H
-
-#include "base/macros.h"
-#include "ppapi/c/pp_instance.h"
-#include "ppapi/c/pp_resource.h"
-#include "ppapi/c/private/ppb_isolated_file_system_private.h"
-#include "ppapi/host/resource_host.h"
-#include "ppapi/host/resource_message_filter.h"
-
-namespace content {
-class BrowserPpapiHost;
-}
-
-namespace ppapi {
-namespace host {
-struct HostMessageContext;
-} // namespace host
-} // namespace ppapi
-
-namespace QtWebEngineCore {
-
-class PepperIsolatedFileSystemMessageFilter : public ppapi::host::ResourceMessageFilter {
-public:
- static PepperIsolatedFileSystemMessageFilter *Create(PP_Instance instance, content::BrowserPpapiHost *host);
-
- // ppapi::host::ResourceMessageFilter implementation.
- scoped_refptr<base::SequencedTaskRunner> OverrideTaskRunnerForMessage(const IPC::Message &msg) override;
- int32_t OnResourceMessageReceived(const IPC::Message &msg, ppapi::host::HostMessageContext *context) override;
-
-private:
- PepperIsolatedFileSystemMessageFilter(int render_process_id, ppapi::host::PpapiHost *ppapi_host);
-
- ~PepperIsolatedFileSystemMessageFilter() override;
-
-
- int32_t OnOpenFileSystem(ppapi::host::HostMessageContext *context, PP_IsolatedFileSystemType_Private type);
- int32_t OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext *context);
-
- const int m_render_process_id;
-
- // Not owned by this object.
- ppapi::host::PpapiHost* m_ppapi_host;
-
- DISALLOW_COPY_AND_ASSIGN(PepperIsolatedFileSystemMessageFilter);
-};
-
-} // namespace QtWebEngineCore
-
-#endif // PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H
diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp
index 387df9452..f2a00fc72 100644
--- a/src/core/renderer_host/user_resource_controller_host.cpp
+++ b/src/core/renderer_host/user_resource_controller_host.cpp
@@ -1,52 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "user_resource_controller_host.h"
#include "type_conversion.h"
#include "web_contents_adapter.h"
+
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
+#include "ipc/ipc_channel_proxy.h"
#include "qtwebengine/userscript/userscript.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -151,7 +117,7 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont
m_perContentsScripts.insert(contents, currentScripts);
}
}
- GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame())
+ GetUserResourceControllerRenderFrame(contents->GetPrimaryMainFrame())
->AddScript(script.data());
}
}
@@ -174,7 +140,7 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC
QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script);
if (it == list.end())
return false;
- GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame())
+ GetUserResourceControllerRenderFrame(contents->GetPrimaryMainFrame())
->RemoveScript((*it).data());
list.erase(it);
}
@@ -193,7 +159,7 @@ void UserResourceControllerHost::clearAllScripts(WebContentsAdapter *adapter)
m_perContentsScripts.remove(contents);
mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame>
userResourceController;
- GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame())
+ GetUserResourceControllerRenderFrame(contents->GetPrimaryMainFrame())
->ClearScripts();
}
}
@@ -218,7 +184,7 @@ void UserResourceControllerHost::renderProcessStartedWithHost(content::RenderPro
auto userResourceController = new UserResourceControllerRemote;
renderer->GetChannel()->GetRemoteAssociatedInterface(userResourceController);
m_observedProcesses.insert(renderer, userResourceController);
- for (const UserScript &script : qAsConst(m_profileWideScripts)) {
+ for (const UserScript &script : std::as_const(m_profileWideScripts)) {
(*userResourceController)->AddScript(script.data());
}
}
diff --git a/src/core/renderer_host/user_resource_controller_host.h b/src/core/renderer_host/user_resource_controller_host.h
index a88264f2d..eb4404879 100644
--- a/src/core/renderer_host/user_resource_controller_host.h
+++ b/src/core/renderer_host/user_resource_controller_host.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -83,7 +47,7 @@ using UserResourceControllerRemote = mojo::AssociatedRemote<qtwebengine::mojom::
using UserResourceControllerRenderFrameRemote = mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame>;
class WebContentsAdapter;
-class Q_WEBENGINECORE_PRIVATE_EXPORT UserResourceControllerHost
+class Q_WEBENGINECORE_EXPORT UserResourceControllerHost
{
public:
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
index 43c3347bc..0824ed56d 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_channel_ipc_transport_host.h"
@@ -60,23 +24,15 @@ inline QDebug operator<<(QDebug stream, content::RenderFrameHost *frame)
return stream << "frame " << frame->GetRoutingID() << " in process " << frame->GetProcess()->GetID();
}
-template<class T>
-inline QDebug operator<<(QDebug stream, const base::Optional<T> &opt)
-{
- if (opt)
- return stream << *opt;
- else
- return stream << "nullopt";
-}
-
WebChannelIPCTransportHost::WebChannelIPCTransportHost(content::WebContents *contents, uint worldId, QObject *parent)
: QWebChannelAbstractTransport(parent)
, content::WebContentsObserver(contents)
, m_worldId(worldId)
, m_receiver(contents, this)
{
- for (content::RenderFrameHost *frame : contents->GetAllFrames())
- setWorldId(frame, worldId);
+ contents->ForEachRenderFrameHost([this, worldId](content::RenderFrameHost *frame) {
+ setWorldId(frame, worldId);
+ });
}
WebChannelIPCTransportHost::~WebChannelIPCTransportHost()
@@ -93,7 +49,7 @@ void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
{
QJsonDocument doc(message);
QByteArray json = doc.toJson(QJsonDocument::Compact);
- content::RenderFrameHost *frame = web_contents()->GetMainFrame();
+ content::RenderFrameHost *frame = web_contents()->GetPrimaryMainFrame();
qCDebug(log).nospace() << "sending webchannel message to " << frame << ": " << doc;
GetWebChannelIPCTransportRemote(frame)->DispatchWebChannelMessage(
std::vector<uint8_t>(json.begin(), json.end()), m_worldId);
@@ -103,8 +59,9 @@ void WebChannelIPCTransportHost::setWorldId(uint32_t worldId)
{
if (m_worldId == worldId)
return;
- for (content::RenderFrameHost *frame : web_contents()->GetAllFrames())
- setWorldId(frame, worldId);
+ web_contents()->ForEachRenderFrameHost([this, worldId](content::RenderFrameHost *frame) {
+ setWorldId(frame, worldId);
+ });
m_worldId = worldId;
}
@@ -118,16 +75,16 @@ void WebChannelIPCTransportHost::setWorldId(content::RenderFrameHost *frame, uin
void WebChannelIPCTransportHost::resetWorldId()
{
- for (content::RenderFrameHost *frame : web_contents()->GetAllFrames()) {
+ web_contents()->ForEachRenderFrameHost([this] (content::RenderFrameHost *frame) {
if (!frame->IsRenderFrameLive())
return;
GetWebChannelIPCTransportRemote(frame)->ResetWorldId();
- }
+ });
}
void WebChannelIPCTransportHost::DispatchWebChannelMessage(const std::vector<uint8_t> &json)
{
- content::RenderFrameHost *frame = web_contents()->GetMainFrame();
+ content::RenderFrameHost *frame = web_contents()->GetPrimaryMainFrame();
if (m_receiver.GetCurrentTargetFrame() != frame) {
return;
@@ -155,6 +112,14 @@ void WebChannelIPCTransportHost::RenderFrameDeleted(content::RenderFrameHost *rf
m_renderFrames.erase(rfh);
}
+void WebChannelIPCTransportHost::BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportHost> receiver,
+ content::RenderFrameHost *rfh)
+{
+ m_receiver.Bind(rfh, std::move(receiver));
+}
+
+
const mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> &
WebChannelIPCTransportHost::GetWebChannelIPCTransportRemote(content::RenderFrameHost *rfh)
{
diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h
index 794238667..9e003c222 100644
--- a/src/core/renderer_host/web_channel_ipc_transport_host.h
+++ b/src/core/renderer_host/web_channel_ipc_transport_host.h
@@ -1,49 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_CHANNEL_IPC_TRANSPORT_H
#define WEB_CHANNEL_IPC_TRANSPORT_H
#include "qtwebenginecoreglobal.h"
+#include "content/public/browser/render_frame_host_receiver_set.h"
#include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_receiver_set.h"
#include "qtwebengine/browser/qtwebchannel.mojom.h"
#include <QWebChannelAbstractTransport>
@@ -68,6 +32,10 @@ public:
// QWebChannelAbstractTransport
void sendMessage(const QJsonObject &message) override;
+ void BindReceiver(
+ mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportHost> receiver,
+ content::RenderFrameHost *rfh);
+
private:
void setWorldId(content::RenderFrameHost *frame, uint32_t worldId);
void resetWorldId();
@@ -85,7 +53,7 @@ private:
// Empty only during construction/destruction. Synchronized to all the
// WebChannelIPCTransports/RenderFrames in the observed WebContents.
uint32_t m_worldId;
- content::WebContentsFrameReceiverSet<qtwebchannel::mojom::WebChannelTransportHost> m_receiver;
+ content::RenderFrameHostReceiverSet<qtwebchannel::mojom::WebChannelTransportHost> m_receiver;
std::map<content::RenderFrameHost *,
mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender>>
m_renderFrames;
diff --git a/src/core/renderer_host/web_engine_page_host.cpp b/src/core/renderer_host/web_engine_page_host.cpp
index 36907ef5a..ea9b363ea 100644
--- a/src/core/renderer_host/web_engine_page_host.cpp
+++ b/src/core/renderer_host/web_engine_page_host.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_engine_page_host.h"
@@ -57,7 +21,7 @@ WebEnginePageHost::WebEnginePageHost(content::WebContents *webContents,
void WebEnginePageHost::FetchDocumentMarkup(uint64_t requestId)
{
- auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetPrimaryMainFrame());
remote->FetchDocumentMarkup(
requestId,
base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentMarkup, base::Unretained(this)));
@@ -65,7 +29,7 @@ void WebEnginePageHost::FetchDocumentMarkup(uint64_t requestId)
void WebEnginePageHost::FetchDocumentInnerText(uint64_t requestId)
{
- auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetPrimaryMainFrame());
remote->FetchDocumentInnerText(requestId,
base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentInnerText,
base::Unretained(this)));
@@ -89,7 +53,7 @@ void WebEnginePageHost::RenderFrameDeleted(content::RenderFrameHost *render_fram
void WebEnginePageHost::SetBackgroundColor(uint32_t color)
{
- auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame());
+ auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetPrimaryMainFrame());
remote->SetBackgroundColor(color);
}
diff --git a/src/core/renderer_host/web_engine_page_host.h b/src/core/renderer_host/web_engine_page_host.h
index f305d22ea..20b9145b2 100644
--- a/src/core/renderer_host/web_engine_page_host.h
+++ b/src/core/renderer_host/web_engine_page_host.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_ENGINE_PAGE_HOST_H
#define WEB_ENGINE_PAGE_HOST_H
diff --git a/src/core/request_controller.h b/src/core/request_controller.h
index ffcf9edac..8008b2edb 100644
--- a/src/core/request_controller.h
+++ b/src/core/request_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef REQUEST_CONTROLLER_H
#define REQUEST_CONTROLLER_H
diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp
index 4e814a806..693d1291f 100644
--- a/src/core/resource_bundle_qt.cpp
+++ b/src/core/resource_bundle_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "base/command_line.h"
#include "base/files/file_util.h"
@@ -51,7 +15,7 @@
#include "web_engine_library_info.h"
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
#include "base/posix/global_descriptors.h"
#include "global_descriptors_qt.h"
#endif
@@ -61,10 +25,10 @@ namespace ui {
void ResourceBundle::LoadCommonResources()
{
// We repacked the resources we need and installed them. now let chromium mmap that file.
- AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_100P_PAK), SCALE_FACTOR_100P);
- AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_200P_PAK), SCALE_FACTOR_200P);
- AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_PAK), SCALE_FACTOR_NONE);
- AddOptionalDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_DEVTOOLS_PAK), SCALE_FACTOR_NONE);
+ AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_100P_PAK), ui::k100Percent);
+ AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_200P_PAK), ui::k200Percent);
+ AddDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_PAK), ui::kScaleFactorNone);
+ AddOptionalDataPackFromPath(WebEngineLibraryInfo::getPath(QT_RESOURCES_DEVTOOLS_PAK), ui::kScaleFactorNone);
}
gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id)
@@ -75,7 +39,7 @@ gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id)
// static
bool ResourceBundle::LocaleDataPakExists(const std::string& locale)
{
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
base::CommandLine *parsed_command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = parsed_command_line->GetSwitchValueASCII(switches::kProcessType);
bool no_sandbox = parsed_command_line->HasSwitch(sandbox::policy::switches::kNoSandbox);
@@ -100,12 +64,12 @@ std::string ResourceBundle::LoadLocaleResources(const std::string &pref_locale,
std::string app_locale = l10n_util::GetApplicationLocale(pref_locale, false /* set_icu_locale */);
-#if defined(OS_LINUX)
+#if BUILDFLAG(IS_LINUX)
int locale_fd = base::GlobalDescriptors::GetInstance()->MaybeGet(kWebEngineLocale);
if (locale_fd > -1) {
- std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P));
+ std::unique_ptr<DataPack> data_pack(new DataPack(ui::k100Percent));
data_pack->LoadFromFile(base::File(locale_fd));
- locale_resources_data_.reset(data_pack.release());
+ locale_resources_data_ = std::move(data_pack);
return app_locale;
}
#endif
@@ -120,7 +84,7 @@ std::string ResourceBundle::LoadLocaleResources(const std::string &pref_locale,
return std::string();
}
- std::unique_ptr<DataPack> data_pack(new DataPack(SCALE_FACTOR_100P));
+ std::unique_ptr<DataPack> data_pack(new DataPack(ui::k100Percent));
if (!data_pack->LoadFromPath(locale_file_path)) {
UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError",
logging::GetLastSystemErrorCode(), 16000);
@@ -129,7 +93,7 @@ std::string ResourceBundle::LoadLocaleResources(const std::string &pref_locale,
return std::string();
}
- locale_resources_data_.reset(data_pack.release());
+ locale_resources_data_ = std::move(data_pack);
return app_locale;
}
diff --git a/src/core/resource_context_qt.cpp b/src/core/resource_context_qt.cpp
deleted file mode 100644
index 79c105956..000000000
--- a/src/core/resource_context_qt.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "resource_context_qt.h"
-
-namespace QtWebEngineCore {
-
-ResourceContextQt::ResourceContextQt(ProfileIODataQt *io_data)
- : m_io_data(io_data)
-{
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/resource_context_qt.h b/src/core/resource_context_qt.h
deleted file mode 100644
index efd3d2e7e..000000000
--- a/src/core/resource_context_qt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef RESOURCE_CONTEXT_QT_H
-#define RESOURCE_CONTEXT_QT_H
-
-#include "content/public/browser/resource_context.h"
-
-namespace QtWebEngineCore {
-
-class ProfileIODataQt;
-
-class ResourceContextQt : public content::ResourceContext
-{
-public:
- ResourceContextQt(ProfileIODataQt *io_data);
-private:
- friend class ProfileIODataQt;
- ProfileIODataQt* m_io_data;
- DISALLOW_COPY_AND_ASSIGN(ResourceContextQt);
-};
-
-} // namespace QtWebEngineCore
-
-#endif // RESOURCE_CONTEXT_QT_H
diff --git a/src/core/sandbox_win.cpp b/src/core/sandbox_win.cpp
index 01538d318..bc70bced7 100644
--- a/src/core/sandbox_win.cpp
+++ b/src/core/sandbox_win.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtwebenginecoreglobal_p.h"
#include "sandbox/win/src/process_mitigations.h"
@@ -47,7 +11,7 @@
#endif
namespace QtWebEngineSandbox {
-// A duplicate of the function by same name in startup_helper_win.cc
+// A duplicate of the function by same name in sandbox_helper_win.cc
static void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo *info)
{
info->broker_services = sandbox::SandboxFactory::GetBrokerServices();
@@ -55,7 +19,7 @@ static void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo *info)
info->target_services = sandbox::SandboxFactory::GetTargetServices();
} else {
// Ensure the proper mitigations are enforced for the browser process.
- sandbox::ApplyProcessMitigationsToCurrentProcess(
+ info->broker_services->RatchetDownSecurityMitigations(
sandbox::MITIGATION_DEP | sandbox::MITIGATION_DEP_NO_ATL_THUNK |
sandbox::MITIGATION_HARDEN_TOKEN_IL_POLICY);
// Note: these mitigations are "post-startup". Some mitigations that need
diff --git a/src/core/select_file_dialog_factory_qt.cpp b/src/core/select_file_dialog_factory_qt.cpp
index baad07b24..1f897a805 100644
--- a/src/core/select_file_dialog_factory_qt.cpp
+++ b/src/core/select_file_dialog_factory_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "select_file_dialog_factory_qt.h"
@@ -98,17 +62,16 @@ public:
// ui::SelectFileDialog implementation:
bool IsRunning(gfx::NativeWindow) const override;
void ListenerDestroyed() override;
- void SelectFileImpl(Type type, const base::string16 &title, const base::FilePath &default_path,
+ void SelectFileImpl(Type type, const std::u16string &title, const base::FilePath &default_path,
const FileTypeInfo *file_types, int file_type_index,
const base::FilePath::StringType &default_extension,
- gfx::NativeWindow owning_window, void *params) override;
+ gfx::NativeWindow owning_window, void *params, const GURL *) override;
+
bool HasMultipleFileTypeChoicesImpl() override;
private:
WebContentsAdapterClient *m_client;
QSharedPointer<FilePickerController> m_filePickerController;
-
- DISALLOW_COPY_AND_ASSIGN(SelectFileDialogQt);
};
SelectFileDialogQt::SelectFileDialogQt(Listener *listener,
@@ -139,17 +102,18 @@ extern FilePickerController *createFilePickerController(FilePickerController::Fi
const QStringList &acceptedMimeTypes,
QObject *parent = nullptr);
-void SelectFileDialogQt::SelectFileImpl(Type type, const base::string16 &title,
+void SelectFileDialogQt::SelectFileImpl(Type type, const std::u16string &title,
const base::FilePath &default_path,
const FileTypeInfo *file_types, int file_type_index,
const base::FilePath::StringType &default_extension,
- gfx::NativeWindow owning_window, void *params)
+ gfx::NativeWindow owning_window, void *params, const GURL *caller)
{
Q_UNUSED(title);
Q_UNUSED(file_type_index);
Q_UNUSED(default_extension);
Q_UNUSED(owning_window);
Q_UNUSED(params);
+ Q_UNUSED(caller);
QStringList acceptedSuffixes;
if (file_types) {
@@ -173,7 +137,7 @@ SelectFileDialogFactoryQt::Create(ui::SelectFileDialog::Listener *listener,
std::unique_ptr<ui::SelectFilePolicy> policy)
{
content::WebContents *webContents =
- static_cast<SelectFilePolicyQt *>(policy.get())->webContents();
+ static_cast<SelectFilePolicyQt *>(policy.get())->webContents()->GetOutermostWebContents();
WebContentsAdapterClient *client =
WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(webContents)->GetView())
->client();
diff --git a/src/core/select_file_dialog_factory_qt.h b/src/core/select_file_dialog_factory_qt.h
index 572bf217f..8036995f1 100644
--- a/src/core/select_file_dialog_factory_qt.h
+++ b/src/core/select_file_dialog_factory_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef SELECT_FILE_DIALOG_FACTORY_QT_H_
#define SELECT_FILE_DIALOG_FACTORY_QT_H_
@@ -63,8 +27,6 @@ public:
private:
content::WebContents *m_webContents;
-
- DISALLOW_COPY_AND_ASSIGN(SelectFilePolicyQt);
};
// Implements a file Open / Save dialog for File System Access API.
@@ -77,9 +39,6 @@ public:
// Overridden from ui::SelectFileDialogFactory:
ui::SelectFileDialog *Create(ui::SelectFileDialog::Listener *listener,
std::unique_ptr<ui::SelectFilePolicy> policy) override;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(SelectFileDialogFactoryQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/tools/CMakeLists.txt b/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
index 63cb234d6..5e8a1de14 100644
--- a/src/core/tools/CMakeLists.txt
+++ b/src/core/tools/qwebengine_convert_dict/CMakeLists.txt
@@ -1,25 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
-##
-# WEBENGINECORE DICT CONVERT TOOL
-##
-
-if(QT_FEATURE_webengine_spellchecker)
+if(QT_FEATURE_webengine_spellchecker AND NOT CMAKE_CROSSCOMPILING)
qt_get_tool_target_name(dict_target_name qwebengine_convert_dict)
qt_internal_add_tool(${dict_target_name}
TARGET_DESCRIPTION "QtWebEngine Dictionary Conversion Tool"
INSTALL_DIR ${INSTALL_LIBEXECDIR}
TOOLS_TARGET WebEngineCore
SOURCES main.cpp
+ INCLUDE_DIRECTORIES
+ ../../../3rdparty/chromium/third_party/abseil-cpp
)
- qt_internal_return_unless_building_tools()
+ if(COMMAND qt_internal_return_unless_building_tools)
+ qt_internal_return_unless_building_tools()
+ endif()
qt_skip_warnings_are_errors(${dict_target_name})
add_dependencies(${dict_target_name} WebEngineCore)
qt_internal_extend_target(${dict_target_name} CONDITION WIN32
- DEFINES WIN32_LEAN_AND_MEAN NOMINMAX
+ DEFINES WIN32_LEAN_AND_MEAN
)
qt_internal_extend_target(${dict_target_name} CONDITION GCC OR CLANG
COMPILE_OPTIONS -Wno-unused-parameter
)
+ set_target_properties(${dict_target_name} PROPERTIES CXX_STANDARD 20)
if(NOT QT_FEATURE_webengine_system_icu AND QT_WILL_INSTALL)
# tool can be called durig build so copy icu file
get_target_property(icuFile WebEngineCore ICUDTL_FILE)
diff --git a/src/core/tools/main.cpp b/src/core/tools/qwebengine_convert_dict/main.cpp
index a977fc22d..a82947ddc 100644
--- a/src/core/tools/main.cpp
+++ b/src/core/tools/qwebengine_convert_dict/main.cpp
@@ -7,8 +7,7 @@
** Modified work:
** Copyright (C) 2016 The Qt Company Ltd.
**
-** Use of this source code is governed by a BSD-style license that can be
-** found in the LICENSE.Chromium file.
+** SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
**
** This tool converts Hunspell .aff/.dic pairs to a combined binary dictionary
** format (.bdic). This format is more compact, and can be more efficiently
@@ -48,13 +47,16 @@ inline base::FilePath toFilePath(const QString &str)
return base::FilePath(toFilePathString(str));
}
-inline QString toQt(const base::string16 &string)
+#if defined(Q_OS_WIN)
+inline QString toQt(const std::wstring &string)
{
-#if defined(OS_WIN)
return QString::fromStdWString(string);
-#else
- return QString::fromUtf16(reinterpret_cast<const char16_t *>(string.data()), string.size());
+}
#endif
+
+inline QString toQt(const std::u16string &string)
+{
+ return QString::fromStdU16String(string);
}
inline QString toQt(const std::string &string)
@@ -109,7 +111,7 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
}
base::span<const int> expectedAffixes(org_words[i].second);
- base::span<const int> actualAffixes(affix_ids, affix_matches);
+ base::span<const int> actualAffixes(affix_ids, (size_t)affix_matches);
if (!std::equal(expectedAffixes.begin(), expectedAffixes.end(),
actualAffixes.begin(), actualAffixes.end(),
@@ -126,7 +128,7 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
return true;
}
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
QString frameworkIcuDataPath()
{
return QLibraryInfo::location(QLibraryInfo::LibrariesPath) +
@@ -166,7 +168,7 @@ int main(int argc, char *argv[])
icuDataDir = icuPossibleEnvDataDir;
icuDataDirFound = true;
}
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
// In a macOS Qt framework build, the resources are inside the QtWebEngineCore framework
// Resources directory, rather than in the Qt install location.
else if (QFileInfo::exists(frameworkIcuDataPath())) {
@@ -194,7 +196,6 @@ int main(int argc, char *argv[])
}
#endif // USE_ICU_FILE
- base::AtExitManager exit_manager;
base::i18n::InitializeICU();
base::FilePath file_in_path = toFilePath(argv[1]);
diff --git a/src/core/tools/webenginedriver/CMakeLists.txt b/src/core/tools/webenginedriver/CMakeLists.txt
new file mode 100644
index 000000000..b20311980
--- /dev/null
+++ b/src/core/tools/webenginedriver/CMakeLists.txt
@@ -0,0 +1,57 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(WIN32)
+ set(WEBENGINEDRIVER_EXECUTABLE webenginedriver.exe)
+else()
+ set(WEBENGINEDRIVER_EXECUTABLE webenginedriver)
+endif()
+set(WEBENGINEDRIVER_EXECUTABLE ${WEBENGINEDRIVER_EXECUTABLE} PARENT_SCOPE)
+
+if(QT_FEATURE_webenginedriver)
+ get_install_config(config)
+ get_architectures(archs)
+ list(GET archs 0 arch)
+
+ ##
+ # DOCS
+ ##
+ add_code_attributions_target(
+ TARGET generate_webenginedriver_attributions
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/webenginedriver_attributions.qdoc
+ GN_TARGET //chrome/test/chromedriver:chromedriver_server
+ EXTRA_THIRD_PARTY_DIRS
+ third_party/selenium-atoms/sizzle
+ third_party/selenium-atoms/wgxpath
+ third_party/selenium-atoms/closure-lib
+ FILE_TEMPLATE ../../doc/about_credits.tmpl
+ ENTRY_TEMPLATE ../../doc/about_credits_entry.tmpl
+ BUILDDIR ${buildDir}/${config}/${arch}
+ )
+ add_dependencies(generate_webenginedriver_attributions run_core_GnDone)
+ add_dependencies(prepare_docs_WebEngineCore generate_webenginedriver_attributions)
+
+ ##
+ # INSTALL
+ ##
+ install(
+ PROGRAMS ${buildDir}/${config}/${arch}/${WEBENGINEDRIVER_EXECUTABLE}
+ CONFIGURATIONS ${config}
+ RUNTIME DESTINATION "${INSTALL_LIBEXECDIR}"
+ )
+ if(NOT QT_WILL_INSTALL)
+ add_custom_target(copy-webenginedriver
+ ALL
+ DEPENDS ${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${WEBENGINEDRIVER_EXECUTABLE}
+ )
+ add_custom_command(
+ OUTPUT ${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${WEBENGINEDRIVER_EXECUTABLE}
+ COMMAND ${CMAKE_COMMAND} -E copy ${buildDir}/${config}/${arch}/${WEBENGINEDRIVER_EXECUTABLE}
+ ${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}
+ DEPENDS
+ WebEngineCore
+ ${buildDir}/${config}/${arch}/${WEBENGINEDRIVER_EXECUTABLE}
+ USES_TERMINAL
+ )
+ endif()
+endif()
diff --git a/src/core/touch_handle_drawable_client.h b/src/core/touch_handle_drawable_client.h
index d7db78f02..ddfaa9f57 100644
--- a/src/core/touch_handle_drawable_client.h
+++ b/src/core/touch_handle_drawable_client.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef TOUCH_HANDLE_DRAWABLE_CLIENT_H
#define TOUCH_HANDLE_DRAWABLE_CLIENT_H
@@ -45,9 +9,9 @@
namespace QtWebEngineCore {
-class Q_WEBENGINECORE_PRIVATE_EXPORT TouchHandleDrawableClient {
+class Q_WEBENGINECORE_EXPORT TouchHandleDrawableDelegate {
public:
- virtual ~TouchHandleDrawableClient() { }
+ virtual ~TouchHandleDrawableDelegate() { }
virtual void setImage(int orientation) = 0;
virtual void setBounds(const QRect &bounds) = 0;
diff --git a/src/core/touch_handle_drawable_qt.cpp b/src/core/touch_handle_drawable_qt.cpp
index 66b1cf40e..1e979fa03 100644
--- a/src/core/touch_handle_drawable_qt.cpp
+++ b/src/core/touch_handle_drawable_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -49,7 +13,6 @@
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
-#include "ui/gfx/image/image.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/resources/grit/ui_resources.h"
@@ -68,27 +31,6 @@ const int kSelectionHandlePadding = 0;
// Epsilon value used to compare float values to zero.
const float kEpsilon = 1e-8f;
-// Returns the appropriate handle image based on the handle orientation.
-gfx::Image* GetHandleImage(ui::TouchHandleOrientation orientation)
-{
- int resource_id = 0;
- switch (orientation) {
- case ui::TouchHandleOrientation::LEFT:
- resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT;
- break;
- case ui::TouchHandleOrientation::CENTER:
- resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER;
- break;
- case ui::TouchHandleOrientation::RIGHT:
- resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT;
- break;
- case ui::TouchHandleOrientation::UNDEFINED:
- NOTREACHED() << "Invalid touch handle bound type.";
- return nullptr;
- };
- return &ui::ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
-}
-
bool IsNearlyZero(float value)
{
return std::abs(value) < kEpsilon;
@@ -96,21 +38,12 @@ bool IsNearlyZero(float value)
} // namespace
-TouchHandleDrawableQt::TouchHandleDrawableQt(RenderWidgetHostViewQt *rwhv)
- : m_rwhv(rwhv)
+TouchHandleDrawableQt::TouchHandleDrawableQt(TouchHandleDrawableDelegate *delegate)
+ : m_delegate(delegate)
, m_enabled(false)
, m_alpha(0)
, m_orientation(ui::TouchHandleOrientation::UNDEFINED)
{
- QMap<int, QImage> images;
- for (int orientation = 0; orientation < static_cast<int>(ui::TouchHandleOrientation::UNDEFINED); ++orientation) {
- gfx::Image* image = GetHandleImage(static_cast<ui::TouchHandleOrientation>(orientation));
- images.insert(orientation, toQImage(image->AsBitmap()));
- }
-
- Q_ASSERT(m_rwhv);
- Q_ASSERT(m_rwhv->adapterClient());
- m_client.reset(m_rwhv->adapterClient()->createTouchHandle(images));
}
TouchHandleDrawableQt::~TouchHandleDrawableQt()
@@ -119,12 +52,12 @@ TouchHandleDrawableQt::~TouchHandleDrawableQt()
void TouchHandleDrawableQt::UpdateBounds()
{
- if (!m_client)
+ if (!m_delegate)
return;
gfx::RectF newBounds = m_relativeBounds;
newBounds.Offset(m_originPosition.x(), m_originPosition.y());
- m_client->setBounds(toQt(gfx::ToEnclosingRect(newBounds)));
+ m_delegate->setBounds(toQt(gfx::ToEnclosingRect(newBounds)));
}
bool TouchHandleDrawableQt::IsVisible() const
@@ -134,19 +67,19 @@ bool TouchHandleDrawableQt::IsVisible() const
void TouchHandleDrawableQt::SetEnabled(bool enabled)
{
- if (!m_client)
+ if (!m_delegate)
return;
if (enabled == m_enabled)
return;
m_enabled = enabled;
- m_client->setVisible(enabled);
+ m_delegate->setVisible(enabled);
}
void TouchHandleDrawableQt::SetOrientation(ui::TouchHandleOrientation orientation, bool mirror_vertical, bool mirror_horizontal)
{
- if (!m_client)
+ if (!m_delegate)
return;
// TODO: Implement adaptive handle orientation logic
@@ -157,7 +90,7 @@ void TouchHandleDrawableQt::SetOrientation(ui::TouchHandleOrientation orientatio
return;
m_orientation = orientation;
gfx::Image* image = GetHandleImage(orientation);
- m_client->setImage(static_cast<int>(orientation));
+ m_delegate->setImage(static_cast<int>(orientation));
// Calculate the relative bounds.
gfx::Size image_size = image->Size();
@@ -178,15 +111,15 @@ void TouchHandleDrawableQt::SetOrigin(const gfx::PointF& position)
void TouchHandleDrawableQt::SetAlpha(float alpha)
{
- if (!m_client)
+ if (!m_delegate)
return;
if (alpha == m_alpha)
return;
m_alpha = alpha;
- m_client->setOpacity(m_alpha);
- m_client->setVisible(IsVisible());
+ m_delegate->setOpacity(m_alpha);
+ m_delegate->setVisible(IsVisible());
}
gfx::RectF TouchHandleDrawableQt::GetVisibleBounds() const
@@ -195,10 +128,11 @@ gfx::RectF TouchHandleDrawableQt::GetVisibleBounds() const
bounds.Offset(m_originPosition.x(), m_originPosition.y());
gfx::RectF visibleBounds(bounds);
- visibleBounds.Inset(kSelectionHandlePadding,
- kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset,
- kSelectionHandlePadding,
- kSelectionHandlePadding);
+ visibleBounds.Inset(gfx::InsetsF::TLBR(
+ kSelectionHandlePadding,
+ kSelectionHandlePadding + kSelectionHandleVerticalVisualOffset,
+ kSelectionHandlePadding,
+ kSelectionHandlePadding));
return visibleBounds;
}
@@ -208,4 +142,25 @@ float TouchHandleDrawableQt::GetDrawableHorizontalPaddingRatio() const
return 0.0;
}
+// Returns the appropriate handle image based on the handle orientation.
+gfx::Image *TouchHandleDrawableQt::GetHandleImage(ui::TouchHandleOrientation orientation)
+{
+ int resource_id = 0;
+ switch (orientation) {
+ case ui::TouchHandleOrientation::LEFT:
+ resource_id = IDR_TEXT_SELECTION_HANDLE_LEFT;
+ break;
+ case ui::TouchHandleOrientation::CENTER:
+ resource_id = IDR_TEXT_SELECTION_HANDLE_CENTER;
+ break;
+ case ui::TouchHandleOrientation::RIGHT:
+ resource_id = IDR_TEXT_SELECTION_HANDLE_RIGHT;
+ break;
+ case ui::TouchHandleOrientation::UNDEFINED:
+ NOTREACHED() << "Invalid touch handle bound type.";
+ return nullptr;
+ };
+ return &ui::ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/touch_handle_drawable_qt.h b/src/core/touch_handle_drawable_qt.h
index 46fa217b7..1738e68e9 100644
--- a/src/core/touch_handle_drawable_qt.h
+++ b/src/core/touch_handle_drawable_qt.h
@@ -1,60 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef TOUCH_HANDLE_DRAWABLE_QT_H
#define TOUCH_HANDLE_DRAWABLE_QT_H
#include "ui/touch_selection/touch_handle.h"
#include "ui/touch_selection/touch_handle_orientation.h"
+#include "ui/gfx/image/image.h"
#include <QtCore/QScopedPointer>
namespace QtWebEngineCore {
-class RenderWidgetHostViewQt;
-class TouchHandleDrawableClient;
+class TouchHandleDrawableDelegate;
class TouchHandleDrawableQt : public ui::TouchHandleDrawable
{
public:
- explicit TouchHandleDrawableQt(RenderWidgetHostViewQt *rwhv);
+ explicit TouchHandleDrawableQt(TouchHandleDrawableDelegate *delegate);
~TouchHandleDrawableQt() override;
+ static gfx::Image *GetHandleImage(ui::TouchHandleOrientation orientation);
private:
void UpdateBounds();
@@ -71,15 +36,13 @@ private:
float GetDrawableHorizontalPaddingRatio() const override;
RenderWidgetHostViewQt *m_rwhv;
- QScopedPointer<TouchHandleDrawableClient> m_client;
+ QScopedPointer<TouchHandleDrawableDelegate> m_delegate;
bool m_enabled;
float m_alpha;
ui::TouchHandleOrientation m_orientation;
gfx::RectF m_relativeBounds;
gfx::PointF m_originPosition;
-
- DISALLOW_COPY_AND_ASSIGN(TouchHandleDrawableQt);
};
} // namespace QtWebEngineCore
diff --git a/src/core/touch_selection_controller_client_qt.cpp b/src/core/touch_selection_controller_client_qt.cpp
index 2e9f56a5f..befee6aaf 100644
--- a/src/core/touch_selection_controller_client_qt.cpp
+++ b/src/core/touch_selection_controller_client_qt.cpp
@@ -1,44 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "render_widget_host_view_qt.h"
#include "touch_handle_drawable_qt.h"
+#include "touch_handle_drawable_client.h"
#include "touch_selection_controller_client_qt.h"
#include "touch_selection_menu_controller.h"
#include "type_conversion.h"
@@ -293,13 +258,31 @@ void TouchSelectionControllerClientQt::OnDragUpdate(const ui::TouchSelectionDrag
std::unique_ptr<ui::TouchHandleDrawable> TouchSelectionControllerClientQt::CreateDrawable()
{
- return std::unique_ptr<ui::TouchHandleDrawable>(new TouchHandleDrawableQt(m_rwhv));
+ Q_ASSERT(m_rwhv);
+ Q_ASSERT(m_rwhv->adapterClient());
+ QMap<int, QImage> images;
+ for (int orientation = 0; orientation < static_cast<int>(ui::TouchHandleOrientation::UNDEFINED);
+ ++orientation) {
+ gfx::Image *image = TouchHandleDrawableQt::GetHandleImage(
+ static_cast<ui::TouchHandleOrientation>(orientation));
+ images.insert(orientation, toQImage(image->AsBitmap()));
+ }
+ auto delegate = m_rwhv->adapterClient()->createTouchHandleDelegate(images);
+ return std::unique_ptr<ui::TouchHandleDrawable>(new TouchHandleDrawableQt(delegate));
}
void TouchSelectionControllerClientQt::DidScroll()
{
}
+void TouchSelectionControllerClientQt::resetControls()
+{
+ if (m_menuShowing) {
+ hideMenu();
+ GetTouchSelectionController()->HideAndDisallowShowingAutomatically();
+ }
+}
+
void TouchSelectionControllerClientQt::showMenu()
{
gfx::RectF rect = GetTouchSelectionController()->GetRectBetweenBounds();
diff --git a/src/core/touch_selection_controller_client_qt.h b/src/core/touch_selection_controller_client_qt.h
index 02febd9bf..3fdca7922 100644
--- a/src/core/touch_selection_controller_client_qt.h
+++ b/src/core/touch_selection_controller_client_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef TOUCH_SELECTION_CONTROLLER_CLIENT_QT_H
#define TOUCH_SELECTION_CONTROLLER_CLIENT_QT_H
@@ -51,6 +15,7 @@ namespace QtWebEngineCore {
class RenderWidgetHostViewQt;
class TouchSelectionMenuController;
+class TouchHandleDrawableDelegate;
class TouchSelectionControllerClientQt
: public ui::TouchSelectionControllerClient
@@ -74,7 +39,7 @@ public:
void ExecuteCommand(int command_id, int event_flags) override;
void RunContextMenu() override;
bool ShouldShowQuickMenu() override { return false; }
- base::string16 GetSelectedText() override { return base::string16(); }
+ std::u16string GetSelectedText() override { return std::u16string(); }
// content::TouchSelectionControllerClientManager overrides
void DidStopFlinging() override;
@@ -86,6 +51,9 @@ public:
ui::TouchSelectionController* GetTouchSelectionController() override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
+ void OnSwipeToMoveCursorBegin() override {}
+ void OnSwipeToMoveCursorEnd() override {}
+ void OnClientHitTestRegionUpdated(ui::TouchSelectionControllerClient *) override {}
// ui::TouchSelectionControllerClient overrides
bool SupportsAnimation() const override;
@@ -98,6 +66,8 @@ public:
std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override;
void DidScroll() override;
+ void resetControls();
+
private:
void showMenu();
void hideMenu();
diff --git a/src/core/touch_selection_menu_controller.cpp b/src/core/touch_selection_menu_controller.cpp
index 3a6d49160..98481baf0 100644
--- a/src/core/touch_selection_menu_controller.cpp
+++ b/src/core/touch_selection_menu_controller.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "touch_selection_controller_client_qt.h"
#include "touch_selection_menu_controller.h"
diff --git a/src/core/touch_selection_menu_controller.h b/src/core/touch_selection_menu_controller.h
index a90695c80..6a1fc1960 100644
--- a/src/core/touch_selection_menu_controller.h
+++ b/src/core/touch_selection_menu_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef TOUCH_SELECTION_MENU_CONTROLLER_H
#define TOUCH_SELECTION_MENU_CONTROLLER_H
@@ -47,7 +11,7 @@ namespace QtWebEngineCore {
class TouchSelectionControllerClientQt;
-class Q_WEBENGINECORE_PRIVATE_EXPORT TouchSelectionMenuController : public QObject {
+class Q_WEBENGINECORE_EXPORT TouchSelectionMenuController : public QObject {
Q_OBJECT
public:
enum TouchSelectionCommandFlag {
@@ -55,7 +19,7 @@ public:
Copy = 0x2,
Paste = 0x4
};
- Q_DECLARE_FLAGS(TouchSelectionCommandFlags, TouchSelectionCommandFlag);
+ Q_DECLARE_FLAGS(TouchSelectionCommandFlags, TouchSelectionCommandFlag)
Q_FLAG(TouchSelectionCommandFlag)
TouchSelectionMenuController(TouchSelectionControllerClientQt *touchSelectionControllerClient);
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index e8f8131b6..2d4fb323d 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -1,54 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "type_conversion.h"
+#include "base/containers/contains.h"
#include <components/favicon_base/favicon_util.h>
#include <net/cert/x509_certificate.h>
#include <net/cert/x509_util.h>
#include <ui/events/event_constants.h>
-#include <ui/gfx/image/image.h>
-#include <ui/gfx/image/image_skia.h>
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_rep.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
#include <QtCore/qcoreapplication.h>
-#include <QtGui/qmatrix4x4.h>
#include <QtNetwork/qsslcertificate.h>
namespace QtWebEngineCore {
@@ -66,6 +31,7 @@ QImage toQImage(const SkBitmap &bitmap)
case kA16_unorm_SkColorType:
case kR16G16_float_SkColorType:
case kR16G16_unorm_SkColorType:
+ case kR8_unorm_SkColorType:
qWarning("Unknown or unsupported skia image format");
break;
case kAlpha_8_SkColorType:
@@ -88,6 +54,7 @@ QImage toQImage(const SkBitmap &bitmap)
break;
}
break;
+ case kSRGBA_8888_SkColorType:
case kRGB_888x_SkColorType:
case kRGBA_8888_SkColorType:
switch (bitmap.alphaType()) {
@@ -136,6 +103,7 @@ QImage toQImage(const SkBitmap &bitmap)
}
break;
case kBGR_101010x_SkColorType:
+ case kBGR_101010x_XR_SkColorType:
case kBGRA_1010102_SkColorType:
switch (bitmap.alphaType()) {
case kUnknown_SkAlphaType:
@@ -276,17 +244,6 @@ int flagsFromModifiers(Qt::KeyboardModifiers modifiers)
return modifierFlags;
}
-void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c)
-{
- QMatrix4x4 qtMatrix(
- m.get(0, 0), m.get(0, 1), m.get(0, 2), m.get(0, 3),
- m.get(1, 0), m.get(1, 1), m.get(1, 2), m.get(1, 3),
- m.get(2, 0), m.get(2, 1), m.get(2, 2), m.get(2, 3),
- m.get(3, 0), m.get(3, 1), m.get(3, 2), m.get(3, 3));
- qtMatrix.optimize();
- c = qtMatrix;
-}
-
static QSslCertificate toCertificate(CRYPTO_BUFFER *buffer)
{
auto derCert = net::x509_util::CryptoBufferAsStringPiece(buffer);
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 9bf0416a9..0da8a6931 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef TYPE_CONVERSION_H
#define TYPE_CONVERSION_H
@@ -49,7 +13,6 @@
#include <QRect>
#include <QString>
#include <QUrl>
-#include <base/strings/nullable_string16.h>
#include "base/files/file_path.h"
#include "base/time/time.h"
#include "net/cookies/canonical_cookie.h"
@@ -57,13 +20,12 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPixelRef.h"
-#include "third_party/skia/include/core/SkMatrix44.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "url/gurl.h"
+#include "url/origin.h"
-QT_FORWARD_DECLARE_CLASS(QMatrix4x4)
QT_FORWARD_DECLARE_CLASS(QSslCertificate)
namespace gfx {
@@ -77,24 +39,28 @@ class X509Certificate;
namespace QtWebEngineCore {
-inline QString toQt(const base::string16 &string)
+#if defined(Q_OS_WIN)
+inline QString toQt(const std::wstring &string)
{
-#if defined(OS_WIN)
return QString::fromStdWString(string);
-#else
- return QString::fromUtf16(reinterpret_cast<const char16_t *>(string.data()), string.size());
+}
#endif
+
+inline QString toQt(const std::u16string &string)
+{
+ return QString::fromStdU16String(string);
}
-inline QString toQt(const base::Optional<base::string16> &string)
+inline QString toQt(const absl::optional<std::u16string> &string)
{
if (!string.has_value())
return QString();
-#if defined(OS_WIN)
- return QString::fromStdWString(string->data());
-#else
- return QString::fromUtf16(string->data());
-#endif
+ return QString::fromStdU16String(*string);
+}
+
+inline QString toQString(const base::StringPiece &string)
+{
+ return QString::fromUtf8(string.data(), string.size());
}
inline QString toQString(const std::string &string)
@@ -102,6 +68,11 @@ inline QString toQString(const std::string &string)
return QString::fromStdString(string);
}
+inline QByteArray toQByteArray(const base::StringPiece &string)
+{
+ return QByteArray(string.data(), string.size());
+}
+
inline QByteArray toQByteArray(const std::string &string)
{
return QByteArray::fromStdString(string);
@@ -113,25 +84,16 @@ inline QString toQt(const std::string &string)
return toQString(string);
}
-inline base::string16 toString16(const QString &qString)
-{
-#if defined(OS_WIN)
- return base::string16(qString.toStdWString());
-#else
- return base::string16((const char16_t *)qString.utf16());
-#endif
-}
-
-inline base::NullableString16 toNullableString16(const QString &qString)
+inline std::u16string toString16(const QString &qString)
{
- return base::NullableString16(toString16(qString), qString.isNull());
+ return qString.toStdU16String();
}
-inline base::Optional<base::string16> toOptionalString16(const QString &qString)
+inline absl::optional<std::u16string> toOptionalString16(const QString &qString)
{
if (qString.isNull())
- return base::nullopt;
- return base::make_optional(toString16(qString));
+ return absl::nullopt;
+ return absl::make_optional(qString.toStdU16String());
}
inline QUrl toQt(const GURL &url)
@@ -147,11 +109,26 @@ inline GURL toGurl(const QUrl& url)
return GURL(url.toEncoded().toStdString());
}
+inline QUrl toQt(const url::Origin &origin)
+{
+ return QUrl::fromEncoded(toQByteArray(origin.Serialize()));
+}
+
+inline url::Origin toOrigin(const QUrl &url)
+{
+ return url::Origin::Create(toGurl(url));
+}
+
inline QPoint toQt(const gfx::Point &point)
{
return QPoint(point.x(), point.y());
}
+inline QPointF toQt(const gfx::PointF &point)
+{
+ return QPointF(point.x(), point.y());
+}
+
inline QPointF toQt(const gfx::Vector2dF &point)
{
return QPointF(point.x(), point.y());
@@ -202,6 +179,11 @@ inline QSizeF toQt(const gfx::SizeF &size)
return QSizeF(size.width(), size.height());
}
+inline QSize toQt(const SkISize &size)
+{
+ return QSize(size.width(), size.height());
+}
+
inline QColor toQt(const SkColor &c)
{
return QColor(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c));
@@ -225,8 +207,6 @@ SkBitmap toSkBitmap(const QImage &image);
QIcon toQIcon(const gfx::Image &image);
QIcon toQIcon(const std::vector<SkBitmap> &bitmaps);
-void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c);
-
inline QDateTime toQt(base::Time time)
{
return QDateTime::fromMSecsSinceEpoch(time.ToJavaTime());
@@ -250,7 +230,7 @@ inline QNetworkCookie toQt(const net::CanonicalCookie & cookie)
inline base::FilePath::StringType toFilePathString(const QString &str)
{
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
return QDir::toNativeSeparators(str).toStdWString();
#else
return str.toStdString();
@@ -264,7 +244,7 @@ inline base::FilePath toFilePath(const QString &str)
int flagsFromModifiers(Qt::KeyboardModifiers modifiers);
-inline QStringList fromVector(const std::vector<base::string16> &vector)
+inline QStringList fromVector(const std::vector<std::u16string> &vector)
{
QStringList result;
for (auto s: vector) {
diff --git a/src/core/user_notification_controller.cpp b/src/core/user_notification_controller.cpp
index f94605a55..9c1122cca 100644
--- a/src/core/user_notification_controller.cpp
+++ b/src/core/user_notification_controller.cpp
@@ -1,48 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "user_notification_controller.h"
#include "type_conversion.h"
-#include "base/callback.h"
-#include "content/public/browser/notification_event_dispatcher.h"
#include "third_party/blink/public/mojom/notifications/notification.mojom-shared.h"
#include "third_party/blink/public/common/notifications/notification_resources.h"
#include "third_party/blink/public/common/notifications/platform_notification_data.h"
diff --git a/src/core/user_notification_controller.h b/src/core/user_notification_controller.h
index b710641d0..21d9fc653 100644
--- a/src/core/user_notification_controller.h
+++ b/src/core/user_notification_controller.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef DESKTOP_NOTIFICATION_CONTROLLER_H
#define DESKTOP_NOTIFICATION_CONTROLLER_H
diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp
index 1c8a78cd3..c33fb9081 100644
--- a/src/core/user_script.cpp
+++ b/src/core/user_script.cpp
@@ -1,41 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "base/strings/string_util.h"
#include "qtwebengine/userscript/user_script_data.h"
#include "user_script.h"
@@ -54,7 +20,7 @@ bool GetDeclarationValue(const base::StringPiece& line,
std::string temp(line.data() + index + prefix.length(),
line.length() - index - prefix.length());
- if (temp.empty() || !base::IsUnicodeWhitespace(temp[0]))
+ if (temp.empty() || !base::IsWhitespace(temp[0]))
return false;
base::TrimWhitespaceASCII(temp, base::TRIM_ALL, value);
diff --git a/src/core/user_script.h b/src/core/user_script.h
index 2be1b4ed0..fdc7782b8 100644
--- a/src/core/user_script.h
+++ b/src/core/user_script.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
diff --git a/src/core/visited_links_manager_qt.cpp b/src/core/visited_links_manager_qt.cpp
index 7b98da8a3..9e1bd7a32 100644
--- a/src/core/visited_links_manager_qt.cpp
+++ b/src/core/visited_links_manager_qt.cpp
@@ -1,45 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "visited_links_manager_qt.h"
#include "content_browser_client_qt.h"
+#include "profile_adapter.h"
#include "profile_qt.h"
#include "type_conversion.h"
@@ -95,7 +60,7 @@ VisitedLinksManagerQt::VisitedLinksManagerQt(ProfileQt *profile, bool persistVis
{
Q_ASSERT(profile);
if (persistVisitedLinks)
- profile->ensureDirectoryExists();
+ profile->profileAdapter()->ensureDataPathExists();
m_visitedLinkWriter.reset(new visitedlink::VisitedLinkWriter(profile, m_delegate.data(), persistVisitedLinks));
m_visitedLinkWriter->Init();
}
diff --git a/src/core/visited_links_manager_qt.h b/src/core/visited_links_manager_qt.h
index 27d46f8ff..7bcf32d52 100644
--- a/src/core/visited_links_manager_qt.h
+++ b/src/core/visited_links_manager_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -68,7 +32,7 @@ namespace QtWebEngineCore {
class ProfileQt;
class VisitedLinkDelegateQt;
-class Q_WEBENGINECORE_PRIVATE_EXPORT VisitedLinksManagerQt {
+class Q_WEBENGINECORE_EXPORT VisitedLinksManagerQt {
public:
virtual~VisitedLinksManagerQt();
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 0a83b248f..7ffeaaa5b 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -43,11 +7,15 @@
#include "web_contents_adapter.h"
+#include "autofill_client_qt.h"
+#include "content_browser_client_qt.h"
#include "devtools_frontend_qt.h"
#include "download_manager_delegate_qt.h"
#include "favicon_driver_qt.h"
#include "favicon_service_factory_qt.h"
+#include "find_text_helper.h"
#include "media_capture_devices_dispatcher.h"
+#include "pdf_util_qt.h"
#include "profile_adapter.h"
#include "profile_qt.h"
#include "qwebengineloadinginfo.h"
@@ -61,25 +29,28 @@
#include "base/command_line.h"
#include "base/metrics/user_metrics.h"
#include "base/task/current_thread.h"
-#include "base/task/post_task.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/values.h"
#include "chrome/browser/tab_contents/form_interaction_tab_helper.h"
+#include "components/autofill/core/browser/autofill_manager.h"
+#include "components/autofill/content/browser/content_autofill_driver_factory.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "components/favicon/core/favicon_service.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/text_input_manager.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/download_request_utils.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/navigation_entry_restore_context.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/drop_data.h"
+#include "content/public/common/url_constants.h"
#include "extensions/buildflags/buildflags.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/common/page_state/page_state.h"
@@ -89,8 +60,26 @@
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/font_render_params.h"
+#include "ui/native_theme/native_theme.h"
#include "qtwebengine/browser/qtwebenginepage.mojom.h"
+#include <QtCore/QVariant>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QMimeData>
+#include <QtCore/QTemporaryDir>
+#include <QtGui/QDrag>
+#include <QtGui/QDragEnterEvent>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPageLayout>
+#include <QtGui/QPixmap>
+#include <QtGui/QStyleHints>
+
+#if QT_CONFIG(accessibility)
+#include "browser_accessibility_qt.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include <QtGui/qaccessible.h>
+#endif
+
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/print_view_manager_qt.h"
#endif
@@ -104,36 +93,18 @@
#include "extensions/extension_web_contents_observer_qt.h"
#endif
-#include <QtCore/QVariant>
-#include <QtCore/QElapsedTimer>
-#include <QtCore/QMimeData>
-#include <QtCore/QTemporaryDir>
-#include <QtGui/QDrag>
-#include <QtGui/QDragEnterEvent>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QPageLayout>
-#include <QtGui/QPixmap>
-#include <QtGui/QStyleHints>
-
-// Can't include headers as qaccessible.h conflicts with Chromium headers.
-namespace content {
-extern QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc);
-}
-
namespace QtWebEngineCore {
#define CHECK_INITIALIZED(return_value) \
if (!isInitialized()) \
return return_value
-#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \
- if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \
+#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_frame_host) \
+ if (!render_frame_host->IsRenderFrameLive() && render_frame_host->GetView()) { \
LOG(WARNING) << "Ignore navigation due to terminated render process with invalid RenderWidgetHostView."; \
return; \
}
-static const int kTestWindowWidth = 800;
-static const int kTestWindowHeight = 600;
static const int kHistoryStreamVersion = 4;
static QVariant fromJSValue(const base::Value *result)
@@ -144,57 +115,48 @@ static QVariant fromJSValue(const base::Value *result)
break;
case base::Value::Type::BOOLEAN:
{
- bool out;
- if (result->GetAsBoolean(&out))
- ret.setValue(out);
+ if (auto out = result->GetIfBool())
+ ret.setValue(*out);
break;
}
case base::Value::Type::INTEGER:
{
- int out;
- if (result->GetAsInteger(&out))
- ret.setValue(out);
+ if (auto out = result->GetIfInt())
+ ret.setValue(*out);
break;
}
case base::Value::Type::DOUBLE:
{
- double out;
- if (result->GetAsDouble(&out))
- ret.setValue(out);
+ if (auto out = result->GetIfDouble())
+ ret.setValue(*out);
break;
}
case base::Value::Type::STRING:
{
- base::string16 out;
- if (result->GetAsString(&out))
- ret.setValue(toQt(out));
+ if (auto out = result->GetIfString())
+ ret.setValue(toQt(*out));
break;
}
case base::Value::Type::LIST:
{
- const base::ListValue *out;
- if (result->GetAsList(&out)) {
+ if (const auto out = result->GetIfList()) {
+ size_t size = out->size();
QVariantList list;
- list.reserve(out->GetSize());
- for (size_t i = 0; i < out->GetSize(); ++i) {
- const base::Value *outVal = 0;
- if (out->Get(i, &outVal) && outVal)
- list.insert(i, fromJSValue(outVal));
+ list.reserve(size);
+ for (size_t i = 0; i < size; ++i) {
+ auto &outVal = (*out)[i];
+ list.insert(i, fromJSValue(&outVal));
}
ret.setValue(list);
}
break;
}
- case base::Value::Type::DICTIONARY:
+ case base::Value::Type::DICT:
{
- const base::DictionaryValue *out;
- if (result->GetAsDictionary(&out)) {
+ if (const auto dict = result->GetIfDict()) {
QVariantMap map;
- base::DictionaryValue::Iterator it(*out);
- while (!it.IsAtEnd()) {
- map.insert(toQt(it.key()), fromJSValue(&it.value()));
- it.Advance();
- }
+ for (const auto pair : *dict)
+ map.insert(toQt(pair.first), fromJSValue(&pair.second));
ret.setValue(map);
}
break;
@@ -247,10 +209,28 @@ static std::unique_ptr<content::WebContents> createBlankWebContents(WebContentsA
return webContents;
}
+static int navigationListSize(content::NavigationController &controller) {
+ // If we're currently on the initial NavigationEntry, no navigation has
+ // committed, so the initial NavigationEntry should not be part of the
+ // "Navigation List", and we should return 0 as the navigation list size.
+ if (controller.GetLastCommittedEntry()->IsInitialEntry())
+ return 0;
+ return controller.GetEntryCount();
+}
+
+static int navigationListCurrentIndex(content::NavigationController &controller) {
+ // If we're currently on the initial NavigationEntry, no navigation has
+ // committed, so the initial NavigationEntry should not be part of the
+ // "Navigation List", and we should return -1 as the current index.
+ if (controller.GetLastCommittedEntry()->IsInitialEntry())
+ return -1;
+ return controller.GetCurrentEntryIndex();
+}
+
static void serializeNavigationHistory(content::NavigationController &controller, QDataStream &output)
{
- const int currentIndex = controller.GetCurrentEntryIndex();
- const int count = controller.GetEntryCount();
+ const int currentIndex = navigationListCurrentIndex(controller);
+ const int count = navigationListSize(controller);
const int pendingIndex = controller.GetPendingEntryIndex();
output << kHistoryStreamVersion;
@@ -299,6 +279,8 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
int count;
input >> count >> *currentIndex;
+ std::unique_ptr<content::NavigationEntryRestoreContext> context = content::NavigationEntryRestoreContext::Create();
+
entries->reserve(count);
// Logic taken from SerializedNavigationEntry::ReadFromPickle and ToNavigationEntries.
for (int i = 0; i < count; ++i) {
@@ -338,7 +320,8 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
std::unique_ptr<content::NavigationEntry> entry = content::NavigationController::CreateNavigationEntry(
toGurl(virtualUrl),
content::Referrer(toGurl(referrerUrl), static_cast<network::mojom::ReferrerPolicy>(referrerPolicy)),
- base::nullopt, // optional initiator_origin
+ absl::nullopt, // optional initiator_origin
+ absl::nullopt, // optional initiator_base_url
// Use a transition type of reload so that we don't incorrectly
// increase the typed count.
ui::PAGE_TRANSITION_RELOAD,
@@ -349,7 +332,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
nullptr);
entry->SetTitle(toString16(title));
- entry->SetPageState(blink::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size())));
+ entry->SetPageState(blink::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size())), context.get());
entry->SetHasPostData(hasPostData);
entry->SetOriginalRequestURL(toGurl(originalRequestUrl));
entry->SetIsOverridingUserAgent(isOverridingUserAgent);
@@ -424,17 +407,6 @@ QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavig
content::NavigationController &controller = newWebContents->GetController();
controller.Restore(currentIndex, content::RestoreType::kRestored, &entries);
- if (controller.GetActiveEntry()) {
- // Set up the file access rights for the selected navigation entry.
- // TODO(joth): This is duplicated from chrome/.../session_restore.cc and
- // should be shared e.g. in NavigationController. http://crbug.com/68222
- const int id = newWebContents->GetMainFrame()->GetProcess()->GetID();
- const blink::PageState& pageState = controller.GetActiveEntry()->GetPageState();
- const std::vector<base::FilePath>& filePaths = pageState.GetReferencedFiles();
- for (std::vector<base::FilePath>::const_iterator file = filePaths.begin(); file != filePaths.end(); ++file)
- content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(id, *file);
- }
-
return QSharedPointer<WebContentsAdapter>::create(std::move(newWebContents));
}
@@ -482,6 +454,10 @@ bool WebContentsAdapter::isInitialized() const
return (bool)m_webContentsDelegate;
}
+ui::NativeTheme::PreferredColorScheme toWeb(Qt::ColorScheme colorScheme) {
+ return colorScheme == Qt::ColorScheme::Dark ? ui::NativeTheme::PreferredColorScheme::kDark : ui::NativeTheme::PreferredColorScheme::kLight;
+}
+
void WebContentsAdapter::initialize(content::SiteInstance *site)
{
Q_ASSERT(m_adapterClient);
@@ -518,6 +494,8 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
FaviconDriverQt::CreateForWebContents(
webContents(), FaviconServiceFactoryQt::GetForBrowserContext(context), m_adapterClient);
+ AutofillClientQt::CreateForWebContents(webContents());
+
// Create an instance of WebEngineVisitedLinksManager to catch the first
// content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will
// force to initialize visited links in VisitedLinkSlave.
@@ -527,12 +505,18 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
// Create a RenderView with the initial empty document
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
- if (!rvh->IsRenderViewLive())
+ if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive())
static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(
- rvh, base::nullopt, nullptr);
+ rvh, absl::nullopt, nullptr);
m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
+ // Make sure the system theme's light/dark mode is propagated to webpages
+ QObject::connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, [](Qt::ColorScheme colorScheme){
+ ui::NativeTheme::GetInstanceForWeb()->set_preferred_color_scheme(toWeb(colorScheme));
+ });
+ ui::NativeTheme::GetInstanceForWeb()->set_preferred_color_scheme(toWeb(QGuiApplication::styleHints()->colorScheme()));
+
m_adapterClient->initializationFinished();
}
@@ -544,8 +528,9 @@ void WebContentsAdapter::initializeRenderPrefs()
// seconds
const int qtCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime();
rendererPrefs->caret_blink_interval =
- base::TimeDelta::FromMillisecondsD(0.5 * static_cast<double>(qtCursorFlashTime));
+ base::Milliseconds(0.5 * static_cast<double>(qtCursorFlashTime));
rendererPrefs->user_agent_override = blink::UserAgentOverride::UserAgentOnly(m_profileAdapter->httpUserAgent().toStdString());
+ rendererPrefs->user_agent_override.ua_metadata_override = profile()->userAgentMetadata();
rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString();
#if QT_CONFIG(webengine_webrtc)
base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess();
@@ -559,6 +544,8 @@ void WebContentsAdapter::initializeRenderPrefs()
? blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly
: blink::kWebRTCIPHandlingDefault;
#endif
+ rendererPrefs->can_accept_load_drops = m_adapterClient->webEngineSettings()->testAttribute(QWebEngineSettings::NavigateOnDropEnabled);
+
// Set web-contents font settings to the default font settings as Chromium constantly overrides
// the global font defaults with the font settings of the latest web-contents created.
static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
@@ -610,7 +597,7 @@ void WebContentsAdapter::reload()
bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
setLifecycleState(LifecycleState::Active);
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings());
settings->doApply();
if (!wasDiscarded) // undiscard() already triggers a reload
@@ -625,7 +612,7 @@ void WebContentsAdapter::reloadAndBypassCache()
bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
setLifecycleState(LifecycleState::Active);
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings());
settings->doApply();
if (!wasDiscarded) // undiscard() already triggers a reload
@@ -657,7 +644,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
setLifecycleState(LifecycleState::Active);
}
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply();
@@ -731,7 +718,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
if (resizeNeeded) {
// Schedule navigation on the event loop.
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&NavigateTask, sharedFromThis().toWeakRef(), std::move(params)));
} else {
Navigate(this, params);
@@ -745,7 +732,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
else
setLifecycleState(LifecycleState::Active);
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply();
@@ -777,7 +764,7 @@ void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("SavePage"));
- m_webContentsDelegate->setSavePageInfo(SavePageInfo(filePath, savePageFormat));
+ m_webContentsDelegate->setSavePageInfo(new SavePageInfo(filePath, savePageFormat));
m_webContents->OnSavePage();
}
@@ -896,7 +883,7 @@ void WebContentsAdapter::navigateBack()
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("Back"));
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
if (!m_webContents->GetController().CanGoBack())
return;
m_webContents->GetController().GoBack();
@@ -907,7 +894,7 @@ void WebContentsAdapter::navigateForward()
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("Forward"));
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
if (!m_webContents->GetController().CanGoForward())
return;
m_webContents->GetController().GoForward();
@@ -917,7 +904,7 @@ void WebContentsAdapter::navigateForward()
void WebContentsAdapter::navigateToIndex(int offset)
{
CHECK_INITIALIZED();
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
m_webContents->GetController().GoToIndex(offset);
focusIfNecessary();
}
@@ -925,7 +912,7 @@ void WebContentsAdapter::navigateToIndex(int offset)
void WebContentsAdapter::navigateToOffset(int offset)
{
CHECK_INITIALIZED();
- CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame());
m_webContents->GetController().GoToOffset(offset);
focusIfNecessary();
}
@@ -933,13 +920,13 @@ void WebContentsAdapter::navigateToOffset(int offset)
int WebContentsAdapter::navigationEntryCount()
{
CHECK_INITIALIZED(0);
- return m_webContents->GetController().GetEntryCount();
+ return navigationListSize(m_webContents->GetController());
}
int WebContentsAdapter::currentNavigationEntryIndex()
{
CHECK_INITIALIZED(0);
- return m_webContents->GetController().GetCurrentEntryIndex();
+ return navigationListCurrentIndex(m_webContents->GetController());
}
QUrl WebContentsAdapter::getNavigationEntryOriginalUrl(int index)
@@ -1003,9 +990,8 @@ void WebContentsAdapter::setZoomFactor(qreal factor)
content::HostZoomMap *zoomMap = content::HostZoomMap::GetForWebContents(m_webContents.get());
if (zoomMap) {
- int render_process_id = m_webContents->GetMainFrame()->GetProcess()->GetID();
- int render_view_id = m_webContents->GetRenderViewHost()->GetRoutingID();
- zoomMap->SetTemporaryZoomLevel(render_process_id, render_view_id, zoomLevel);
+ const content::GlobalRenderFrameHostId global_id = m_webContents->GetPrimaryMainFrame()->GetGlobalId();
+ zoomMap->SetTemporaryZoomLevel(global_id, zoomLevel);
}
}
@@ -1041,15 +1027,13 @@ QWebEngineUrlRequestInterceptor* WebContentsAdapter::requestInterceptor() const
QAccessibleInterface *WebContentsAdapter::browserAccessible()
{
CHECK_INITIALIZED(nullptr);
- content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
- Q_ASSERT(rvh);
- content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame());
+ content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(m_webContents->GetPrimaryMainFrame());
if (!rfh)
return nullptr;
content::BrowserAccessibilityManager *manager = rfh->GetOrCreateBrowserAccessibilityManager();
if (!manager) // FIXME!
return nullptr;
- content::BrowserAccessibility *acc = manager->GetRoot();
+ content::BrowserAccessibility *acc = manager->GetFromAXNode(manager->GetRoot());
return content::toQAccessibleInterface(acc);
}
@@ -1058,26 +1042,32 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible()
void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId)
{
CHECK_INITIALIZED();
- content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
- Q_ASSERT(rvh);
-// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation();
+ content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame();
+ Q_ASSERT(rfh);
+ if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
+ qWarning() << "Local frame is gone, not running script";
+ return;
+ }
if (worldId == 0)
- rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), base::NullCallback());
+ rfh->ExecuteJavaScript(toString16(javaScript), base::NullCallback());
else
- rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), base::NullCallback(), worldId);
+ rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), base::NullCallback(), worldId);
}
quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId)
{
CHECK_INITIALIZED(0);
- content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
- Q_ASSERT(rvh);
-// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation();
+ content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame();
+ Q_ASSERT(rfh);
+ if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) {
+ qWarning() << "Local frame is gone, not running script";
+ return 0;
+ }
content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId);
if (worldId == 0)
- rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), std::move(callback));
+ rfh->ExecuteJavaScript(toString16(javaScript), std::move(callback));
else
- rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId);
+ rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId);
return m_nextRequestId++;
}
@@ -1102,7 +1092,9 @@ void WebContentsAdapter::updateWebPreferences(const blink::web_pref::WebPreferen
// In case of updating preferences during navigation, there might be a pending RVH what will
// be active on successful navigation.
- content::RenderFrameHost *pendingRFH = (static_cast<content::WebContentsImpl*>(m_webContents.get()))->GetFrameTree()->root()->render_manager()->speculative_frame_host();
+ content::RenderFrameHost *pendingRFH =
+ (static_cast<content::WebContentsImpl*>(m_webContents.get()))
+ ->GetPrimaryFrameTree().root()->render_manager()->speculative_frame_host();
if (pendingRFH) {
content::RenderViewHost *pendingRVH = pendingRFH->GetRenderViewHost();
Q_ASSERT(pendingRVH);
@@ -1116,7 +1108,7 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN
{
CHECK_INITIALIZED();
content::BrowserContext *bctx = m_webContents->GetBrowserContext();
- content::DownloadManager *dlm = content::BrowserContext::GetDownloadManager(bctx);
+ content::DownloadManager *dlm = bctx->GetDownloadManager();
DownloadManagerDelegateQt *dlmd = m_profileAdapter->downloadManagerDelegate();
if (!dlm)
@@ -1181,7 +1173,7 @@ qint64 WebContentsAdapter::renderProcessPid() const
{
CHECK_INITIALIZED(0);
- content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess();
+ content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess();
const base::Process &process = renderProcessHost->GetProcess();
if (!process.IsValid())
return 0;
@@ -1191,7 +1183,7 @@ qint64 WebContentsAdapter::renderProcessPid() const
void WebContentsAdapter::copyImageAt(const QPoint &location)
{
CHECK_INITIALIZED();
- m_webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y());
+ m_webContents->GetPrimaryMainFrame()->CopyImageAt(location.x(), location.y());
}
static blink::mojom::MediaPlayerActionType toBlinkMediaPlayerActionType(WebContentsAdapter::MediaPlayerAction action)
@@ -1218,7 +1210,7 @@ void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, Medi
if (action == MediaPlayerNoAction)
return;
blink::mojom::MediaPlayerAction blinkAction(toBlinkMediaPlayerActionType(action), enable);
- m_webContents->GetRenderViewHost()->GetMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
+ m_webContents->GetPrimaryMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction);
}
void WebContentsAdapter::inspectElementAt(const QPoint &location)
@@ -1269,7 +1261,10 @@ void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter>
setLifecycleState(LifecycleState::Active);
- m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, m_webContents.get());
+ content::WebContents *webContents = m_webContents.get();
+ if (content::WebContents *guest = guestWebContents())
+ webContents = guest;
+ m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, webContents);
updateRecommendedState();
}
@@ -1289,6 +1284,11 @@ void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend)
updateRecommendedState();
}
+QString WebContentsAdapter::devToolsId()
+{
+ return QString::fromStdString(DevToolsFrontendQt::GetId(m_webContents.get()));
+}
+
void WebContentsAdapter::exitFullScreen()
{
CHECK_INITIALIZED();
@@ -1319,14 +1319,17 @@ void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QPageRa
{
#if QT_CONFIG(webengine_printing_and_pdf)
CHECK_INITIALIZED();
- PrintViewManagerQt::PrintToPDFFileCallback callback = base::Bind(&callbackOnPdfSavingFinished,
- m_adapterClient,
- filePath);
- PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFFileWithCallback(pageLayout,
+ PrintViewManagerQt::PrintToPDFFileCallback callback = base::BindOnce(&callbackOnPdfSavingFinished,
+ m_adapterClient,
+ filePath);
+ content::WebContents *webContents = m_webContents.get();
+ if (content::WebContents *guest = guestWebContents())
+ webContents = guest;
+ PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFFileWithCallback(pageLayout,
pageRanges,
true,
filePath,
- callback);
+ std::move(callback));
#endif // QT_CONFIG(webengine_printing_and_pdf)
}
@@ -1337,14 +1340,17 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo
{
#if QT_CONFIG(webengine_printing_and_pdf)
CHECK_INITIALIZED(0);
- PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished,
- m_adapterClient,
- m_nextRequestId);
- PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFWithCallback(pageLayout,
+ PrintViewManagerQt::PrintToPDFCallback callback = base::BindOnce(&callbackOnPrintingFinished,
+ m_adapterClient,
+ m_nextRequestId);
+ content::WebContents *webContents = m_webContents.get();
+ if (content::WebContents *guest = guestWebContents())
+ webContents = guest;
+ PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFWithCallback(pageLayout,
pageRanges,
colorMode,
useCustomMargins,
- callback);
+ std::move(callback));
return m_nextRequestId++;
#else
Q_UNUSED(pageLayout);
@@ -1389,7 +1395,7 @@ void WebContentsAdapter::grantFeaturePermission(const QUrl &securityOrigin, Prof
void WebContentsAdapter::grantMouseLockPermission(const QUrl &securityOrigin, bool granted)
{
CHECK_INITIALIZED();
- if (securityOrigin != toQt(m_webContents->GetLastCommittedURL().GetOrigin()))
+ if (securityOrigin != toQt(m_webContents->GetLastCommittedURL().DeprecatedGetOriginAsURL()))
return;
if (granted) {
@@ -1414,7 +1420,7 @@ void WebContentsAdapter::grantMouseLockPermission(const QUrl &securityOrigin, bo
void WebContentsAdapter::handlePendingMouseLockPermission()
{
CHECK_INITIALIZED();
- auto it = m_pendingMouseLockPermissions.find(toQt(m_webContents->GetLastCommittedURL().GetOrigin()));
+ auto it = m_pendingMouseLockPermissions.find(toQt(m_webContents->GetLastCommittedURL().DeprecatedGetOriginAsURL()));
if (it != m_pendingMouseLockPermissions.end()) {
m_webContents->GotResponseToLockMouseRequest(it.value() ? blink::mojom::PointerLockResult::kSuccess
: blink::mojom::PointerLockResult::kPermissionDenied);
@@ -1426,8 +1432,10 @@ void WebContentsAdapter::setBackgroundColor(const QColor &color)
{
CHECK_INITIALIZED();
SkColor c = toSk(color);
- if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView())
+ if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView()) {
rwhv->SetBackgroundColor(c);
+ ((content::RenderWidgetHostViewBase *)rwhv)->SetContentBackgroundColor(c);
+ }
if (color != Qt::transparent)
m_pageHost->SetBackgroundColor(c);
}
@@ -1437,6 +1445,12 @@ content::WebContents *WebContentsAdapter::webContents() const
return m_webContents.get();
}
+content::WebContents *WebContentsAdapter::guestWebContents() const
+{
+ std::vector<content::WebContents *> innerWebContents = m_webContents->GetInnerWebContents();
+ return !innerWebContents.empty() ? innerWebContents[0] : nullptr;
+}
+
#if QT_CONFIG(webengine_webchannel)
QWebChannel *WebContentsAdapter::webChannel() const
{
@@ -1477,8 +1491,10 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
mimeData->setText(toQt(*dropData.text));
if (dropData.html.has_value())
mimeData->setHtml(toQt(*dropData.html));
- if (dropData.url.is_valid())
+ if (dropData.url.is_valid()) {
mimeData->setUrls(QList<QUrl>() << toQt(dropData.url));
+ mimeData->setText(toQt(dropData.url_title));
+ }
if (!dropData.custom_data.empty()) {
base::Pickle pickle;
ui::WriteCustomDataToPickle(dropData.custom_data, &pickle);
@@ -1533,7 +1549,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
}
{
- base::CurrentThread::ScopedNestableTaskAllower allow;
+ base::CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop allow;
drag->exec(allowedActions);
}
@@ -1544,15 +1560,15 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
// dropping data into them. We don't even try to support dropping into PDF input fields,
// since it's not working in Chrome right now.
content::WebContents *targetWebContents = m_webContents.get();
- std::vector<content::WebContents *> innerWebContents = m_webContents->GetInnerWebContents();
- if (!innerWebContents.empty())
- targetWebContents = innerWebContents[0];
+ if (content::WebContents *guest = guestWebContents())
+ targetWebContents = guest;
content::RenderViewHost *rvh = targetWebContents->GetRenderViewHost();
if (rvh) {
rvh->GetWidget()->DragSourceEndedAt(gfx::PointF(m_lastDragClientPos.x(), m_lastDragClientPos.y()),
gfx::PointF(m_lastDragScreenPos.x(), m_lastDragScreenPos.y()),
- ui::mojom::DragOperation(m_currentDropAction));
+ ui::mojom::DragOperation(m_currentDropAction),
+ base::DoNothing());
rvh->GetWidget()->DragSourceSystemDragEnded();
}
}
@@ -1603,6 +1619,11 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
}
if (!dropData->filenames.empty())
return;
+ if (!urls.empty()) {
+ dropData->url = toGurl(urls.first());
+ if (mimeData->hasText())
+ dropData->url_title = toString16(mimeData->text());
+ }
if (mimeData->hasHtml())
dropData->html = toOptionalString16(mimeData->html());
if (mimeData->hasText())
@@ -1664,7 +1685,8 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPointF &screenPos)
rvh->GetWidget()->FilterDropData(m_currentDropData.get());
rvh->GetWidget()->DragTargetDragEnter(*m_currentDropData, toGfx(e->position()), toGfx(screenPos),
toWeb(e->possibleActions()),
- toWeb(e->buttons()) | toWeb(e->modifiers()));
+ toWeb(e->buttons()) | toWeb(e->modifiers()),
+ base::DoNothing());
}
Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const QPointF &screenPos)
@@ -1674,7 +1696,7 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q
m_lastDragClientPos = e->position();
m_lastDragScreenPos = screenPos;
rvh->GetWidget()->DragTargetDragOver(toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos), toWeb(e->possibleActions()),
- toWeb(e->buttons()) | toWeb(e->modifiers()));
+ toWeb(e->buttons()) | toWeb(e->modifiers()), base::DoNothing());
waitForUpdateDragActionCalled();
return toQt(ui::mojom::DragOperation(m_currentDropAction));
}
@@ -1701,7 +1723,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled()
static_cast<int>(timeout));
return;
}
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
+ base::PlatformThread::Sleep(base::Milliseconds(1));
}
}
@@ -1720,7 +1742,7 @@ void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos)
m_lastDragClientPos = e->position();
m_lastDragScreenPos = screenPos;
rvh->GetWidget()->DragTargetDrop(*m_currentDropData, toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos),
- toWeb(e->buttons()) | toWeb(e->modifiers()));
+ toWeb(e->buttons()) | toWeb(e->modifiers()), base::DoNothing());
m_currentDropData.reset();
}
@@ -1764,7 +1786,29 @@ void WebContentsAdapter::resetSelection()
if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
if (auto mgr = rwhv->GetTextInputManager())
if (auto selection = const_cast<content::TextInputManager::TextSelection *>(mgr->GetTextSelection(rwhv)))
- selection->SetSelection(base::string16(), 0, gfx::Range(), false);
+ selection->SetSelection(std::u16string(), 0, gfx::Range(), false);
+ }
+}
+
+void WebContentsAdapter::resetTouchSelectionController()
+{
+ CHECK_INITIALIZED();
+ unselect();
+ if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView()))
+ rwhv->resetTouchSelectionController();
+}
+
+void WebContentsAdapter::changeTextDirection(bool leftToRight)
+{
+ CHECK_INITIALIZED();
+ if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
+ auto textInputManager = rwhv->GetTextInputManager();
+ if (!textInputManager)
+ return;
+ if (auto activeWidget = textInputManager->GetActiveWidget()) {
+ activeWidget->UpdateTextDirection(leftToRight ? base::i18n::TextDirection::LEFT_TO_RIGHT : base::i18n::TextDirection::RIGHT_TO_LEFT);
+ activeWidget->NotifyTextDirection();
+ }
}
}
@@ -1776,18 +1820,20 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
status = WebContentsAdapterClient::NormalTerminationStatus;
break;
case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+ case base::TERMINATION_STATUS_LAUNCH_FAILED:
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
+ case base::TERMINATION_STATUS_OOM:
status = WebContentsAdapterClient::KilledTerminationStatus;
break;
case base::TERMINATION_STATUS_PROCESS_CRASHED:
-#if defined(OS_ANDROID)
+#if BUILDFLAG(IS_ANDROID)
case base::TERMINATION_STATUS_OOM_PROTECTED:
#endif
+#if BUILDFLAG(IS_WIN)
+ case base::TERMINATION_STATUS_INTEGRITY_FAILURE:
+#endif
status = WebContentsAdapterClient::CrashedTerminationStatus;
break;
case base::TERMINATION_STATUS_STILL_RUNNING:
@@ -1809,7 +1855,7 @@ void WebContentsAdapter::viewSource()
{
CHECK_INITIALIZED();
base::RecordAction(base::UserMetricsAction("ViewSource"));
- m_webContents->GetMainFrame()->ViewSource();
+ m_webContents->GetPrimaryMainFrame()->ViewSource();
}
bool WebContentsAdapter::canViewSource()
@@ -1921,7 +1967,7 @@ WebContentsAdapter::LifecycleState WebContentsAdapter::determineRecommendedState
// Do not discard PDFs as they might contain entry that is not saved and they
// don't remember their scrolling positions. See crbug.com/547286 and
// crbug.com/65244.
- if (m_webContents->GetContentsMimeType() == "application/pdf")
+ if (m_webContents->GetContentsMimeType() == kPDFMimeType)
return LifecycleState::Frozen;
return LifecycleState::Discarded;
@@ -1996,7 +2042,7 @@ void WebContentsAdapter::discard()
nullContents->SetWasDiscarded(true);
// Kill render process if this is the only page it's got.
- content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess();
+ content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess();
renderProcessHost->FastShutdownIfPossible(/* page_count */ 1u,
/* skip_unload_handlers */ false);
@@ -2033,9 +2079,9 @@ void WebContentsAdapter::undiscard()
// Create a RenderView with the initial empty document
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
- if (!rvh->IsRenderViewLive())
+ if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive())
static_cast<content::WebContentsImpl *>(m_webContents.get())
- ->CreateRenderViewForRenderManager(rvh, base::nullopt, nullptr);
+ ->CreateRenderViewForRenderManager(rvh, absl::nullopt, nullptr);
m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
m_adapterClient->initializationFinished();
m_adapterClient->selectionChanged();
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 26cfa1b64..62c3f087c 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -96,7 +60,7 @@ class ProfileQt;
class WebEnginePageHost;
class WebChannelIPCTransportHost;
-class Q_WEBENGINECORE_PRIVATE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<WebContentsAdapter> {
+class Q_WEBENGINECORE_EXPORT WebContentsAdapter : public QEnableSharedFromThis<WebContentsAdapter> {
public:
static QSharedPointer<WebContentsAdapter> createFromSerializedNavigationHistory(QDataStream &input, WebContentsAdapterClient *adapterClient);
WebContentsAdapter();
@@ -195,6 +159,7 @@ public:
void openDevToolsFrontend(QSharedPointer<WebContentsAdapter> devtoolsFrontend);
void closeDevToolsFrontend();
void devToolsFrontendDestroyed(DevToolsFrontendQt *frontend);
+ QString devToolsId();
void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
void grantMouseLockPermission(const QUrl &securityOrigin, bool granted);
@@ -208,6 +173,7 @@ public:
#if QT_CONFIG(webengine_webchannel)
QWebChannel *webChannel() const;
void setWebChannel(QWebChannel *, uint worldId);
+ WebChannelIPCTransportHost *webChannelTransport() { return m_webChannelTransport.get(); }
#endif
FindTextHelper *findTextHelper();
@@ -235,10 +201,13 @@ public:
bool isFindTextInProgress() const;
bool hasFocusedFrame() const;
void resetSelection();
+ void resetTouchSelectionController();
+ void changeTextDirection(bool leftToRight);
// meant to be used within WebEngineCore only
void initialize(content::SiteInstance *site);
content::WebContents *webContents() const;
+ content::WebContents *guestWebContents() const;
void updateRecommendedState();
void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
QWebEngineUrlRequestInterceptor* requestInterceptor() const;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index ddc371fa3..1a1474644 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -63,15 +27,16 @@
QT_FORWARD_DECLARE_CLASS(QKeyEvent)
QT_FORWARD_DECLARE_CLASS(QVariant)
+QT_FORWARD_DECLARE_CLASS(QWebEngineFileSystemAccessRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineFindTextResult)
QT_FORWARD_DECLARE_CLASS(QWebEngineLoadingInfo)
-QT_FORWARD_DECLARE_CLASS(QWebEngineQuotaRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineRegisterProtocolHandlerRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInfo)
QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInterceptor)
QT_FORWARD_DECLARE_CLASS(QWebEngineContextMenuRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineCertificateError)
QT_FORWARD_DECLARE_CLASS(QWebEngineSettings)
+QT_FORWARD_DECLARE_CLASS(QWebEngineWebAuthUxRequest)
namespace content {
struct DropData;
@@ -79,22 +44,24 @@ struct DropData;
namespace QtWebEngineCore {
+class AutofillPopupController;
class CertificateErrorController;
class ClientCertSelectController;
class AuthenticationDialogController;
class ColorChooserController;
+class DesktopMediaController;
class FilePickerController;
class JavaScriptDialogController;
class RenderWidgetHostViewQt;
class RenderWidgetHostViewQtDelegate;
class RenderWidgetHostViewQtDelegateClient;
-class TouchHandleDrawableClient;
+class TouchHandleDrawableDelegate;
class TouchSelectionMenuController;
class WebContentsAdapter;
class WebContentsDelegateQt;
class WebEngineSettings;
-class Q_WEBENGINECORE_PRIVATE_EXPORT WebContentsAdapterClient {
+class Q_WEBENGINECORE_EXPORT WebContentsAdapterClient {
public:
// This must match window_open_disposition_list.h.
enum WindowOpenDisposition {
@@ -183,6 +150,7 @@ public:
virtual void loadProgressChanged(int progress) = 0;
virtual void didUpdateTargetURL(const QUrl&) = 0;
virtual void selectionChanged() = 0;
+ virtual void zoomUpdateIsNeeded() = 0;
virtual void recentlyAudibleChanged(bool recentlyAudible) = 0;
virtual void renderProcessPidChanged(qint64 pid) = 0;
virtual QRectF viewportRect() const = 0;
@@ -200,6 +168,7 @@ public:
virtual void close() = 0;
virtual void windowCloseRejected() = 0;
virtual void contextMenuRequested(QWebEngineContextMenuRequest *request) = 0;
+ virtual void desktopMediaRequested(DesktopMediaController *) = 0;
virtual void navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame) = 0;
virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) = 0;
virtual bool isFullScreenMode() const = 0;
@@ -220,8 +189,8 @@ public:
virtual void runFeaturePermissionRequest(ProfileAdapter::PermissionType, const QUrl &securityOrigin) = 0;
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
- virtual void runQuotaRequest(QWebEngineQuotaRequest) = 0;
virtual void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) = 0;
+ virtual void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) = 0;
virtual QWebEngineSettings *webEngineSettings() const = 0;
RenderProcessTerminationStatus renderProcessExitStatus(int);
virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0;
@@ -238,14 +207,18 @@ public:
virtual void setToolTip(const QString& toolTipText) = 0;
virtual ClientType clientType() = 0;
virtual void printRequested() = 0;
- virtual TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &images) = 0;
+ virtual TouchHandleDrawableDelegate * createTouchHandleDelegate(const QMap<int, QImage> &images) = 0;
virtual void showTouchSelectionMenu(TouchSelectionMenuController *menuController, const QRect &bounds, const QSize &handleSize) = 0;
virtual void hideTouchSelectionMenu() = 0;
virtual void findTextFinished(const QWebEngineFindTextResult &result) = 0;
+ virtual void showAutofillPopup(AutofillPopupController *controller, const QRect &bounds,
+ bool autoselectFirstSuggestion) = 0;
+ virtual void hideAutofillPopup() = 0;
virtual ProfileAdapter *profileAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
virtual void releaseProfile() = 0;
+ virtual void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) = 0;
};
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index ef79c8f47..194274fcb 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -43,15 +7,22 @@
#include "web_contents_delegate_qt.h"
-#include "profile_adapter.h"
+#include "certificate_error_controller.h"
#include "color_chooser_controller.h"
#include "color_chooser_qt.h"
+#include "custom_handlers/protocol_handler_registry_factory.h"
+#include "custom_handlers/register_protocol_handler_request_controller_impl.h"
+#include "desktop_media_controller.h"
+#include "desktop_media_controller_p.h"
#include "file_picker_controller.h"
+#include "find_text_helper.h"
+#include "javascript_dialog_manager_qt.h"
#include "media_capture_devices_dispatcher.h"
+#include "native_web_keyboard_event_qt.h"
+#include "profile_adapter.h"
#include "profile_qt.h"
#include "qwebengineloadinginfo.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
-#include "register_protocol_handler_request_controller_impl.h"
#include "render_widget_host_view_qt.h"
#include "type_conversion.h"
#include "visited_links_manager_qt.h"
@@ -62,16 +33,15 @@
#include "web_engine_error.h"
#include "web_engine_settings.h"
#include "certificate_error_controller.h"
-#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
-#include "components/error_page/common/error.h"
-#include "components/error_page/common/localized_error.h"
+
+#include "components/custom_handlers/protocol_handler_registry.h"
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
-#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/invalidate_type.h"
+#include "content/public/browser/media_stream_request.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_view_host.h"
@@ -81,6 +51,7 @@
#include "content/public/common/url_constants.h"
#include "net/base/data_url.h"
#include "net/base/url_util.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#include <QDesktopServices>
#include <QTimer>
@@ -105,7 +76,6 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents,
: m_viewClient(adapterClient)
, m_findTextHelper(new FindTextHelper(webContents, adapterClient))
, m_loadingState(determineLoadingState(webContents))
- , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading)
, m_frameFocusedObserver(adapterClient)
{
webContents->SetDelegate(this);
@@ -180,6 +150,10 @@ static bool shouldUseActualURL(content::NavigationEntry *entry)
if (entry->GetPageType() != content::PAGE_TYPE_NORMAL)
return false;
+ // Show the virtual URL based on custom base, if present
+ if (!entry->GetBaseURLForDataURL().is_empty())
+ return false;
+
// Show invalid data URL
std::string mime_type, charset, data;
if (!net::DataURL::Parse(entry->GetURL(), &mime_type, &charset, &data))
@@ -215,8 +189,8 @@ void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source,
}
}
-QUrl WebContentsDelegateQt::url(content::WebContents* source) const {
-
+QUrl WebContentsDelegateQt::url(content::WebContents *source) const
+{
content::NavigationEntry *entry = source->GetController().GetVisibleEntry();
QUrl newUrl;
if (entry) {
@@ -227,18 +201,18 @@ QUrl WebContentsDelegateQt::url(content::WebContents* source) const {
GURL strippedUrl = net::SimplifyUrlForRequest(url);
newUrl = QUrl(QString("%1:%2").arg(content::kViewSourceScheme, QString::fromStdString(strippedUrl.spec())));
}
- // If there is a visible entry there are special cases when we dont wan't to use the actual URL
+ // If there is a visible entry there are special cases where we dont wan't to use the actual URL
if (newUrl.isEmpty())
newUrl = shouldUseActualURL(entry) ? toQt(url) : toQt(entry->GetVirtualURL());
}
m_pendingUrlUpdate = false;
return newUrl;
}
-void WebContentsDelegateQt::AddNewContents(content::WebContents* source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
- WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked)
+void WebContentsDelegateQt::AddNewContents(content::WebContents *source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
+ WindowOpenDisposition disposition, const blink::mojom::WindowFeatures &window_features, bool user_gesture, bool *was_blocked)
{
Q_UNUSED(source)
- QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, initial_pos, toQt(target_url), user_gesture);
+ QSharedPointer<WebContentsAdapter> newAdapter = createWindow(std::move(new_contents), disposition, window_features.bounds, toQt(target_url), user_gesture);
// Chromium can forget to pass user-agent override settings to new windows (see QTBUG-61774 and QTBUG-76249),
// so set it here. Note the actual value doesn't really matter here. Only the second value does, but we try
// to give the correct user-agent anyway.
@@ -273,9 +247,9 @@ void WebContentsDelegateQt::LoadProgressChanged(double progress)
bool WebContentsDelegateQt::HandleKeyboardEvent(content::WebContents *, const content::NativeWebKeyboardEvent &event)
{
- Q_ASSERT(!event.skip_in_browser);
+ Q_ASSERT(!event.skip_if_unhandled);
if (event.os_event)
- m_viewClient->unhandledKeyEvent(reinterpret_cast<QKeyEvent *>(event.os_event));
+ m_viewClient->unhandledKeyEvent(ToKeyEvent(event.os_event));
// FIXME: ?
return true;
}
@@ -284,9 +258,13 @@ void WebContentsDelegateQt::RenderFrameCreated(content::RenderFrameHost *render_
{
content::FrameTreeNode *node = static_cast<content::RenderFrameHostImpl *>(render_frame_host)->frame_tree_node();
m_frameFocusedObserver.addNode(node);
+
+ // If it's a child frame (render_widget_host_view_child_frame) install an InputEventObserver on
+ // it. Note that it is only needed for WheelEventAck.
+ RenderWidgetHostViewQt::registerInputEventObserver(web_contents(), render_frame_host);
}
-void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
+void WebContentsDelegateQt::PrimaryMainFrameRenderProcessGone(base::TerminationStatus status)
{
// RenderProcessHost::FastShutdownIfPossible results in TERMINATION_STATUS_STILL_RUNNING
if (status != base::TERMINATION_STATUS_STILL_RUNNING) {
@@ -301,6 +279,7 @@ void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
|| status == base::TERMINATION_STATUS_STILL_RUNNING) {
return;
}
+ LOG(INFO) << "ProcessGone: " << int(status) << " (" << web_contents()->GetCrashedErrorCode() << ")";
setLoadingState(LoadingState::Unloaded);
}
@@ -317,11 +296,13 @@ void WebContentsDelegateQt::RenderFrameHostChanged(content::RenderFrameHost *old
m_frameFocusedObserver.addNode(new_node);
// Is this a main frame?
- if (new_host->GetFrameOwnerElementType() == blink::mojom::FrameOwnerElementType::kNone) {
+ if (new_host->GetFrameOwnerElementType() == blink::FrameOwnerElementType::kNone) {
content::RenderProcessHost *renderProcessHost = new_host->GetProcess();
const base::Process &process = renderProcessHost->GetProcess();
- if (process.IsValid())
+ if (process.IsValid()) {
m_viewClient->renderProcessPidChanged(process.Pid());
+ m_viewClient->zoomUpdateIsNeeded();
+ }
}
}
}
@@ -332,6 +313,21 @@ void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, con
auto rwhv = static_cast<RenderWidgetHostViewQt *>(newHost->GetWidget()->GetView());
Q_ASSERT(rwhv->delegate());
rwhv->delegate()->adapterClientChanged(m_viewClient);
+ m_viewClient->zoomUpdateIsNeeded();
+ auto backgroundColor = m_viewClient->backgroundColor();
+ if (backgroundColor != Qt::white)
+ m_viewClient->webContentsAdapter()->setBackgroundColor(backgroundColor);
+ }
+}
+
+void WebContentsDelegateQt::RenderViewReady()
+{
+ // The render view might have returned after a crash without us getting a RenderViewHostChanged call
+ content::RenderWidgetHostView *newHostView = web_contents()->GetRenderWidgetHostView();
+ if (newHostView) {
+ auto *rwhv = static_cast<RenderWidgetHostViewQt *>(newHostView);
+ Q_ASSERT(rwhv->delegate());
+ rwhv->delegate()->updateAdapterClientIfNeeded(m_viewClient);
}
}
@@ -360,7 +356,7 @@ void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *naviga
if (!webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled))
navigation_handle->SetSilentlyIgnoreErrors();
- if (!navigation_handle->IsInMainFrame() || !web_contents()->IsLoadingToDifferentDocument())
+ if (!navigation_handle->IsInMainFrame() || navigation_handle->IsSameDocument())
return;
m_loadingInfo.url = toQt(navigation_handle->GetURL());
@@ -391,9 +387,10 @@ void WebContentsDelegateQt::emitLoadFinished(bool isErrorPage)
? QWebEngineLoadingInfo::LoadSucceededStatus
: (m_loadingInfo.errorCode == WebEngineError::UserAbortedError
? QWebEngineLoadingInfo::LoadStoppedStatus : QWebEngineLoadingInfo::LoadFailedStatus);
- auto errorDomain = static_cast<QWebEngineLoadingInfo::ErrorDomain>(WebEngineError::toQtErrorDomain(m_loadingInfo.errorCode));
QWebEngineLoadingInfo info(m_loadingInfo.url, loadStatus, m_loadingInfo.isErrorPage,
- m_loadingInfo.errorDescription, m_loadingInfo.errorCode, errorDomain);
+ m_loadingInfo.errorDescription, m_loadingInfo.errorCode,
+ QWebEngineLoadingInfo::ErrorDomain(m_loadingInfo.errorDomain),
+ m_loadingInfo.responseHeaders);
m_viewClient->loadFinished(std::move(info));
m_viewClient->updateNavigationActions();
}
@@ -421,14 +418,30 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
emitLoadCommitted();
}
+ const net::HttpResponseHeaders * const responseHeaders = navigation_handle->GetResponseHeaders();
+ if (responseHeaders != nullptr) {
+ m_loadingInfo.responseHeaders.clear();
+ std::size_t iter = 0;
+ std::string headerName;
+ std::string headerValue;
+ while (responseHeaders->EnumerateHeaderLines(&iter, &headerName, &headerValue)) {
+ m_loadingInfo.responseHeaders.insert(
+ QByteArray::fromStdString(headerName),
+ QByteArray::fromStdString(headerValue)
+ );
+ }
+ }
+
// Success is reported by DidFinishLoad, but DidFailLoad is now dead code and needs to be handled below
if (navigation_handle->GetNetErrorCode() == net::OK)
return;
// WebContentsObserver::DidFailLoad is not called any longer so we have to report the failure here.
- const net::Error error_code = navigation_handle->GetNetErrorCode();
- const std::string error_description = net::ErrorToString(error_code);
- didFailLoad(toQt(navigation_handle->GetURL()), error_code, toQt(error_description));
+ int error_code = navigation_handle->GetNetErrorCode();
+ if (error_code == net::ERR_HTTP_RESPONSE_CODE_FAILURE)
+ if (auto entry = web_contents()->GetController().GetActiveEntry())
+ error_code = entry->GetHttpStatusCode();
+ didFailLoad(toQt(navigation_handle->GetURL()), error_code, WebEngineError::toQtErrorDescription(error_code));
// The load will succede as an error-page load later, and we reported the original error above
if (navigation_handle->IsErrorPage()) {
@@ -440,34 +453,18 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
}
}
-void WebContentsDelegateQt::DidStartLoading()
-{
- // Based on TabLoadTracker::DidStartLoading
-
- if (!web_contents()->IsLoadingToDifferentDocument())
- return;
- if (m_loadingState == LoadingState::Loading) {
- DCHECK(m_didStartLoadingSeen);
- return;
- }
- m_didStartLoadingSeen = true;
-}
-
-void WebContentsDelegateQt::DidReceiveResponse()
+void WebContentsDelegateQt::PrimaryPageChanged(content::Page &)
{
- // Based on TabLoadTracker::DidReceiveResponse
+ // Based on TabLoadTracker::PrimaryPageChanged
- if (m_loadingState == LoadingState::Loading) {
- DCHECK(m_didStartLoadingSeen);
+ if (!web_contents()->ShouldShowLoadingUI())
return;
- }
// A transition to loading requires both DidStartLoading (navigation
// committed) and DidReceiveResponse (data has been transmitted over the
// network) events to occur. This is because NavigationThrottles can block
// actual network requests, but not the rest of the state machinery.
- if (m_didStartLoadingSeen)
- setLoadingState(LoadingState::Loading);
+ setLoadingState(LoadingState::Loading);
}
void WebContentsDelegateQt::DidStopLoading()
@@ -476,8 +473,7 @@ void WebContentsDelegateQt::DidStopLoading()
// NOTE: PageAlmostIdle feature not implemented
- if (m_loadingState == LoadingState::Loading)
- setLoadingState(LoadingState::Loaded);
+ setLoadingState(LoadingState::Loaded);
emitLoadFinished();
m_loadingInfo.clear();
@@ -493,16 +489,16 @@ void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QS
m_loadingInfo.success = false;
m_loadingInfo.url = url;
m_loadingInfo.errorCode = errorCode;
+ m_loadingInfo.errorDomain = WebEngineError::toQtErrorDomain(errorCode);
m_loadingInfo.errorDescription = errorDescription;
m_loadingInfo.triggersErrorPage = errorPageEnabled && !aborted;
}
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code)
{
- if (m_loadingState == LoadingState::Loading)
- setLoadingState(LoadingState::Loaded);
+ setLoadingState(LoadingState::Loaded);
- if (render_frame_host != web_contents()->GetMainFrame())
+ if (render_frame_host != web_contents()->GetPrimaryMainFrame())
return;
if (validated_url.spec() == content::kUnreachableWebDataURL) {
@@ -512,12 +508,7 @@ void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_h
emitLoadFinished(/* isErrorPage = */true);
return;
}
- // Qt6: Consider getting rid of the error_description (Chromium already has)
- base::string16 error_description;
- error_description = error_page::LocalizedError::GetErrorDetails(
- error_code <= 0 ? error_page::Error::kNetErrorDomain : error_page::Error::kHttpErrorDomain,
- error_code, false, false);
- didFailLoad(toQt(validated_url), error_code, toQt(error_description));
+ didFailLoad(toQt(validated_url), error_code, WebEngineError::toQtErrorDescription(error_code));
}
void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url)
@@ -546,6 +537,8 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
m_loadingInfo.success = http_statuscode < 400;
m_loadingInfo.url = toQt(validated_url);
m_loadingInfo.errorCode = http_statuscode;
+ m_loadingInfo.errorDomain = WebEngineError::toQtErrorDomain(http_statuscode);
+ m_loadingInfo.errorDescription = WebEngineError::toQtErrorDescription(http_statuscode);
m_loadingInfo.triggersErrorPage = triggersErrorPage;
}
@@ -558,10 +551,10 @@ void WebContentsDelegateQt::WebContentsCreated(content::WebContents * /*source_c
static_cast<WebContentsViewQt *>(view)->setFactoryClient(m_viewClient);
}
-content::ColorChooser *WebContentsDelegateQt::OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestion)
+std::unique_ptr<content::ColorChooser> WebContentsDelegateQt::OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestion)
{
Q_UNUSED(suggestion);
- ColorChooserQt *colorChooser = new ColorChooserQt(source, toQt(color));
+ auto colorChooser = std::make_unique<ColorChooserQt>(source, toQt(color));
m_viewClient->showColorDialog(colorChooser->controller());
return colorChooser;
@@ -575,13 +568,13 @@ void WebContentsDelegateQt::EnterFullscreenModeForTab(content::RenderFrameHost *
{
Q_UNUSED(options);
if (!m_viewClient->isFullScreenMode())
- m_viewClient->requestFullScreenMode(toQt(requesting_frame->GetLastCommittedURL()), true);
+ m_viewClient->requestFullScreenMode(toQt(requesting_frame->GetLastCommittedURL().DeprecatedGetOriginAsURL()), true);
}
void WebContentsDelegateQt::ExitFullscreenModeForTab(content::WebContents *web_contents)
{
if (m_viewClient->isFullScreenMode())
- m_viewClient->requestFullScreenMode(toQt(web_contents->GetLastCommittedURL().GetOrigin()), false);
+ m_viewClient->requestFullScreenMode(toQt(web_contents->GetLastCommittedURL().DeprecatedGetOriginAsURL()), false);
}
bool WebContentsDelegateQt::IsFullscreenForTabOrPending(const content::WebContents* web_contents)
@@ -603,7 +596,7 @@ void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost * /*frameHos
{
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)
+ for (std::vector<std::u16string>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it)
acceptedMimeTypes.append(toQt(*it));
m_filePickerController.reset(createFilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode),
@@ -616,7 +609,7 @@ void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost * /*frameHos
}
bool WebContentsDelegateQt::DidAddMessageToConsole(content::WebContents *source, blink::mojom::ConsoleMessageLevel log_level,
- const base::string16 &message, int32_t line_no, const base::string16 &source_id)
+ const std::u16string &message, int32_t line_no, const std::u16string &source_id)
{
Q_UNUSED(source);
m_viewClient->javaScriptConsoleMessage(mapToJavascriptConsoleMessageLevel(log_level), toQt(message), static_cast<int>(line_no), toQt(source_id));
@@ -628,9 +621,45 @@ void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_
m_findTextHelper->handleFindReply(source, request_id, number_of_matches, selection_rect, active_match_ordinal, final_update);
}
+static void processMediaAccessRequest(content::WebContents *webContents,
+ const content::MediaStreamRequest &request,
+ content::MediaResponseCallback callback,
+ content::DesktopMediaID id)
+{
+ MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(
+ webContents, request, std::move(callback), id);
+}
+
+static inline bool needsPickerDialog(const content::MediaStreamRequest &request)
+{
+ return (request.requested_video_device_id.empty() && // device already selected in chooseDesktopMedia
+ (request.video_type == blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE
+ || request.video_type == blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE));
+}
+
void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *web_contents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
{
- MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(web_contents, request, std::move(callback));
+ if (needsPickerDialog(request)) {
+#if QT_CONFIG(webengine_webrtc)
+ base::OnceCallback<void(content::DesktopMediaID)> cb = base::BindOnce(
+ &processMediaAccessRequest, web_contents, std::move(request), std::move(callback));
+ // ownership is taken by the request
+ auto *controller = new DesktopMediaController(
+ new DesktopMediaControllerPrivate(std::move(cb)));
+ QObject::connect(controller, &DesktopMediaController::mediaListsInitialized, [controller, delegate = AsWeakPtr()]() {
+ if (delegate)
+ delegate->adapterClient()->desktopMediaRequested(controller);
+ else
+ controller->deleteLater();
+ });
+#else
+ // To keep the old behavior return the default screen even if webrtc is disabled
+ processMediaAccessRequest(web_contents, std::move(request), std::move(callback),
+ content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0));
+#endif // QT_CONFIG(webengine_webrtc)
+ } else {
+ processMediaAccessRequest(web_contents, std::move(request), std::move(callback), {});
+ }
}
void WebContentsDelegateQt::SetContentsBounds(content::WebContents *source, const gfx::Rect &bounds)
@@ -641,8 +670,8 @@ void WebContentsDelegateQt::SetContentsBounds(content::WebContents *source, cons
QRect frameGeometry(toQt(bounds));
QRect geometry;
if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView())) {
- if (rwhv->delegate() && rwhv->delegate()->window())
- geometry = frameGeometry.marginsRemoved(rwhv->delegate()->window()->frameMargins());
+ if (rwhv->delegate() && rwhv->delegate()->Window())
+ geometry = frameGeometry.marginsRemoved(rwhv->delegate()->Window()->frameMargins());
}
m_viewClient->requestGeometryChange(geometry, frameGeometry);
}
@@ -653,12 +682,6 @@ void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const
m_viewClient->didUpdateTargetURL(toQt(url));
}
-void WebContentsDelegateQt::OnVisibilityChanged(content::Visibility visibility)
-{
- if (visibility != content::Visibility::HIDDEN)
- web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetMainFrame()->GetProcess()->GetID());
-}
-
void WebContentsDelegateQt::ActivateContents(content::WebContents* contents)
{
QWebEngineSettings *settings = m_viewClient->webEngineSettings();
@@ -673,7 +696,7 @@ void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_content
if (last_unlocked_by_target)
web_contents->GotResponseToLockMouseRequest(blink::mojom::PointerLockResult::kSuccess);
else
- m_viewClient->runMouseLockPermissionRequest(toQt(web_contents->GetLastCommittedURL().GetOrigin()));
+ m_viewClient->runMouseLockPermissionRequest(toQt(web_contents->GetLastCommittedURL().DeprecatedGetOriginAsURL()));
}
void WebContentsDelegateQt::overrideWebPreferences(content::WebContents *webContents, blink::web_pref::WebPreferences *webPreferences)
@@ -738,7 +761,7 @@ void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransitio
if (navigationAllowedByPolicy) {
m_viewClient->navigationRequested(pageTransitionToNavigationType(page_transition), url, navigationRequestAccepted, is_main_frame);
-#ifndef QT_NO_DESKTOPSERVICES
+#if QT_CONFIG(desktopservices)
if (navigationRequestAccepted)
QDesktopServices::openUrl(url);
#endif
@@ -749,7 +772,7 @@ void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransitio
if (!navigationAllowedByPolicy)
errorDescription = QStringLiteral("Launching external protocol forbidden by WebEngineSettings::UnknownUrlSchemePolicy");
else
- errorDescription = QStringLiteral("Launching external protocol suppressed by WebContentsAdapterClient::navigationRequested");
+ errorDescription = QStringLiteral("Launching external protocol suppressed by 'navigationRequested' API");
didFailLoad(url, net::Error::ERR_ABORTED, errorDescription);
}
}
@@ -763,12 +786,6 @@ void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool pr
m_viewClient->windowCloseRejected();
}
-void WebContentsDelegateQt::BeforeUnloadFired(bool proceed, const base::TimeTicks &proceed_time)
-{
- Q_UNUSED(proceed);
- Q_UNUSED(proceed_time);
-}
-
bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost *, const GURL& security_origin, blink::mojom::MediaStreamType type)
{
switch (type) {
@@ -778,7 +795,7 @@ bool WebContentsDelegateQt::CheckMediaAccessPermission(content::RenderFrameHost
return m_viewClient->profileAdapter()->checkPermission(toQt(security_origin), ProfileAdapter::VideoCapturePermission);
default:
LOG(INFO) << "WebContentsDelegateQt::CheckMediaAccessPermission: "
- << "Unsupported media stream type checked" << type;
+ << "Unsupported media stream type checked " << type;
return false;
}
}
@@ -787,10 +804,10 @@ void WebContentsDelegateQt::RegisterProtocolHandler(content::RenderFrameHost *fr
{
content::BrowserContext *context = frameHost->GetBrowserContext();
- ProtocolHandler handler =
- ProtocolHandler::CreateProtocolHandler(protocol, url);
+ custom_handlers::ProtocolHandler handler =
+ custom_handlers::ProtocolHandler::CreateProtocolHandler(protocol, url);
- ProtocolHandlerRegistry *registry =
+ custom_handlers::ProtocolHandlerRegistry *registry =
ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
if (registry->SilentlyHandleRegisterHandlerRequest(handler))
return;
@@ -804,10 +821,10 @@ void WebContentsDelegateQt::UnregisterProtocolHandler(content::RenderFrameHost *
{
content::BrowserContext* context = frameHost->GetBrowserContext();
- ProtocolHandler handler =
- ProtocolHandler::CreateProtocolHandler(protocol, url);
+ custom_handlers::ProtocolHandler handler =
+ custom_handlers::ProtocolHandler::CreateProtocolHandler(protocol, url);
- ProtocolHandlerRegistry* registry =
+ custom_handlers::ProtocolHandlerRegistry* registry =
ProtocolHandlerRegistryFactory::GetForBrowserContext(context);
registry->RemoveHandler(handler);
}
@@ -839,6 +856,15 @@ void WebContentsDelegateQt::ResourceLoadComplete(content::RenderFrameHost* rende
}
}
+void WebContentsDelegateQt::InnerWebContentsAttached(content::WebContents *inner_web_contents,
+ content::RenderFrameHost *render_frame_host,
+ bool is_full_page)
+{
+ blink::web_pref::WebPreferences guestPrefs = inner_web_contents->GetOrCreateWebPreferences();
+ webEngineSettings()->overrideWebPreferences(inner_web_contents, &guestPrefs);
+ inner_web_contents->SetWebPreferences(guestPrefs);
+}
+
FindTextHelper *WebContentsDelegateQt::findTextHelper()
{
return m_findTextHelper.data();
@@ -863,7 +889,7 @@ WebContentsDelegateQt::LoadingState WebContentsDelegateQt::determineLoadingState
{
// Based on TabLoadTracker::DetermineLoadingState
- if (contents->IsLoadingToDifferentDocument() && !contents->IsWaitingForResponse())
+ if (contents->ShouldShowLoadingUI() && !contents->IsWaitingForResponse())
return LoadingState::Loading;
content::NavigationController &controller = contents->GetController();
@@ -902,6 +928,7 @@ int &WebContentsDelegateQt::streamCount(blink::mojom::MediaStreamType type)
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE:
case blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE:
case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB:
+ case blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_SET:
return m_desktopStreamCount;
case blink::mojom::MediaStreamType::NO_SERVICE:
@@ -913,22 +940,36 @@ int &WebContentsDelegateQt::streamCount(blink::mojom::MediaStreamType type)
return m_videoStreamCount;
}
-void WebContentsDelegateQt::addDevices(const blink::MediaStreamDevices &devices)
+void WebContentsDelegateQt::addDevices(const blink::mojom::StreamDevices &devices)
{
- for (const auto &device : devices)
- ++streamCount(device.type);
+ if (devices.audio_device.has_value())
+ addDevice(devices.audio_device.value());
+ if (devices.video_device.has_value())
+ addDevice(devices.video_device.value());
webContentsAdapter()->updateRecommendedState();
}
-void WebContentsDelegateQt::removeDevices(const blink::MediaStreamDevices &devices)
+void WebContentsDelegateQt::removeDevices(const blink::mojom::StreamDevices &devices)
{
- for (const auto &device : devices)
- ++streamCount(device.type);
+ if (devices.audio_device.has_value())
+ removeDevice(devices.audio_device.value());
+ if (devices.video_device.has_value())
+ removeDevice(devices.video_device.value());
webContentsAdapter()->updateRecommendedState();
}
+void WebContentsDelegateQt::addDevice(const blink::MediaStreamDevice &device)
+{
+ ++streamCount(device.type);
+}
+
+void WebContentsDelegateQt::removeDevice(const blink::MediaStreamDevice &device)
+{
+ --streamCount(device.type);
+}
+
FrameFocusedObserver::FrameFocusedObserver(WebContentsAdapterClient *adapterClient)
: m_viewClient(adapterClient)
{}
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 4704f78fb..51004878d 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -1,58 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_CONTENTS_DELEGATE_QT_H
#define WEB_CONTENTS_DELEGATE_QT_H
#include "content/browser/renderer_host/frame_tree_node.h"
-#include "content/public/browser/media_capture_devices.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "base/callback.h"
+#include "web_contents_adapter_client.h"
-#include "color_chooser_controller.h"
-#include "find_text_helper.h"
-#include "javascript_dialog_manager_qt.h"
#include <QtCore/qlist.h>
-#include <QWebEngineCertificateError>
+#include <QtCore/qmap.h>
namespace blink {
namespace web_pref {
@@ -61,15 +21,15 @@ namespace blink {
}
namespace content {
- class ColorChooser;
- class SiteInstance;
- class JavaScriptDialogManager;
- class WebContents;
- struct ColorSuggestion;
+class ColorChooser;
+class JavaScriptDialogManager;
+class WebContents;
+struct MediaStreamRequest;
}
namespace QtWebEngineCore {
+class FindTextHelper;
class WebContentsAdapter;
class WebContentsAdapterClient;
class WebEngineSettings;
@@ -122,11 +82,11 @@ public:
content::WebContents *OpenURLFromTab(content::WebContents *source, const content::OpenURLParams &params) override;
void NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) override;
void AddNewContents(content::WebContents *source, std::unique_ptr<content::WebContents> new_contents, const GURL &target_url,
- WindowOpenDisposition disposition, const gfx::Rect &initial_pos, bool user_gesture, bool *was_blocked) override;
+ WindowOpenDisposition disposition, const blink::mojom::WindowFeatures &window_features, bool user_gesture, bool *was_blocked) override;
void CloseContents(content::WebContents *source) override;
void LoadProgressChanged(double progress) override;
bool HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override;
- content::ColorChooser* OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestions) override;
+ std::unique_ptr<content::ColorChooser> OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<blink::mojom::ColorSuggestionPtr> &suggestions) override;
void WebContentsCreated(content::WebContents *source_contents, int opener_render_process_id, int opener_render_frame_id,
const std::string &frame_name, const GURL &target_url, content::WebContents *new_contents) override;
content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) override;
@@ -137,7 +97,7 @@ public:
scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) override;
bool DidAddMessageToConsole(content::WebContents *source, blink::mojom::ConsoleMessageLevel log_level,
- const base::string16 &message, int32_t line_no, const base::string16 &source_id) override;
+ const std::u16string &message, int32_t line_no, const std::u16string &source_id) override;
void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) override;
void RequestMediaAccessPermission(content::WebContents *web_contents,
const content::MediaStreamRequest &request,
@@ -154,22 +114,23 @@ public:
// WebContentsObserver overrides
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
- void RenderProcessGone(base::TerminationStatus status) override;
+ void PrimaryMainFrameRenderProcessGone(base::TerminationStatus status) override;
void RenderFrameHostChanged(content::RenderFrameHost *old_host, content::RenderFrameHost *new_host) override;
void RenderViewHostChanged(content::RenderViewHost *old_host, content::RenderViewHost *new_host) override;
+ void RenderViewReady() override;
void DidStartNavigation(content::NavigationHandle *navigation_handle) override;
void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
- void DidStartLoading() override;
- void DidReceiveResponse() override;
+ void PrimaryPageChanged(content::Page &page) override;
void DidStopLoading() override;
void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code) override;
void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override;
- void BeforeUnloadFired(bool proceed, const base::TimeTicks& proceed_time) override;
- void OnVisibilityChanged(content::Visibility visibility) override;
void ActivateContents(content::WebContents* contents) override;
void ResourceLoadComplete(content::RenderFrameHost* render_frame_host,
const content::GlobalRequestID& request_id,
const blink::mojom::ResourceLoadInfo& resource_load_info) override;
+ void InnerWebContentsAttached(content::WebContents *inner_web_contents,
+ content::RenderFrameHost *render_frame_host,
+ bool is_full_page) override;
void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription);
void overrideWebPreferences(content::WebContents *, blink::web_pref::WebPreferences*);
@@ -179,8 +140,8 @@ public:
void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
FindTextHelper *findTextHelper();
- void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; }
- const SavePageInfo &savePageInfo() { return m_savePageInfo; }
+ void setSavePageInfo(SavePageInfo *spi) { m_savePageInfo.reset(spi); }
+ SavePageInfo *savePageInfo() { return m_savePageInfo.get(); }
WebEngineSettings *webEngineSettings() const;
WebContentsAdapter *webContentsAdapter() const;
@@ -191,8 +152,10 @@ public:
using LoadingState = WebContentsAdapterClient::LoadingState;
LoadingState loadingState() const { return m_loadingState; }
- void addDevices(const blink::MediaStreamDevices &devices);
- void removeDevices(const blink::MediaStreamDevices &devices);
+ void addDevices(const blink::mojom::StreamDevices &devices);
+ void removeDevices(const blink::mojom::StreamDevices &devices);
+ void addDevice(const blink::MediaStreamDevice &device);
+ void removeDevice(const blink::MediaStreamDevice &device);
bool isCapturingAudio() const { return m_audioStreamCount > 0; }
bool isCapturingVideo() const { return m_videoStreamCount > 0; }
@@ -218,10 +181,9 @@ private:
WebContentsAdapterClient *m_viewClient;
QScopedPointer<FindTextHelper> m_findTextHelper;
- SavePageInfo m_savePageInfo;
+ std::unique_ptr<SavePageInfo> m_savePageInfo;
QSharedPointer<FilePickerController> m_filePickerController;
LoadingState m_loadingState;
- bool m_didStartLoadingSeen;
FrameFocusedObserver m_frameFocusedObserver;
QString m_title;
@@ -237,9 +199,10 @@ private:
bool isLoading() const { return progress >= 0; }
QUrl url;
bool isErrorPage = false;
- int errorCode = 0;
+ int errorCode = 0, errorDomain = 0;
QString errorDescription;
bool triggersErrorPage = false;
+ QMultiMap<QByteArray, QByteArray> responseHeaders;
void clear() { *this = LoadingInfo(); }
} m_loadingInfo;
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 4b1db2cb0..023f9e99f 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_contents_view_qt.h"
@@ -237,7 +201,7 @@ void WebContentsViewQt::update(QWebEngineContextMenuRequest *request,
#endif
}
-void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *,
+void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost &,
const content::ContextMenuParams &params)
{
if (auto rwhv =
@@ -266,8 +230,9 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
blink::DragOperationsMask allowed_ops,
const gfx::ImageSkia &image,
const gfx::Vector2d &image_offset,
+ const gfx::Rect &drag_obj_rect,
const blink::mojom::DragEventSourceInfo &event_info,
- content::RenderWidgetHostImpl* source_rwh)
+ content::RenderWidgetHostImpl *source_rwh)
{
#if QT_CONFIG(draganddrop)
Q_UNUSED(event_info);
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 8b59fc34b..8754250e6 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_CONTENTS_VIEW_QT_H
#define WEB_CONTENTS_VIEW_QT_H
@@ -78,7 +42,7 @@ public:
content::RenderWidgetHostViewBase *CreateViewForChildWidget(content::RenderWidgetHost* render_widget_host) override;
- void SetPageTitle(const base::string16& title) override { }
+ void SetPageTitle(const std::u16string& title) override { }
void RenderViewReady() override { }
@@ -107,20 +71,24 @@ public:
gfx::Rect GetViewBounds() const override { return gfx::Rect(); }
void FocusThroughTabTraversal(bool reverse) override;
+ void OnCapturerCountChanged() override { QT_NOT_YET_IMPLEMENTED }
+ void FullscreenStateChanged(bool) override { }
+ void UpdateWindowControlsOverlay(const gfx::Rect &) override { QT_NOT_YET_IMPLEMENTED }
-#if defined(OS_MAC)
+#if BUILDFLAG(IS_MAC)
bool CloseTabAfterEventTrackingIfNeeded() override { QT_NOT_YET_IMPLEMENTED return false; }
-#endif // defined(OS_MAC)
+#endif
// content::RenderViewHostDelegateView overrides:
void StartDragging(const content::DropData& drop_data, blink::DragOperationsMask allowed_ops,
const gfx::ImageSkia& image, const gfx::Vector2d& image_offset,
+ const gfx::Rect& drag_obj_rect,
const blink::mojom::DragEventSourceInfo &event_info,
content::RenderWidgetHostImpl *source_rwh) override;
void UpdateDragCursor(ui::mojom::DragOperation dragOperation) override;
- void ShowContextMenu(content::RenderFrameHost *, const content::ContextMenuParams &params) override;
+ void ShowContextMenu(content::RenderFrameHost &, const content::ContextMenuParams &params) override;
void GotFocus(content::RenderWidgetHostImpl *render_widget_host) override;
void LostFocus(content::RenderWidgetHostImpl *render_widget_host) override;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 41aed57e2..94110d51c 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1,53 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_engine_context.h"
#include <math.h>
+#include <QtGui/private/qrhi_p.h>
#include "base/base_switches.h"
+#include "base/functional/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "base/run_loop.h"
-#include "base/task/post_task.h"
+#include "base/strings/string_split.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/thread_restrictions.h"
@@ -56,6 +22,7 @@
#include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
#endif
#include "chrome/common/chrome_switches.h"
+#include "content/common/process_visibility_tracker.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/compositor/viz_process_transport_factory.h"
@@ -69,29 +36,35 @@
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/app/mojo_ipc_support.h"
#include "content/browser/devtools/devtools_http_handler.h"
+#include "content/browser/gpu/gpu_main_thread_factory.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/startup_data_impl.h"
#include "content/browser/startup_helper.h"
+#include "content/browser/utility_process_host.h"
+#include "content/gpu/in_process_gpu_thread.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#if QT_CONFIG(webengine_pepper_plugins)
#include "content/public/browser/plugin_service.h"
+#endif
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
-#include "content/public/common/network_service_util.h"
+#include "content/renderer/in_process_renderer_thread.h"
+#include "content/utility/in_process_utility_thread.h"
#include "gpu/command_buffer/service/gpu_switches.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
+#include "gpu/config/gpu_finch_features.h"
#include "media/audio/audio_manager.h"
#include "media/base/media_switches.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/port_util.h"
-#include "ppapi/buildflags/buildflags.h"
#include "sandbox/policy/switches.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
@@ -102,14 +75,15 @@
#include "ui/base/ui_base_features.h"
#include "ui/events/event_switches.h"
#include "ui/native_theme/native_theme_features.h"
+#include "ui/gl/gl_utils.h"
#include "ui/gl/gl_switches.h"
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
#include "sandbox/win/src/sandbox_types.h"
#include "content/public/app/sandbox_helper_win.h"
-#endif // OS_WIN
+#endif // Q_OS_WIN
#if defined(Q_OS_MACOS)
-#include "base/mac/foundation_util.h"
+#include "base/apple/foundation_util.h"
#endif
#if QT_CONFIG(accessibility)
@@ -136,11 +110,13 @@
#include <qopenglcontext_platform.h>
#endif
#include <QQuickWindow>
+#include <QRegularExpression>
#include <QStringList>
#include <QSurfaceFormat>
#include <QNetworkProxy>
#include <QtGui/qpa/qplatformintegration.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtQuick/private/qsgrhisupport_p.h>
#include <QLoggingCategory>
#if QT_CONFIG(opengl)
@@ -149,23 +125,19 @@ Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
QT_END_NAMESPACE
#endif
+#define STRINGIFY_LITERAL(x) #x
+#define STRINGIFY_EXPANDED(x) STRINGIFY_LITERAL(x)
+
namespace QtWebEngineCore {
-#if QT_CONFIG(opengl)
-static bool usingANGLE()
-{
-#if defined(Q_OS_WIN)
- if (qt_gl_global_share_context())
- return qt_gl_global_share_context()->isOpenGLES();
- return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
-#else
- return false;
-#endif
-}
+Q_LOGGING_CATEGORY(webEngineContextLog, "qt.webenginecontext")
-static bool usingDefaultSGBackend()
+static bool usingSupportedSGBackend()
{
- if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL)
+ if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Vulkan
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Metal
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Direct3D11)
return false;
const QStringList args = QGuiApplication::arguments();
@@ -185,109 +157,254 @@ static bool usingDefaultSGBackend()
if (device.isEmpty())
device = qEnvironmentVariable("QMLSCENE_DEVICE");
- return device.isEmpty();
+ return device.isEmpty() || device == QLatin1String("rhi");
}
+#if QT_CONFIG(opengl)
bool usingSoftwareDynamicGL()
{
+ const char openGlVar[] = "QT_OPENGL";
if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
return true;
+
+ if (qEnvironmentVariableIsSet(openGlVar)) {
+ const QByteArray requested = qgetenv(openGlVar);
+ if (requested == "software")
+ return true;
+ }
#if defined(Q_OS_WIN)
HMODULE handle = QNativeInterface::QWGLContext::openGLModuleHandle();
wchar_t path[MAX_PATH];
DWORD size = GetModuleFileName(handle, path, MAX_PATH);
QFileInfo openGLModule(QString::fromWCharArray(path, size));
- return openGLModule.fileName() == QLatin1String("opengl32sw.dll");
+ return openGLModule.fileName().contains(QLatin1String("opengl32sw"),Qt::CaseInsensitive);
#else
return false;
#endif
}
-static const char *getGLType(bool enableGLSoftwareRendering)
+static bool openGLPlatformSupport()
{
- const char *glType = nullptr;
- const bool tryGL = (usingDefaultSGBackend() && !usingSoftwareDynamicGL()
- && QGuiApplicationPrivate::platformIntegration()->hasCapability(
- QPlatformIntegration::OpenGL))
- || enableGLSoftwareRendering;
- if (tryGL) {
- if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) {
- qWarning("WebEngineContext used before QtWebEngineCore::initialize() or OpenGL context "
- "creation failed.");
- } else {
- const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
- switch (sharedFormat.renderableType()) {
- case QSurfaceFormat::OpenGL:
- glType = gl::kGLImplementationDesktopName;
- // Check if Core profile was requested and is supported.
- if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
-#ifdef Q_OS_MACOS
- glType = gl::kGLImplementationCoreProfileName;
+ return QGuiApplicationPrivate::platformIntegration()->hasCapability(
+ QPlatformIntegration::OpenGL);
+}
+
+static std::string getGLType(bool enableGLSoftwareRendering, bool disableGpu)
+{
+ const bool tryGL =
+ usingSupportedSGBackend() && !usingSoftwareDynamicGL() && openGLPlatformSupport();
+ if (disableGpu || (!tryGL && !enableGLSoftwareRendering))
+ return gl::kGLImplementationDisabledName;
+
+#if defined(Q_OS_MACOS)
+ return gl::kGLImplementationANGLEName;
#else
- qWarning("An OpenGL Core Profile was requested, but it is not supported "
- "on the current platform. Falling back to a non-Core profile. "
- "Note that this might cause rendering issues.");
+#if defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
+ || QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ return gl::kGLImplementationANGLEName;
+ }
#endif
- }
- break;
- case QSurfaceFormat::OpenGLES:
- glType = usingANGLE() ? gl::kGLImplementationANGLEName
- : gl::kGLImplementationEGLName;
- break;
- case QSurfaceFormat::OpenVG:
- case QSurfaceFormat::DefaultRenderableType:
- default:
- // Shared contex created but no rederable type set.
- qWarning("Unsupported rendering surface format. Please open bug report at "
- "https://bugreports.qt.io");
- }
+
+ if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) {
+ qWarning("WebEngineContext is used before QtWebEngineQuick::initialize() or OpenGL context "
+ "creation failed.");
+ return gl::kGLImplementationDisabledName;
+ }
+
+ const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
+
+ switch (sharedFormat.renderableType()) {
+ case QSurfaceFormat::OpenGL:
+ if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
+ qWarning("An OpenGL Core Profile was requested, but it is not supported "
+ "on the current platform. Falling back to a non-Core profile. "
+ "Note that this might cause rendering issues.");
}
+ return gl::kGLImplementationDesktopName;
+ case QSurfaceFormat::OpenGLES:
+ return gl::kGLImplementationEGLName;
+ case QSurfaceFormat::OpenVG:
+ case QSurfaceFormat::DefaultRenderableType:
+ default:
+ // Shared contex created but no rederable type set.
+ qWarning("Unsupported rendering surface format. Please open bug report at "
+ "https://bugreports.qt.io");
}
- return glType;
+
+ return gl::kGLImplementationDisabledName;
+#endif // defined(Q_OS_MACOS)
}
#else
-static const char *getGLType(bool enableGLSoftwareRendering)
+static std::string getGLType(bool /*enableGLSoftwareRendering*/, bool disableGpu)
{
- return nullptr;
+ if (disableGpu)
+ return gl::kGLImplementationDisabledName;
+#if defined(Q_OS_MACOS)
+ return gl::kGLImplementationANGLEName;
+#elif defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
+ || QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ return gl::kGLImplementationANGLEName;
+ }
+#endif
+ return gl::kGLImplementationDisabledName;
}
#endif // QT_CONFIG(opengl)
+static std::string getVulkanType(base::CommandLine *cmd)
+{
+#if QT_CONFIG(webengine_vulkan)
+ if (cmd->HasSwitch(switches::kUseVulkan))
+ return cmd->GetSwitchValueASCII(switches::kUseVulkan);
+#endif
+
+ return "disabled";
+}
+
+static std::string getAngleType(const std::string &glType, base::CommandLine *cmd)
+{
+ if (glType == gl::kGLImplementationANGLEName) {
+ if (cmd->HasSwitch(switches::kUseANGLE))
+ return cmd->GetSwitchValueASCII(switches::kUseANGLE);
+
+#if defined(Q_OS_WIN)
+ return gl::kANGLEImplementationD3D11Name;
+#elif defined(Q_OS_MACOS)
+ return gl::kANGLEImplementationMetalName;
+#else
+ return gl::kANGLEImplementationDefaultName;
+#endif
+ }
+
+ return "disabled";
+}
+
+static quint64 getGPUVendorId()
+{
+#if QT_CONFIG(webengine_vulkan)
+ QVulkanInstance vulkanInstance;
+ vulkanInstance.setApiVersion(QVersionNumber(1, 1));
+ if (vulkanInstance.create()) {
+ QRhiVulkanInitParams params;
+ params.inst = &vulkanInstance;
+ QScopedPointer<QRhi> rhi(QRhi::create(QRhi::Vulkan, &params, QRhi::Flags(), nullptr));
+ return rhi->driverInfo().vendorId;
+ }
+#endif
+
+ return 0;
+}
+
+#if defined(Q_OS_WIN)
+static QString getAdapterLuid() {
+ static const bool preferSoftwareDevice = qEnvironmentVariableIntValue("QSG_RHI_PREFER_SOFTWARE_RENDERER");
+ QRhiD3D11InitParams rhiParams;
+ QRhi::Flags flags;
+ if (preferSoftwareDevice) {
+ flags |= QRhi::PreferSoftwareRenderer;
+ }
+ QScopedPointer<QRhi> rhi(QRhi::create(QRhi::D3D11,&rhiParams,flags,nullptr));
+ // mimic what QSGRhiSupport and QBackingStoreRhi does
+ if (!rhi && !preferSoftwareDevice) {
+ flags |= QRhi::PreferSoftwareRenderer;
+ rhi.reset(QRhi::create(QRhi::D3D11, &rhiParams, flags));
+ }
+ if (rhi) {
+ const QRhiD3D11NativeHandles *handles =
+ static_cast<const QRhiD3D11NativeHandles *>(rhi->nativeHandles());
+ Q_ASSERT(handles);
+ return QString("%1,%2").arg(handles->adapterLuidHigh).arg(handles->adapterLuidLow);
+ } else {
+ return QString();
+ }
+}
+#endif
+
#if QT_CONFIG(webengine_pepper_plugins)
void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
{
}
#endif
-static void logContext(const char *glType, base::CommandLine *cmd)
+static void logContext(const std::string &glType, base::CommandLine *cmd)
{
- QLoggingCategory webEngineContextLog("qt.webenginecontext");
- if (webEngineContextLog.isInfoEnabled()) {
+ if (Q_UNLIKELY(webEngineContextLog().isDebugEnabled())) {
+ QStringList log;
+ log << "\n";
+
+ log << "Chromium GL Backend:" << glType.c_str() << "\n";
+ log << "Chromium ANGLE Backend:" << getAngleType(glType, cmd).c_str() << "\n";
+ log << "Chromium Vulkan Backend:" << getVulkanType(cmd).c_str() << "\n";
+ log << "\n";
+
+ log << "QSG RHI Backend:" << QSGRhiSupport::instance()->rhiBackendName() << "\n";
+ log << "QSG RHI Backend Supported:" << (usingSupportedSGBackend() ? "yes" : "no") << "\n";
+ log << "GPU Vendor:";
+ if (quint64 vendorId = getGPUVendorId()) {
+ switch (vendorId) {
+ case 0x1002:
+ log << "AMD";
+ break;
+ case 0x10DE:
+ log << "NVIDIA";
+ break;
+ case 0x8086:
+ log << "Intel";
+ break;
+ case 0x1010:
+ log << "ImgTec";
+ break;
+ case 0x13B5:
+ log << "ARM";
+ break;
+ case 0x5143:
+ log << "Qualcomm";
+ break;
+ default:
+ break;
+ }
+ log << QString("(0x%1)\n").arg(vendorId, 0, 16);
+ } else {
+ log << "Unable to detect\n";
+ }
+ log << "\n";
+
#if QT_CONFIG(opengl)
- const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
- const auto profile = QMetaEnum::fromType<QSurfaceFormat::OpenGLContextProfile>().valueToKey(
- sharedFormat.profile());
- const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
- sharedFormat.renderableType());
- const base::CommandLine::SwitchMap switch_map = cmd->GetSwitches();
- QStringList params;
- for (const auto &pair : switch_map)
- params << " * " << toQt(pair.first)
- << toQt(pair.second) << "\n";
- qCInfo(webEngineContextLog,
- "\n\nGLImplementation: %s\n"
- "Surface Type: %s\n"
- "Surface Profile: %s\n"
- "Surface Version: %d.%d\n"
- "Using Default SG Backend: %s\n"
- "Using Software Dynamic GL: %s\n"
- "Using Angle: %s\n\n"
- "Init Parameters:\n %s",
- glType, type, profile, sharedFormat.majorVersion(), sharedFormat.minorVersion(),
- usingDefaultSGBackend() ? "yes" : "no", usingSoftwareDynamicGL() ? "yes" : "no",
- usingANGLE() ? "yes" : "no", qPrintable(params.join(" ")));
-#else
- qCInfo(webEngineContextLog) << "WebEngine compiled with no opengl enabled.";
-#endif //QT_CONFIG(opengl)
+#if defined(USE_OZONE)
+ log << "Using GLX:" << (GLContextHelper::getGlxPlatformInterface() ? "yes" : "no") << "\n";
+ log << "Using EGL:" << (GLContextHelper::getEglPlatformInterface() ? "yes" : "no") << "\n";
+#endif
+ log << "Using Shared GL:" << (qt_gl_global_share_context() ? "yes" : "no") << "\n";
+ if (qt_gl_global_share_context()) {
+ log << "Using Software Dynamic GL:" << (usingSoftwareDynamicGL() ? "yes" : "no")
+ << "\n";
+
+ const QSurfaceFormat sharedFormat = qt_gl_global_share_context()
+ ? qt_gl_global_share_context()->format()
+ : QSurfaceFormat::defaultFormat();
+ const auto profile =
+ QMetaEnum::fromType<QSurfaceFormat::OpenGLContextProfile>().valueToKey(
+ sharedFormat.profile());
+ const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
+ sharedFormat.renderableType());
+ log << "Surface Type:" << type << "\n";
+ log << "Surface Profile:" << profile << "\n";
+ log << "Surface Version:"
+ << QString("%1.%2")
+ .arg(sharedFormat.majorVersion())
+ .arg(sharedFormat.minorVersion())
+ << "\n";
+ }
+ log << "\n";
+#endif // QT_CONFIG(opengl)
+
+ log << "Init Parameters:\n";
+ const base::CommandLine::SwitchMap switchMap = cmd->GetSwitches();
+ for (const auto &pair : switchMap)
+ log << " * " << toQt(pair.first) << toQt(pair.second) << "\n";
+
+ qCDebug(webEngineContextLog) << qPrintable(log.join(" "));
}
}
@@ -314,26 +431,14 @@ static void setupProxyPac(base::CommandLine *commandLine)
}
}
-static bool waitForViz = false;
-static void completeVizCleanup()
-{
- waitForViz = false;
-}
-
static void cleanupVizProcess()
{
auto gpuChildThread = content::GpuChildThread::instance();
if (!gpuChildThread)
return;
- auto vizMain = gpuChildThread->viz_main();
- auto vizCompositorThreadRunner = vizMain->viz_compositor_thread_runner();
- if (!vizCompositorThreadRunner)
- return;
- waitForViz = true;
content::GetHostFrameSinkManager()->SetConnectionLostCallback(base::DoNothing());
auto factory = static_cast<content::VizProcessTransportFactory*>(content::ImageTransportFactory::GetInstance());
factory->PrepareForShutDown();
- vizCompositorThreadRunner->CleanupForShutdown(base::BindOnce(&completeVizCleanup));
}
static QStringList parseEnvCommandLine(const QString &cmdLine)
@@ -446,11 +551,6 @@ void WebEngineContext::destroy()
// on IO thread (triggered by ~BrowserMainRunner). But by that time the UI
// task runner is not working anymore so we need to do this earlier.
cleanupVizProcess();
- while (waitForViz) {
- flushMessages();
- QThread::msleep(50);
- }
- destroyGpuProcess();
// Flush the UI message loop before quitting.
flushMessages();
@@ -485,7 +585,6 @@ void WebEngineContext::destroy()
GLContextHelper::destroy();
// These would normally be in the content-runner, but we allocated them separately:
- m_startupData.reset();
m_mojoIpcSupport.reset();
m_discardableSharedMemoryManager.reset();
@@ -508,7 +607,6 @@ WebEngineContext::~WebEngineContext()
Q_ASSERT(!m_devtoolsServer);
Q_ASSERT(!m_browserRunner);
Q_ASSERT(m_profileAdapters.isEmpty());
- delete s_syncPointManager.fetchAndStoreRelaxed(nullptr);
}
WebEngineContext *WebEngineContext::current()
@@ -582,18 +680,6 @@ ProxyAuthentication WebEngineContext::qProxyNetworkAuthentication(QString host,
const static char kChromiumFlagsEnv[] = "QTWEBENGINE_CHROMIUM_FLAGS";
const static char kDisableSandboxEnv[] = "QTWEBENGINE_DISABLE_SANDBOX";
-const static char kDisableInProcGpuThread[] = "QTWEBENGINE_DISABLE_GPU_THREAD";
-
-// static
-bool WebEngineContext::isGpuServiceOnUIThread()
-{
- static bool threadedGpu =
-#if QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
- QOpenGLContext::supportsThreadedOpenGL() &&
-#endif
- !qEnvironmentVariableIsSet(kDisableInProcGpuThread);
- return !threadedGpu;
-}
static void initializeFeatureList(base::CommandLine *commandLine, std::vector<std::string> enableFeatures, std::vector<std::string> disableFeatures)
{
@@ -645,7 +731,7 @@ WebEngineContext::WebEngineContext()
#if defined(Q_OS_MACOS)
// The bundled handling is currently both completely broken in Chromium,
// and unnecessary for us.
- base::mac::SetOverrideAmIBundled(false);
+ base::apple::SetOverrideAmIBundled(false);
#endif
base::ThreadPoolInstance::Create("Browser");
@@ -671,16 +757,11 @@ WebEngineContext::WebEngineContext()
// Allow us to inject javascript like any webview toolkit.
content::RenderFrameHost::AllowInjectingJavaScript();
- QStringList appArgs = QCoreApplication::arguments();
-
bool useEmbeddedSwitches = false;
-#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
- useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
-#else
- useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
-#endif
+ bool enableGLSoftwareRendering = false;
+ base::CommandLine *parsedCommandLine =
+ initCommandLine(useEmbeddedSwitches, enableGLSoftwareRendering);
- base::CommandLine* parsedCommandLine = commandLine();
setupProxyPac(parsedCommandLine);
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
@@ -697,8 +778,6 @@ WebEngineContext::WebEngineContext()
qInfo() << "Sandboxing disabled by user.";
}
- parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing);
-
// Do not advertise a feature we have removed at compile time
parsedCommandLine->AppendSwitch(switches::kDisableSpeechAPI);
@@ -714,21 +793,62 @@ WebEngineContext::WebEngineContext()
// Avoid crashing when websites tries using this feature (since 83)
disableFeatures.push_back(features::kInstalledApp.name);
+ // Not implemented but it overrides the devtools eyedropper
+ // Should be sync with kEyeDropper base::Feature
+ parsedCommandLine->AppendSwitchASCII(switches::kDisableBlinkFeatures, "EyeDropperAPI");
+ disableFeatures.push_back(features::kEyeDropper.name);
+
// Explicitly tell Chromium about default-on features we do not support
disableFeatures.push_back(features::kBackgroundFetch.name);
disableFeatures.push_back(features::kWebOTP.name);
disableFeatures.push_back(features::kWebPayments.name);
disableFeatures.push_back(features::kWebUsb.name);
- disableFeatures.push_back(media::kPictureInPicture.name);
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
enableFeatures.push_back(features::kOverlayScrollbar.name);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
- parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
+#if QT_CONFIG(webengine_vulkan) && defined(USE_OZONE)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ enableFeatures.push_back(features::kVulkan.name);
+ parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
+ switches::kVulkanImplementationNameNative);
+ const char deviceExtensionsVar[] = "QT_VULKAN_DEVICE_EXTENSIONS";
+ QByteArrayList requiredDeviceExtensions = { "VK_KHR_external_memory_fd",
+ "VK_EXT_external_memory_dma_buf",
+ "VK_EXT_image_drm_format_modifier" };
+ if (qEnvironmentVariableIsSet(deviceExtensionsVar)) {
+ QByteArrayList envExtList = qgetenv(deviceExtensionsVar).split(';');
+ int found = 0;
+ for (const QByteArray &ext : requiredDeviceExtensions) {
+ if (envExtList.contains(ext))
+ found++;
+ }
+ if (found != requiredDeviceExtensions.size()) {
+ qWarning().nospace()
+ << "Vulkan rendering may fail because " << deviceExtensionsVar
+ << " environment variable is already set but it doesn't contain"
+ << " some of the required Vulkan device extensions:\n"
+ << qPrintable(requiredDeviceExtensions.join('\n'));
+ }
+ } else {
+ qputenv(deviceExtensionsVar, requiredDeviceExtensions.join(';'));
+ }
+ }
+#endif // QT_CONFIG(webengine_vulkan) && defined(USE_OZONE)
+
+#if defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
+ || QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ const QString luid = getAdapterLuid();
+ if (!luid.isEmpty())
+ parsedCommandLine->AppendSwitchASCII(switches::kUseAdapterLuid, luid.toStdString());
+ }
+#endif
+
initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
GLContextHelper::initialize();
@@ -737,84 +857,91 @@ WebEngineContext::WebEngineContext()
// bitmaps, use software rendering via software OpenGL. This might be less
// performant, but at least provides WebGL support.
// TODO(miklocek), check if this still works with latest chromium
- const bool enableGLSoftwareRendering = appArgs.contains(QStringLiteral("--enable-webgl-software-rendering"));
- const char *glType = getGLType(enableGLSoftwareRendering);
-
- if (glType) {
-#if QT_CONFIG(opengl)
+ const bool disableGpu = parsedCommandLine->HasSwitch(switches::kDisableGpu);
+ std::string glType;
+ if (parsedCommandLine->HasSwitch(switches::kUseGL))
+ glType = parsedCommandLine->GetSwitchValueASCII(switches::kUseGL);
+ else {
+ glType = getGLType(enableGLSoftwareRendering, disableGpu);
parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
- parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
+ }
+
+ parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
+
+ if (glType != gl::kGLImplementationDisabledName) {
if (enableGLSoftwareRendering) {
parsedCommandLine->AppendSwitch(switches::kDisableGpuRasterization);
parsedCommandLine->AppendSwitch(switches::kIgnoreGpuBlocklist);
}
- const QSurfaceFormat sharedFormat = QOpenGLContext::globalShareContext()->format();
- if (sharedFormat.profile() == QSurfaceFormat::CompatibilityProfile)
- parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext);
+#if QT_CONFIG(opengl)
+ if (glType != gl::kGLImplementationANGLEName) {
+ QOpenGLContext *shareContext = QOpenGLContext::globalShareContext();
+ Q_ASSERT(shareContext);
+ const QSurfaceFormat sharedFormat = shareContext->format();
+ if (sharedFormat.profile() == QSurfaceFormat::CompatibilityProfile)
+ parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext);
#if defined(Q_OS_WIN)
- // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
- // an OpenGL Core Profile context. If the switch is not set, it would always try to create a
- // Core Profile context, even if Qt uses a legacy profile, which causes
- // "Could not share GL contexts" warnings, because it's not possible to share between Core and
- // legacy profiles. See GLContextWGL::Initialize().
- // Given that Desktop GL Core profile is not currently supported on Windows anyway, pass this
- // switch to get rid of the warnings.
- //
- // The switch is also used to determine which version of OpenGL ES to use (2 or 3) when using
- // ANGLE.
- // If the switch is not set, Chromium will always try to create an ES3 context, even if Qt uses
- // an ES2 context, which causes resource sharing issues (black screen),
- // see gpu::gles2::GenerateGLContextAttribs().
- // Make sure to disable ES3 context creation when using ES2.
- const bool isGLES2Context = QOpenGLContext::globalShareContext()->isOpenGLES()
- && QOpenGLContext::globalShareContext()->format().majorVersion() == 2;
- if (!usingANGLE() || isGLES2Context)
- parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
+ // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
+ // an OpenGL Core Profile context. If the switch is not set, it would always try to create a
+ // Core Profile context, even if Qt uses a legacy profile, which causes
+ // "Could not share GL contexts" warnings, because it's not possible to share between Core and
+ // legacy profiles. See GLContextWGL::Initialize().
+ if (sharedFormat.renderableType() == QSurfaceFormat::OpenGL
+ && sharedFormat.profile() != QSurfaceFormat::CoreProfile) {
+ gl::GlWorkarounds workarounds = gl::GetGlWorkarounds();
+ workarounds.disable_es3gl_context = true;
+ gl::SetGlWorkarounds(workarounds);
+ }
#endif
+ }
#endif //QT_CONFIG(opengl)
- } else {
+ } else if (!disableGpu) {
parsedCommandLine->AppendSwitch(switches::kDisableGpu);
}
+ logContext(glType, parsedCommandLine);
+
registerMainThreadFactories();
content::ContentMainParams contentMainParams(m_mainDelegate.get());
-#if defined(OS_WIN)
+ contentMainParams.setup_signal_handlers = false;
+#if defined(Q_OS_WIN)
contentMainParams.sandbox_info = QtWebEngineSandbox::staticSandboxInterfaceInfo();
- sandbox::SandboxInterfaceInfo sandbox_info = {0};
+ sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
if (!contentMainParams.sandbox_info) {
content::InitializeSandboxInfo(&sandbox_info);
contentMainParams.sandbox_info = &sandbox_info;
}
#endif
- m_contentRunner->Initialize(contentMainParams);
+ m_contentRunner->Initialize(std::move(contentMainParams));
mojo::core::Configuration mojoConfiguration;
mojoConfiguration.is_broker_process = true;
mojo::core::Init(mojoConfiguration);
- // This block mirrors ContentMainRunnerImpl::RunServiceManager():
- m_mainDelegate->PreCreateMainMessageLoop();
+ // This block mirrors ContentMainRunnerImpl::RunBrowser():
+ m_mainDelegate->PreBrowserMain();
base::MessagePump::OverrideMessagePumpForUIFactory(messagePumpFactory);
content::BrowserTaskExecutor::Create();
- m_mainDelegate->PostEarlyInitialization(false);
+ m_mainDelegate->PostEarlyInitialization({});
content::StartBrowserThreadPool();
content::BrowserTaskExecutor::PostFeatureListSetup();
- tracing::InitTracingPostThreadPoolStartAndFeatureList();
- m_discardableSharedMemoryManager = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
+ tracing::InitTracingPostThreadPoolStartAndFeatureList(false);
base::PowerMonitor::Initialize(std::make_unique<base::PowerMonitorDeviceSource>());
+ content::ProcessVisibilityTracker::GetInstance();
+ m_discardableSharedMemoryManager = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
m_mojoIpcSupport = std::make_unique<content::MojoIpcSupport>(content::BrowserTaskExecutor::CreateIOThread());
download::SetIOTaskRunner(m_mojoIpcSupport->io_thread()->task_runner());
- m_startupData = m_mojoIpcSupport->CreateBrowserStartupData();
+ std::unique_ptr<content::StartupData> startupData = m_mojoIpcSupport->CreateBrowserStartupData();
// Once the MessageLoop has been created, attach a top-level RunLoop.
m_runLoop.reset(new base::RunLoop);
m_runLoop->BeforeRun();
- content::MainFunctionParams mainParams(*base::CommandLine::ForCurrentProcess());
- mainParams.startup_data = m_startupData.get();
- m_browserRunner->Initialize(mainParams);
+ content::MainFunctionParams mainParams(base::CommandLine::ForCurrentProcess());
+ mainParams.startup_data = std::move(startupData);
+ m_browserRunner->Initialize(std::move(mainParams));
m_devtoolsServer.reset(new DevToolsServerQt());
m_devtoolsServer->start();
@@ -826,14 +953,7 @@ WebEngineContext::WebEngineContext()
// Initialize WebCacheManager here to ensure its subscription to render process creation events.
web_cache::WebCacheManager::GetInstance();
- base::ThreadRestrictions::SetIOAllowed(true);
-
- if (parsedCommandLine->HasSwitch(network::switches::kExplicitlyAllowedPorts)) {
- std::string allowedPorts = parsedCommandLine->GetSwitchValueASCII(network::switches::kExplicitlyAllowedPorts);
- net::SetExplicitlyAllowedPorts(allowedPorts);
- }
-
-#if defined(OS_LINUX)
+#if defined(Q_OS_LINUX)
media::AudioManager::SetGlobalAppName(QCoreApplication::applicationName().toStdString());
#endif
@@ -844,7 +964,7 @@ WebEngineContext::WebEngineContext()
// be created from the FILE thread, and that GetPluginInfoArray is synchronous, it
// can't loads plugins synchronously from the IO thread to serve the render process' request
// and we need to make sure that it happened beforehand.
- content::PluginService::GetInstance()->GetPlugins(base::Bind(&dummyGetPluginCallback));
+ content::PluginService::GetInstance()->GetPlugins(base::BindOnce(&dummyGetPluginCallback));
#endif
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -856,8 +976,6 @@ WebEngineContext::WebEngineContext()
#endif
content::WebUIControllerFactory::RegisterFactory(WebUIControllerFactoryQt::GetInstance());
-
- logContext(glType, parsedCommandLine);
}
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -877,47 +995,71 @@ WebRtcLogUploader *WebEngineContext::webRtcLogUploader()
#endif
-static QMutex s_spmMutex;
-QAtomicPointer<gpu::SyncPointManager> WebEngineContext::s_syncPointManager;
-
-gpu::SyncPointManager *WebEngineContext::syncPointManager()
+base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
+ bool &enableGLSoftwareRendering)
{
- if (gpu::SyncPointManager *spm = s_syncPointManager.loadAcquire())
- return spm;
- QMutexLocker lock(&s_spmMutex);
- if (!s_syncPointManager)
- s_syncPointManager.storeRelaxed(new gpu::SyncPointManager());
- return s_syncPointManager.loadRelaxed();
-}
+ if (!base::CommandLine::CreateEmpty())
+ qFatal("base::CommandLine has been initialized unexpectedly.");
-base::CommandLine* WebEngineContext::commandLine() {
- if (base::CommandLine::CreateEmpty()) {
- base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
- QStringList appArgs = QCoreApplication::arguments();
- if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
- appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
- appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
+ QStringList appArgs = QCoreApplication::arguments();
+ if (appArgs.empty()) {
+ qFatal("Argument list is empty, the program name is not passed to QCoreApplication. "
+ "base::CommandLine cannot be properly initialized.");
+ }
+
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ int index = appArgs.indexOf(QRegularExpression(QLatin1String("--webEngineArgs"),
+ QRegularExpression::CaseInsensitiveOption));
+ if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
+ appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
+ appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
+ if (index > -1)
+ qWarning("Note 'webEngineArgs' are overridden by QTWEBENGINE_CHROMIUM_FLAGS");
+ } else {
+ if (index > -1) {
+ appArgs.erase(appArgs.begin() + 1, appArgs.begin() + index + 1);
+ } else {
+ appArgs = appArgs.mid(0, 1);
}
-#ifdef Q_OS_WIN
- appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+ }
+#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
+ useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
+#else
+ useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
#endif
- appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
- appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+ enableGLSoftwareRendering =
+ appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+ appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
+ appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+
+ bool isRemoteDebugPort =
+ (-1
+ != appArgs.indexOf(QRegularExpression(QStringLiteral("--remote-debugging-port=.*"),
+ QRegularExpression::CaseInsensitiveOption)))
+ || !qEnvironmentVariable("QTWEBENGINE_REMOTE_DEBUGGING").isEmpty();
+ bool isRemoteAllowOrigins =
+ (-1
+ != appArgs.indexOf(QRegularExpression(QStringLiteral("--remote-allow-origins=.*"),
+ QRegularExpression::CaseInsensitiveOption)));
+
+ if (isRemoteDebugPort && !isRemoteAllowOrigins) {
+ appArgs.append(QStringLiteral("--remote-allow-origins=*"));
+ qWarning("Added {--remote-allow-origins=*} to command-line arguments "
+ "to avoid web socket connection errors during remote debugging.");
+ }
- base::CommandLine::StringVector argv;
- argv.resize(appArgs.size());
+ base::CommandLine::StringVector argv;
+ argv.resize(appArgs.size());
#if defined(Q_OS_WIN)
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = toString16(appArgs[i]);
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdWString();
#else
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = appArgs[i].toStdString();
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdString();
#endif
- parsedCommandLine->InitFromArgv(argv);
- return parsedCommandLine;
- } else {
- return base::CommandLine::ForCurrentProcess();
- }
+ parsedCommandLine->InitFromArgv(argv);
+
+ return parsedCommandLine;
}
bool WebEngineContext::closingDown()
@@ -925,45 +1067,34 @@ bool WebEngineContext::closingDown()
return m_closingDown;
}
+void WebEngineContext::registerMainThreadFactories()
+{
+ content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
+ content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
+ content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread);
+}
+
} // namespace
QT_BEGIN_NAMESPACE
-/*!
- \relates <qtwebenginecoreglobal.h>
- \since 6.2
-
- Returns the version number of Qt WebEngine at run-time as a string
- (for example, "6.2.0"). This may be a different version than the
- version the application was compiled against, and a different version
- than Qt.
-*/
const char *qWebEngineVersion() noexcept
{
- return QTWEBENGINECORE_VERSION_STR;
+ return STRINGIFY_EXPANDED(QTWEBENGINECORE_VERSION_STR);
}
-/*!
- \relates <qtwebenginecoreglobal.h>
- \since 6.2
+const char *qWebEngineProcessName() noexcept
+{
+ return STRINGIFY_EXPANDED(QTWEBENGINEPROCESS_NAME);
+}
- Returns the version number of Chromium used by Qt WebEngine at run-time
- as a string (for example, "83.0.4103.122").
-*/
const char *qWebEngineChromiumVersion() noexcept
{
- return CHROMIUM_VERSION;
+ return STRINGIFY_EXPANDED(CHROMIUM_VERSION);
}
-/*!
- \relates <qtwebenginecoreglobal.h>
- \since 6.3
-
- Returns the version number of last Chromium version security patches have been
- merged from.
-*/
const char *qWebEngineChromiumSecurityPatchVersion() noexcept
{
- return "92.0.4515.166"; // FIXME: Remember to update
+ return "122.0.6261.128"; // FIXME: Remember to update
}
QT_END_NAMESPACE
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 27eae95bf..50b080db1 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_ENGINE_CONTEXT_H
#define WEB_ENGINE_CONTEXT_H
@@ -57,11 +21,9 @@ class CommandLine;
namespace content {
class BrowserMainRunner;
class ContentMainRunner;
-class GpuProcess;
class GpuThreadController;
class InProcessChildThreadParams;
class MojoIpcSupport;
-struct StartupData;
}
namespace discardable_memory {
@@ -70,7 +32,6 @@ class DiscardableSharedMemoryManager;
namespace gpu {
struct GpuPreferences;
-class SyncPointManager;
}
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -120,11 +81,8 @@ public:
void addProfileAdapter(ProfileAdapter *profileAdapter);
void removeProfileAdapter(ProfileAdapter *profileAdapter);
void destroy();
- static base::CommandLine* commandLine();
-
- static gpu::SyncPointManager *syncPointManager();
-
- static bool isGpuServiceOnUIThread();
+ static base::CommandLine *initCommandLine(bool &useEmbeddedSwitches,
+ bool &enableGLSoftwareRendering);
private:
friend class base::RefCounted<WebEngineContext>;
@@ -133,14 +91,12 @@ private:
~WebEngineContext();
static void registerMainThreadFactories();
- static void destroyGpuProcess();
std::unique_ptr<base::RunLoop> m_runLoop;
std::unique_ptr<ContentMainDelegateQt> m_mainDelegate;
std::unique_ptr<content::ContentMainRunner> m_contentRunner;
std::unique_ptr<content::BrowserMainRunner> m_browserRunner;
std::unique_ptr<discardable_memory::DiscardableSharedMemoryManager> m_discardableSharedMemoryManager;
- std::unique_ptr<content::StartupData> m_startupData;
std::unique_ptr<content::MojoIpcSupport> m_mojoIpcSupport;
std::unique_ptr<QObject> m_globalQObject;
std::unique_ptr<ProfileAdapter> m_defaultProfileAdapter;
@@ -159,7 +115,6 @@ private:
static scoped_refptr<QtWebEngineCore::WebEngineContext> m_handle;
static bool m_destroyed;
static bool m_closingDown;
- static QAtomicPointer<gpu::SyncPointManager> s_syncPointManager;
};
} // namespace
diff --git a/src/core/web_engine_context_threads.cpp b/src/core/web_engine_context_threads.cpp
deleted file mode 100644
index 5aa4c3e1e..000000000
--- a/src/core/web_engine_context_threads.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "web_engine_context.h"
-
-#include "base/bind.h"
-#include "base/task/post_task.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread_restrictions.h"
-#include "content/browser/gpu/gpu_main_thread_factory.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
-#include "content/browser/utility_process_host.h"
-#include "content/gpu/gpu_child_thread.h"
-#include "content/gpu/gpu_process.h"
-#include "content/gpu/in_process_gpu_thread.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/renderer/in_process_renderer_thread.h"
-#include "content/utility/in_process_utility_thread.h"
-#include "gpu/ipc/service/gpu_init.h"
-
-#include <memory>
-
-#include <QEventLoop>
-
-namespace QtWebEngineCore {
-
-struct GpuThreadControllerQt : content::GpuThreadController
-{
- GpuThreadControllerQt(const content::InProcessChildThreadParams &params, const gpu::GpuPreferences &gpuPreferences)
- {
- base::PostTask(
- FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&GpuThreadControllerQt::createGpuProcess, params, gpuPreferences));
- }
- ~GpuThreadControllerQt() override
- {
- base::PostTask(
- FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&GpuThreadControllerQt::destroyGpuProcess));
- }
-
- static void createGpuProcess(
- const content::InProcessChildThreadParams &params,
- const gpu::GpuPreferences &gpuPreferences)
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (s_gpuProcessDestroyed)
- return;
-
- s_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::NORMAL);
- auto gpuInit = std::make_unique<gpu::GpuInit>();
- gpuInit->InitializeInProcess(base::CommandLine::ForCurrentProcess(), gpuPreferences);
- auto childThread = new content::GpuChildThread(params, std::move(gpuInit));
- childThread->Init(base::Time::Now());
- s_gpuProcess->set_main_thread(childThread);
- }
-
- static void destroyGpuProcess()
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (s_gpuProcessDestroyed)
- return;
-
- // viz::GpuServiceImpl::~GpuServiceImpl waits for io task.
- base::ScopedAllowBaseSyncPrimitivesForTesting allow;
- s_gpuProcess.reset();
- s_gpuProcessDestroyed = true;
- }
-
- static std::unique_ptr<content::GpuProcess> s_gpuProcess;
- static bool s_gpuProcessDestroyed;
-};
-
-std::unique_ptr<content::GpuProcess> GpuThreadControllerQt::s_gpuProcess;
-bool GpuThreadControllerQt::s_gpuProcessDestroyed = false;
-
-static std::unique_ptr<content::GpuThreadController> createGpuThreadController(
- const content::InProcessChildThreadParams &params,
- const gpu::GpuPreferences &gpuPreferences)
-{
- return std::make_unique<GpuThreadControllerQt>(params, gpuPreferences);
-}
-
-// static
-void WebEngineContext::destroyGpuProcess()
-{
- GpuThreadControllerQt::destroyGpuProcess();
-}
-
-// static
-void WebEngineContext::registerMainThreadFactories()
-{
- content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
- content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
- if (!isGpuServiceOnUIThread())
- content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread);
- else
- content::RegisterGpuMainThreadFactory(createGpuThreadController);
-}
-
-} // namespace QtWebEngineCore
diff --git a/src/core/web_engine_error.cpp b/src/core/web_engine_error.cpp
index 0d326473b..c18dfef8c 100644
--- a/src/core/web_engine_error.cpp
+++ b/src/core/web_engine_error.cpp
@@ -1,55 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_engine_error.h"
+
+#include "components/error_page/common/error.h"
+#include "components/error_page/common/localized_error.h"
#include "net/base/net_errors.h"
+#include "type_conversion.h"
+
+#include <QString>
+
+using namespace QtWebEngineCore;
+
const int WebEngineError::UserAbortedError = net::ERR_ABORTED;
namespace {
const int noError = 0;
-const int systemRelatedErrors = -1;
const int connectionRelatedErrors = -100;
const int certificateErrors = -200;
const int httpErrors = -300;
const int cacheErrors = -400;
-const int internalErrors = -500;
const int ftpErrors = -600;
const int certificateManagerErrors = -700;
const int dnsResolverErrors = -800;
@@ -58,6 +29,10 @@ const int endErrors = -900;
WebEngineError::ErrorDomain WebEngineError::toQtErrorDomain(int error_code)
{
+ // net errors are always negative values, and https response codes are positive
+ if (error_code > 0)
+ return HttpStatusCodeDomain;
+
// Chromium's ranges from net/base/net_error_list.h:
// 0 No error
// 1- 99 System related errors
@@ -86,3 +61,13 @@ WebEngineError::ErrorDomain WebEngineError::toQtErrorDomain(int error_code)
else
return WebEngineError::InternalErrorDomain;
}
+
+QString WebEngineError::toQtErrorDescription(int errorCode)
+{
+ if (errorCode < 0)
+ return toQt(net::ErrorToString(errorCode));
+ else if (errorCode > 0)
+ return toQt(error_page::LocalizedError::GetErrorDetails(
+ error_page::Error::kHttpErrorDomain, errorCode, false, false));
+ return QString();
+}
diff --git a/src/core/web_engine_error.h b/src/core/web_engine_error.h
index 7277ffa9d..b43678ad2 100644
--- a/src/core/web_engine_error.h
+++ b/src/core/web_engine_error.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -53,7 +17,7 @@
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
-class Q_WEBENGINECORE_PRIVATE_EXPORT WebEngineError
+class Q_WEBENGINECORE_EXPORT WebEngineError
{
public:
@@ -64,13 +28,14 @@ public:
CertificateErrorDomain,
HttpErrorDomain,
FtpErrorDomain,
- DnsErrorDomain
+ DnsErrorDomain,
+ HttpStatusCodeDomain
};
static const int UserAbortedError;
static ErrorDomain toQtErrorDomain(int error_code);
-
+ static QString toQtErrorDescription(int errorCode);
};
#endif // WEB_ENGINE_ERROR_H
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 6b11cf0cd..e71153899 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtwebenginecoreglobal_p.h"
#include "web_engine_library_info.h"
@@ -59,11 +23,12 @@
#include <QFileInfo>
#include <QLibraryInfo>
#include <QLocale>
+#include <QLoggingCategory>
#include <QStandardPaths>
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
#include <windows.h>
-#endif // OS_WIN
+#endif
#ifndef QTWEBENGINEPROCESS_NAME
#error "No name defined for QtWebEngine's process"
@@ -71,6 +36,8 @@
using namespace QtWebEngineCore;
+Q_LOGGING_CATEGORY(webEngineLibraryInfoLog, "qt.webengine.libraryinfo")
+
namespace {
QString fallbackDir() {
@@ -78,19 +45,19 @@ QString fallbackDir() {
return directory;
}
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
static inline CFBundleRef frameworkBundle()
{
return CFBundleGetBundleWithIdentifier(CFSTR("org.qt-project.QtWebEngineCore"));
}
-static QString getPath(CFBundleRef frameworkBundle)
+static QString getBundlePath(CFBundleRef frameworkBundle)
{
QString path;
// The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before.
// We use it for the other OS X versions as well to make sure it works and because
// the directory structure should be the same.
- if (qApp->applicationName() == QLatin1String(QTWEBENGINEPROCESS_NAME)) {
+ if (qApp->applicationName() == QLatin1String(qWebEngineProcessName())) {
path = QDir::cleanPath(qApp->applicationDirPath() % QLatin1String("/../../../.."));
} else if (frameworkBundle) {
CFURLRef bundleUrl = CFBundleCopyBundleURL(frameworkBundle);
@@ -108,12 +75,12 @@ static QString getResourcesPath(CFBundleRef frameworkBundle)
// The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before.
// We use it for the other OS X versions as well to make sure it works and because
// the directory structure should be the same.
- if (qApp->applicationName() == QLatin1String(QTWEBENGINEPROCESS_NAME)) {
- path = getPath(frameworkBundle) % QLatin1String("/Resources");
+ if (qApp->applicationName() == QLatin1String(qWebEngineProcessName())) {
+ path = getBundlePath(frameworkBundle) % QLatin1String("/Resources");
} else if (frameworkBundle) {
CFURLRef resourcesRelativeUrl = CFBundleCopyResourcesDirectoryURL(frameworkBundle);
CFStringRef resourcesRelativePath = CFURLCopyFileSystemPath(resourcesRelativeUrl, kCFURLPOSIXPathStyle);
- path = getPath(frameworkBundle) % QLatin1Char('/') % QString::fromCFString(resourcesRelativePath);
+ path = getBundlePath(frameworkBundle) % QLatin1Char('/') % QString::fromCFString(resourcesRelativePath);
CFRelease(resourcesRelativePath);
CFRelease(resourcesRelativeUrl);
}
@@ -121,7 +88,7 @@ static QString getResourcesPath(CFBundleRef frameworkBundle)
}
#endif
-#if defined(OS_MAC)
+#if defined(Q_OS_DARWIN)
static QString getMainApplicationResourcesPath()
{
QString resourcesPath;
@@ -153,10 +120,10 @@ QString subProcessPath()
{
static QString processPath;
if (processPath.isEmpty()) {
-#if defined(OS_WIN)
- const QString processBinary = QLatin1String(QTWEBENGINEPROCESS_NAME) % QLatin1String(".exe");
+#if defined(Q_OS_WIN)
+ const QString processBinary = QLatin1String(qWebEngineProcessName()) % QLatin1String(".exe");
#else
- const QString processBinary = QLatin1String(QTWEBENGINEPROCESS_NAME);
+ const QString processBinary = QLatin1String(qWebEngineProcessName());
#endif
QStringList candidatePaths;
@@ -165,9 +132,10 @@ QString subProcessPath()
// Only search in QTWEBENGINEPROCESS_PATH if set
candidatePaths << fromEnv;
} else {
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
- candidatePaths << getPath(frameworkBundle())
- % QStringLiteral("/Helpers/" QTWEBENGINEPROCESS_NAME ".app/Contents/MacOS/" QTWEBENGINEPROCESS_NAME);
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
+ candidatePaths << getBundlePath(frameworkBundle()) % QStringLiteral("/Helpers/")
+ % qWebEngineProcessName() % QStringLiteral(".app/Contents/MacOS/")
+ % qWebEngineProcessName();
#else
candidatePaths << QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath)
% QLatin1Char('/') % processBinary;
@@ -178,16 +146,30 @@ QString subProcessPath()
% QLatin1Char('/') % processBinary;
}
- for (const QString &candidate : qAsConst(candidatePaths)) {
+ for (const QString &candidate : std::as_const(candidatePaths)) {
if (QFileInfo::exists(candidate)) {
processPath = candidate;
+ qCDebug(webEngineLibraryInfoLog, "Qt WebEngine process path: %s",
+ qPrintable(candidate));
break;
}
}
- if (processPath.isEmpty())
- qFatal("Could not find %s", processBinary.toUtf8().constData());
+ if (processPath.isEmpty()) {
+ QStringList errorMessage;
+ errorMessage.append(
+ QStringLiteral("The following paths were searched for Qt WebEngine Process:"));
+ for (const QString &candidate : std::as_const(candidatePaths))
+ errorMessage.append(QStringLiteral(" ") % candidate);
+ errorMessage.append(QStringLiteral("but could not find it."));
+ if (fromEnv.isEmpty()) {
+ errorMessage.append(
+ QStringLiteral("You may override the default search path by using "
+ "QTWEBENGINEPROCESS_PATH environment variable."));
+ }
+ qFatal("%s", qPrintable(errorMessage.join('\n')));
+ }
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
if (!parsedCommandLine->HasSwitch(sandbox::policy::switches::kNoSandbox)) {
if (WebEngineLibraryInfo::isUNCPath(processPath) || WebEngineLibraryInfo::isRemoteDrivePath(processPath))
@@ -203,23 +185,55 @@ QString subProcessPath()
QString localesPath()
{
- static bool initialized = false;
- static QString potentialLocalesPath =
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
- getResourcesPath(frameworkBundle()) % QLatin1String("/qtwebengine_locales");
+ static QString potentialLocalesPath;
+ if (potentialLocalesPath.isEmpty()) {
+ QStringList candidatePaths;
+ const QString translationPakFilename =
+#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
+ QLatin1String(WebEngineLibraryInfo::getResolvedLocale() + ".pak");
#else
- QLibraryInfo::path(QLibraryInfo::TranslationsPath) % QDir::separator() % QLatin1String("qtwebengine_locales");
+ QLatin1String((WebEngineLibraryInfo::getResolvedLocale() + ".pak").c_str());
+#endif
+ const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_LOCALES_PATH");
+ if (!fromEnv.isEmpty()) {
+ // Only search in QTWEBENGINE_LOCALES_PATH if set
+ candidatePaths << fromEnv;
+ } else {
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
+ candidatePaths << getResourcesPath(frameworkBundle()) % QDir::separator()
+ % QLatin1String("qtwebengine_locales");
#endif
+ candidatePaths << QLibraryInfo::path(QLibraryInfo::TranslationsPath) % QDir::separator()
+ % QLatin1String("qtwebengine_locales");
+ candidatePaths << fallbackDir();
+ }
- if (!initialized) {
- initialized = true;
- if (!QFileInfo::exists(potentialLocalesPath)) {
- qWarning("Installed Qt WebEngine locales directory not found at location %s. Trying application directory...", qPrintable(potentialLocalesPath));
- potentialLocalesPath = QCoreApplication::applicationDirPath() % QDir::separator() % QLatin1String("qtwebengine_locales");
+ for (const QString &candidate : std::as_const(candidatePaths)) {
+ if (QFileInfo::exists(candidate % QDir::separator() % translationPakFilename)) {
+ potentialLocalesPath = candidate;
+ qCDebug(webEngineLibraryInfoLog, "Qt WebEngine locales path: %s",
+ qPrintable(candidate));
+ break;
+ }
}
- if (!QFileInfo::exists(potentialLocalesPath)) {
- qWarning("Qt WebEngine locales directory not found at location %s. Trying fallback directory... Translations MAY NOT not be correct.", qPrintable(potentialLocalesPath));
- potentialLocalesPath = fallbackDir();
+
+ if (potentialLocalesPath.isEmpty()) {
+ QStringList warningMessage;
+ warningMessage.append(
+ QStringLiteral("The following paths were searched for Qt WebEngine locales:"));
+ for (const QString &candidate : std::as_const(candidatePaths))
+ warningMessage.append(QStringLiteral(" ") % candidate);
+ warningMessage.append(
+ QStringLiteral(
+ "but could not find the translation file for the current locale: ")
+ % translationPakFilename);
+ if (fromEnv.isEmpty()) {
+ warningMessage.append(
+ QStringLiteral("You may override the default search paths by using "
+ "QTWEBENGINE_LOCALES_PATH environment variable."));
+ }
+ warningMessage.append(QStringLiteral("Translations WILL NOT be correct."));
+ qWarning("%s", qPrintable(warningMessage.join('\n')));
}
}
@@ -241,7 +255,7 @@ QString dictionariesPath()
candidatePaths << fromEnv;
} else {
// First try to find dictionaries near the application.
-#ifdef OS_MAC
+#ifdef Q_OS_DARWIN
QString resourcesDictionariesPath = getMainApplicationResourcesPath()
% QDir::separator() % QLatin1String("qtwebengine_dictionaries");
candidatePaths << resourcesDictionariesPath;
@@ -251,7 +265,7 @@ QString dictionariesPath()
candidatePaths << applicationDictionariesPath;
// Then try to find dictionaries near the installed library.
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
QString frameworkDictionariesPath = getResourcesPath(frameworkBundle())
% QLatin1String("/qtwebengine_dictionaries");
candidatePaths << frameworkDictionariesPath;
@@ -262,40 +276,69 @@ QString dictionariesPath()
candidatePaths << libraryDictionariesPath;
}
- for (const QString &candidate : qAsConst(candidatePaths)) {
+ for (const QString &candidate : std::as_const(candidatePaths)) {
if (QFileInfo::exists(candidate)) {
potentialDictionariesPath = candidate;
+ qCDebug(webEngineLibraryInfoLog, "Qt WebEngine dictionaries path: %s",
+ qPrintable(candidate));
break;
}
}
+
+ if (potentialDictionariesPath.isEmpty()) {
+ // return path for error message
+ potentialDictionariesPath = QCoreApplication::applicationDirPath() % QDir::separator()
+ % QLatin1String("qtwebengine_dictionaries");
+ }
}
return potentialDictionariesPath;
}
#endif // QT_CONFIG(webengine_spellchecker)
-QString resourcesDataPath()
+QString resourcesPath()
{
- static bool initialized = false;
- static QString potentialResourcesPath =
-#if defined(OS_MAC) && defined(QT_MAC_FRAMEWORK_BUILD)
- getResourcesPath(frameworkBundle());
-#else
- QLibraryInfo::path(QLibraryInfo::DataPath) % QLatin1String("/resources");
+ static QString potentialResourcesPath;
+ if (potentialResourcesPath.isEmpty()) {
+ QStringList candidatePaths;
+ const QString resourcesPakFilename = QLatin1String("qtwebengine_resources.pak");
+ const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_RESOURCES_PATH");
+ if (!fromEnv.isEmpty()) {
+ // Only search in QTWEBENGINE_RESOURCES_PATH if set
+ candidatePaths << fromEnv;
+ } else {
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
+ candidatePaths << getResourcesPath(frameworkBundle());
#endif
- 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::path(QLibraryInfo::DataPath);
+ candidatePaths << QLibraryInfo::path(QLibraryInfo::DataPath) % QDir::separator()
+ % QLatin1String("resources");
+ candidatePaths << QLibraryInfo::path(QLibraryInfo::DataPath);
+ candidatePaths << QCoreApplication::applicationDirPath();
+ candidatePaths << fallbackDir();
}
- if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) {
- qWarning("Qt WebEngine resources not found at %s. Trying application directory...", qPrintable(potentialResourcesPath));
- potentialResourcesPath = QCoreApplication::applicationDirPath();
+
+ for (const QString &candidate : std::as_const(candidatePaths)) {
+ if (QFileInfo::exists(candidate % QDir::separator() % resourcesPakFilename)) {
+ potentialResourcesPath = candidate;
+ qCDebug(webEngineLibraryInfoLog, "Qt WebEngine resources path: %s",
+ qPrintable(candidate));
+ break;
+ }
}
- 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();
+
+ if (potentialResourcesPath.isEmpty()) {
+ QStringList errorMessage;
+ errorMessage.append(QStringLiteral(
+ "The following paths were searched for Qt WebEngine resources:"));
+ for (const QString &candidate : std::as_const(candidatePaths))
+ errorMessage.append(QStringLiteral(" ") % candidate);
+ errorMessage.append(QStringLiteral("but could not find any."));
+ if (fromEnv.isEmpty()) {
+ errorMessage.append(
+ QStringLiteral("You may override the default search paths by using "
+ "QTWEBENGINE_RESOURCES_PATH environment variable."));
+ }
+ qFatal("%s", qPrintable(errorMessage.join('\n')));
}
}
@@ -308,17 +351,21 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
QString directory;
switch (key) {
case QT_RESOURCES_PAK:
- return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources.pak"));
+ return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_resources.pak"));
case QT_RESOURCES_100P_PAK:
- return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_100p.pak"));
+ return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_resources_100p.pak"));
case QT_RESOURCES_200P_PAK:
- return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_200p.pak"));
+ return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_resources_200p.pak"));
case QT_RESOURCES_DEVTOOLS_PAK:
- return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_devtools_resources.pak"));
+ return toFilePath(resourcesPath() % QLatin1String("/qtwebengine_devtools_resources.pak"));
+#if defined(Q_OS_DARWIN) && defined(QT_MAC_FRAMEWORK_BUILD)
+ case QT_FRAMEWORK_BUNDLE:
+ return toFilePath(getBundlePath(frameworkBundle()));
+#endif
case base::FILE_EXE:
case content::CHILD_PROCESS_EXE:
return toFilePath(subProcessPath());
-#if defined(OS_POSIX)
+#if BUILDFLAG(IS_POSIX)
case base::DIR_CACHE:
directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
break;
@@ -330,13 +377,15 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
directory = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
break;
case base::DIR_QT_LIBRARY_DATA:
- return toFilePath(resourcesDataPath());
+ return toFilePath(resourcesPath());
case ui::DIR_LOCALES:
return toFilePath(localesPath());
#if QT_CONFIG(webengine_spellchecker)
case base::DIR_APP_DICTIONARIES:
return toFilePath(dictionariesPath());
#endif
+ case base::DIR_ASSETS:
+ return toFilePath(resourcesPath());
default:
// Note: the path system expects this function to override the default
// behavior. So no need to log an error if we don't support a given
@@ -347,7 +396,7 @@ base::FilePath WebEngineLibraryInfo::getPath(int key)
return toFilePath(directory.isEmpty() ? fallbackDir() : directory);
}
-base::string16 WebEngineLibraryInfo::getApplicationName()
+std::u16string WebEngineLibraryInfo::getApplicationName()
{
return toString16(qApp->applicationName());
}
@@ -355,14 +404,16 @@ base::string16 WebEngineLibraryInfo::getApplicationName()
std::string WebEngineLibraryInfo::getResolvedLocale()
{
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
- if (parsedCommandLine->HasSwitch(switches::kLang)) {
- return parsedCommandLine->GetSwitchValueASCII(switches::kLang);
- } else {
- const QString &locale = QLocale().bcp47Name();
- std::string resolvedLocale;
- if (l10n_util::CheckAndResolveLocale(locale.toStdString(), &resolvedLocale))
- return resolvedLocale;
- }
+ std::string locale;
+ if (parsedCommandLine->HasSwitch(switches::kLang))
+ locale = parsedCommandLine->GetSwitchValueASCII(switches::kLang);
+ else
+ locale = QLocale().bcp47Name().toStdString();
+
+ std::string resolvedLocale;
+ if (l10n_util::CheckAndResolveLocale(locale, &resolvedLocale))
+ return resolvedLocale;
+
return "en-US";
}
@@ -374,7 +425,7 @@ std::string WebEngineLibraryInfo::getApplicationLocale()
: QLocale().bcp47Name().toStdString();
}
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
bool WebEngineLibraryInfo::isRemoteDrivePath(const QString &path)
{
WCHAR wDriveLetter[4] = { 0 };
diff --git a/src/core/web_engine_library_info.h b/src/core/web_engine_library_info.h
index e7dc195f6..b7503f2df 100644
--- a/src/core/web_engine_library_info.h
+++ b/src/core/web_engine_library_info.h
@@ -1,65 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_ENGINE_LIBRARY_INFO_H
#define WEB_ENGINE_LIBRARY_INFO_H
#include "base/files/file_path.h"
-#include "base/strings/string16.h"
#include <QString>
enum {
QT_RESOURCES_PAK = 5000,
QT_RESOURCES_100P_PAK = 5001,
QT_RESOURCES_200P_PAK = 5002,
- QT_RESOURCES_DEVTOOLS_PAK = 5003
+ QT_RESOURCES_DEVTOOLS_PAK = 5003,
+ QT_FRAMEWORK_BUNDLE = 5004
};
class WebEngineLibraryInfo {
public:
static base::FilePath getPath(int key);
// Called by localized_error in our custom chrome layer
- static base::string16 getApplicationName();
+ static std::u16string getApplicationName();
static std::string getResolvedLocale();
static std::string getApplicationLocale();
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
static bool isRemoteDrivePath(const QString &path);
static bool isUNCPath(const QString &path);
#endif
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 45d5bcfc8..e302998f0 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_engine_settings.h"
@@ -45,11 +9,11 @@
#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"
-#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "media/base/media_switches.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
@@ -92,10 +56,25 @@ static inline bool isTouchEventsAPIEnabled() {
return touchEventsAPIEnabled;
}
+blink::mojom::ImageAnimationPolicy
+toBlinkImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy)
+{
+ switch (policy) {
+ case QWebEngineSettings::AllowImageAnimation:
+ return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
+ case QWebEngineSettings::AnimateImageOnce:
+ return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAnimateOnce;
+ case QWebEngineSettings::DisallowImageAnimation:
+ return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyNoAnimation;
+ }
+ return blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
+}
+
WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings)
: m_adapter(nullptr)
, parentSettings(_parentSettings)
, m_unknownUrlSchemePolicy(QWebEngineSettings::InheritedUnknownUrlSchemePolicy)
+ , m_imageAnimationPolicy(QWebEngineSettings::InheritedImageAnimationPolicy)
{
if (parentSettings)
parentSettings->childSettings.insert(this);
@@ -113,7 +92,7 @@ WebEngineSettings::~WebEngineSettings()
if (parentSettings)
parentSettings->childSettings.remove(this);
// In QML the profile and its settings may be garbage collected before the page and its settings.
- for (WebEngineSettings *settings : qAsConst(childSettings))
+ for (WebEngineSettings *settings : std::as_const(childSettings))
settings->parentSettings = nullptr;
}
@@ -227,6 +206,24 @@ QString WebEngineSettings::defaultTextEncoding() const
void WebEngineSettings::setUnknownUrlSchemePolicy(QWebEngineSettings::UnknownUrlSchemePolicy policy)
{
m_unknownUrlSchemePolicy = policy;
+ scheduleApplyRecursively();
+}
+
+void WebEngineSettings::setImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy)
+{
+ m_imageAnimationPolicy = policy;
+ scheduleApplyRecursively();
+}
+
+QWebEngineSettings::ImageAnimationPolicy WebEngineSettings::imageAnimationPolicy() const
+{
+ if (m_imageAnimationPolicy != QWebEngineSettings::InheritedImageAnimationPolicy)
+ return m_imageAnimationPolicy;
+
+ if (parentSettings)
+ return parentSettings->imageAnimationPolicy();
+
+ return QWebEngineSettings::AllowImageAnimation;
}
QWebEngineSettings::UnknownUrlSchemePolicy WebEngineSettings::unknownUrlSchemePolicy() const
@@ -296,6 +293,12 @@ void WebEngineSettings::initDefaults()
#else
s_defaultAttributes.insert(QWebEngineSettings::PdfViewerEnabled, false);
#endif
+ s_defaultAttributes.insert(QWebEngineSettings::NavigateOnDropEnabled, true);
+ bool noReadingFromCanvas =
+ commandLine->HasSwitch(switches::kDisableReadingFromCanvas);
+ s_defaultAttributes.insert(QWebEngineSettings::ReadingFromCanvasEnabled, !noReadingFromCanvas);
+ bool forceDarkMode = commandLine->HasSwitch(switches::kForceDarkMode);
+ s_defaultAttributes.insert(QWebEngineSettings::ForceDarkMode, forceDarkMode);
}
if (s_defaultFontFamilies.isEmpty()) {
@@ -330,6 +333,7 @@ void WebEngineSettings::initDefaults()
m_defaultEncoding = QStringLiteral("ISO-8859-1");
m_unknownUrlSchemePolicy = QWebEngineSettings::InheritedUnknownUrlSchemePolicy;
+ m_imageAnimationPolicy = QWebEngineSettings::InheritedImageAnimationPolicy;
}
void WebEngineSettings::scheduleApply()
@@ -355,6 +359,9 @@ void WebEngineSettings::doApply()
void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPreferences *prefs)
{
+ // Not supported
+ prefs->picture_in_picture_enabled = false;
+
// Override for now
prefs->touch_event_feature_detection_enabled = isTouchEventsAPIEnabled();
#if !QT_CONFIG(webengine_embedded_build)
@@ -366,6 +373,7 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
// to enable them separately. With viewport-enabled we match Android defaults.
prefs->viewport_meta_enabled = true;
prefs->shrinks_viewport_contents_to_fit = true;
+ prefs->main_frame_resizes_are_orientation_changes = true;
}
// Attributes mapping.
@@ -376,7 +384,7 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
prefs->tabs_to_links = testAttribute(QWebEngineSettings::LinksIncludedInFocusChain);
prefs->local_storage_enabled = testAttribute(QWebEngineSettings::LocalStorageEnabled);
prefs->databases_enabled = testAttribute(QWebEngineSettings::LocalStorageEnabled);
- prefs->allow_universal_access_from_file_urls =
+ prefs->allow_remote_access_from_local_urls =
testAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls);
prefs->spatial_navigation_enabled = testAttribute(QWebEngineSettings::SpatialNavigationEnabled);
prefs->allow_file_access_from_file_urls =
@@ -388,6 +396,7 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
prefs->fullscreen_supported = testAttribute(QWebEngineSettings::FullScreenSupportEnabled);
prefs->accelerated_2d_canvas_enabled =
testAttribute(QWebEngineSettings::Accelerated2dCanvasEnabled);
+ prefs->force_dark_mode_enabled = testAttribute(QWebEngineSettings::ForceDarkMode);
prefs->webgl1_enabled = prefs->webgl2_enabled = testAttribute(QWebEngineSettings::WebGLEnabled);
prefs->should_print_backgrounds = testAttribute(QWebEngineSettings::PrintElementBackgrounds);
prefs->allow_running_insecure_content =
@@ -402,6 +411,8 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
}
prefs->dom_paste_enabled = testAttribute(QWebEngineSettings::JavascriptCanPaste);
prefs->dns_prefetching_enabled = testAttribute(QWebEngineSettings::DnsPrefetchEnabled);
+ prefs->disable_reading_from_canvas = !testAttribute(QWebEngineSettings::ReadingFromCanvasEnabled);
+ prefs->animation_policy = toBlinkImageAnimationPolicy(imageAnimationPolicy());
// Fonts settings.
prefs->standard_font_family_map[blink::web_pref::kCommonScript] =
@@ -416,8 +427,6 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
toString16(fontFamily(QWebEngineSettings::CursiveFont));
prefs->fantasy_font_family_map[blink::web_pref::kCommonScript] =
toString16(fontFamily(QWebEngineSettings::FantasyFont));
- prefs->pictograph_font_family_map[blink::web_pref::kCommonScript] =
- toString16(fontFamily(QWebEngineSettings::PictographFont));
prefs->default_font_size = fontSize(QWebEngineSettings::DefaultFontSize);
prefs->default_fixed_font_size = fontSize(QWebEngineSettings::DefaultFixedFontSize);
prefs->minimum_font_size = fontSize(QWebEngineSettings::MinimumFontSize);
@@ -438,7 +447,7 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
}
// Apply native CaptionStyle parameters.
- base::Optional<ui::CaptionStyle> style;
+ absl::optional<ui::CaptionStyle> style;
if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kForceCaptionStyle)) {
style = ui::CaptionStyle::FromSpec(
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kForceCaptionStyle));
@@ -456,7 +465,6 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
prefs->text_track_font_family = style->font_family;
prefs->text_track_font_variant = style->font_variant;
prefs->text_track_window_color = style->window_color;
- prefs->text_track_window_padding = style->window_padding;
prefs->text_track_window_radius = style->window_radius;
}
}
@@ -476,13 +484,18 @@ bool WebEngineSettings::applySettingsToRendererPreferences(blink::RendererPrefer
}
}
#endif
+ bool canNavigateOnDrop = testAttribute(QWebEngineSettings::NavigateOnDropEnabled);
+ if (canNavigateOnDrop != prefs->can_accept_load_drops) {
+ prefs->can_accept_load_drops = canNavigateOnDrop;
+ changed = true;
+ }
return changed;
}
void WebEngineSettings::scheduleApplyRecursively()
{
scheduleApply();
- for (WebEngineSettings *settings : qAsConst(childSettings)) {
+ for (WebEngineSettings *settings : std::as_const(childSettings)) {
settings->scheduleApply();
}
}
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index a2366e2f6..2bfc5949d 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -103,6 +67,9 @@ public:
void setUnknownUrlSchemePolicy(QWebEngineSettings::UnknownUrlSchemePolicy policy);
QWebEngineSettings::UnknownUrlSchemePolicy unknownUrlSchemePolicy() const;
+ void setImageAnimationPolicy(QWebEngineSettings::ImageAnimationPolicy policy);
+ QWebEngineSettings::ImageAnimationPolicy imageAnimationPolicy() const;
+
void scheduleApply();
void scheduleApplyRecursively();
@@ -131,6 +98,7 @@ private:
static QHash<QWebEngineSettings::FontFamily, QString> s_defaultFontFamilies;
static QHash<QWebEngineSettings::FontSize, int> s_defaultFontSizes;
QWebEngineSettings::UnknownUrlSchemePolicy m_unknownUrlSchemePolicy;
+ QWebEngineSettings::ImageAnimationPolicy m_imageAnimationPolicy;
friend class WebContentsAdapter;
};
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index d7dceb30c..617eea2d0 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
@@ -71,6 +35,7 @@
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
+#include "native_web_keyboard_event_qt.h"
#include "render_widget_host_view_qt_delegate.h"
#include <QtGui/private/qtgui-config_p.h>
@@ -594,6 +559,8 @@ static int windowsKeyCodeForQtKey(int qtKey, bool isKeypad)
case Qt::Key_QuoteDbl:
return VK_OEM_7; // case '\'': case '"': return 0xDE;
// VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
+ case Qt::Key_AltGr:
+ return 0xE1; // (E1) VK_OEM_AX = ui::VKEY_ALTGR see ui/events/keycodes/keyboard_codes_win.h
// VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
case Qt::Key_AudioRewind:
@@ -1478,8 +1445,10 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev)
webKitEvent.SetType(webEventTypeForEvent(ev));
webKitEvent.SetPositionInWidget(ev->position().x(), ev->position().y());
+ webKitEvent.SetPositionInScreen(ev->globalPosition().x(), ev->globalPosition().y());
webKitEvent.movement_x = ev->position().x() - ev->oldPos().x();
webKitEvent.movement_y = ev->position().y() - ev->oldPos().y();
+ webKitEvent.is_raw_movement_event = true;
webKitEvent.pointer_type = WebPointerProperties::PointerType::kMouse;
return webKitEvent;
@@ -1516,7 +1485,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev)
return webKitEvent;
}
-#ifndef QT_NO_GESTURES
+#if QT_CONFIG(gestures)
WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev)
{
WebGestureEvent webKitEvent;
@@ -1576,8 +1545,9 @@ static QPoint getWheelEventDelta(const blink::WebGestureEvent &webEvent)
{
static const float cDefaultQtScrollStep = 20.f;
static const int wheelScrollLines = QGuiApplication::styleHints()->wheelScrollLines();
- return QPoint(webEvent.data.scroll_update.delta_x * QWheelEvent::DefaultDeltasPerStep / (wheelScrollLines * cDefaultQtScrollStep),
- webEvent.data.scroll_update.delta_y * QWheelEvent::DefaultDeltasPerStep / (wheelScrollLines * cDefaultQtScrollStep));
+ static const float deltasPerStep = static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
+ return QPoint(webEvent.data.scroll_update.delta_x * deltasPerStep / (wheelScrollLines * cDefaultQtScrollStep),
+ webEvent.data.scroll_update.delta_y * deltasPerStep / (wheelScrollLines * cDefaultQtScrollStep));
}
blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev)
@@ -1597,6 +1567,22 @@ blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev)
return blink::WebMouseWheelEvent::kPhaseNone;
}
+blink::WebMouseWheelEvent::Phase getMomentumPhase(QWheelEvent *ev)
+{
+ switch (ev->phase()) {
+ case Qt::ScrollMomentum:
+ return blink::WebMouseWheelEvent::kPhaseBegan;
+ case Qt::ScrollEnd:
+ return blink::WebMouseWheelEvent::kPhaseEnded;
+ case Qt::NoScrollPhase:
+ case Qt::ScrollBegin:
+ case Qt::ScrollUpdate:
+ return blink::WebMouseWheelEvent::kPhaseNone;
+ }
+ Q_UNREACHABLE();
+ return blink::WebMouseWheelEvent::kPhaseNone;
+}
+
blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev)
{
WebMouseWheelEvent webEvent;
@@ -1608,11 +1594,12 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev)
webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()),
static_cast<float>(ev->globalPosition().y()));
- webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep;
- webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep;
+ webEvent.wheel_ticks_x = ev->angleDelta().x() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
+ webEvent.wheel_ticks_y = ev->angleDelta().y() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
webEvent.phase = toBlinkPhase(ev);
#if defined(Q_OS_DARWIN)
// PrecisePixel is a macOS term meaning it is a system scroll gesture, see qnsview_mouse.mm
+ webEvent.momentum_phase = getMomentumPhase(ev);
if (ev->source() == Qt::MouseEventSynthesizedBySystem)
webEvent.delta_units = ui::ScrollGranularity::kScrollByPrecisePixel;
#endif
@@ -1631,6 +1618,9 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
if (toBlinkPhase(ev) != webEvent.phase)
return false;
#if defined(Q_OS_DARWIN)
+ if (getMomentumPhase(ev) != webEvent.momentum_phase)
+ return false;
+
if ((webEvent.delta_units == ui::ScrollGranularity::kScrollByPrecisePixel)
!= (ev->source() == Qt::MouseEventSynthesizedBySystem))
return false;
@@ -1642,8 +1632,8 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()),
static_cast<float>(ev->globalPosition().y()));
- webEvent.wheel_ticks_x += static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep;
- webEvent.wheel_ticks_y += static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep;
+ webEvent.wheel_ticks_x = ev->angleDelta().x() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
+ webEvent.wheel_ticks_y = ev->angleDelta().y() / static_cast<float>(QWheelEvent::DefaultDeltasPerStep);
setBlinkWheelEventDelta(webEvent);
return true;
@@ -1671,13 +1661,17 @@ void WebEventFactory::sendUnhandledWheelEvent(const blink::WebGestureEvent &even
content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *ev)
{
- content::NativeWebKeyboardEvent webKitEvent(reinterpret_cast<gfx::NativeEvent>(ev));
+ content::NativeWebKeyboardEvent webKitEvent(ToNativeEvent(ev));
webKitEvent.SetTimeStamp(base::TimeTicks::Now());
- webKitEvent.SetModifiers(modifiersForEvent(ev));
+ bool isBackTabWithoutModifier =
+ ev->key() == Qt::Key_Backtab && ev->modifiers() == Qt::NoModifier;
+ webKitEvent.SetModifiers(isBackTabWithoutModifier ? WebInputEvent::kShiftKey
+ : modifiersForEvent(ev));
webKitEvent.SetType(webEventTypeForEvent(ev));
int qtKey = qtKeyForKeyEvent(ev);
- Qt::KeyboardModifiers qtModifiers = qtModifiersForEvent(ev);
+ Qt::KeyboardModifiers qtModifiers =
+ isBackTabWithoutModifier ? Qt::ShiftModifier : qtModifiersForEvent(ev);
QString qtText = qtTextForKeyEvent(ev, qtKey, qtModifiers);
webKitEvent.native_key_code = nativeKeyCodeForKeyEvent(ev);
@@ -1712,10 +1706,12 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e
ui::DomCodeToUsLayoutKeyboardCode(static_cast<ui::DomCode>(webKitEvent.dom_code));
const ushort* text = qtText.utf16();
- size_t textSize = std::min(sizeof(webKitEvent.text), size_t(qtText.length() * 2));
- memcpy(&webKitEvent.text, text, textSize);
- memcpy(&webKitEvent.unmodified_text, text, textSize);
-
+ size_t size = std::char_traits<char16_t>::length((char16_t *)text);
+ if (size <= blink::WebKeyboardEvent::kTextLengthCap - 1) { // should be null terminated
+ size_t textSize = std::min(sizeof(webKitEvent.text), size * sizeof(char16_t));
+ memcpy(&webKitEvent.text, text, textSize);
+ memcpy(&webKitEvent.unmodified_text, text, textSize);
+ }
if (webKitEvent.windows_key_code == VK_RETURN) {
// This is the same behavior as GTK:
// We need to treat the enter key as a key press of character \r. This
diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h
index df2f26694..53ebfb509 100644
--- a/src/core/web_event_factory.h
+++ b/src/core/web_event_factory.h
@@ -1,64 +1,28 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_EVENT_FACTORY_H
#define WEB_EVENT_FACTORY_H
-#include "content/public/browser/native_web_keyboard_event.h"
-#ifndef QT_NO_GESTURES
+#include "QtGui/qtguiglobal.h"
+
+#include "content/public/common/input/native_web_keyboard_event.h"
+#if QT_CONFIG(gestures)
#include "third_party/blink/public/common/input/web_gesture_event.h"
#endif
#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
-#include <QtGlobal>
-
QT_BEGIN_NAMESPACE
class QEvent;
class QHoverEvent;
class QKeyEvent;
class QMouseEvent;
-#ifndef QT_NO_TABLETEVENT
+#if QT_CONFIG(tabletevent)
class QTabletEvent;
#endif
class QWheelEvent;
-#ifndef QT_NO_GESTURES
+#if QT_CONFIG(gestures)
class QNativeGestureEvent;
#endif
QT_END_NAMESPACE
@@ -72,11 +36,11 @@ class WebEventFactory {
public:
static blink::WebMouseEvent toWebMouseEvent(QMouseEvent *);
static blink::WebMouseEvent toWebMouseEvent(QHoverEvent *);
-#ifndef QT_NO_TABLETEVENT
+#if QT_CONFIG(tabletevent)
static blink::WebMouseEvent toWebMouseEvent(QTabletEvent *);
#endif
static blink::WebMouseEvent toWebMouseEvent(QEvent *);
-#ifndef QT_NO_GESTURES
+#if QT_CONFIG(gestures)
static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *);
#endif
static blink::WebMouseWheelEvent toWebWheelEvent(QWheelEvent *);
diff --git a/src/core/web_usb_detector_qt.cpp b/src/core/web_usb_detector_qt.cpp
index 0fd898333..511ac6801 100644
--- a/src/core/web_usb_detector_qt.cpp
+++ b/src/core/web_usb_detector_qt.cpp
@@ -1,41 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// based on chrome/browser/usb/web_usb_detector.cc
+// Copyright 2015 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 "web_usb_detector_qt.h"
@@ -43,6 +12,7 @@
#include "content/public/browser/device_service.h"
#include "device/base/features.h"
+#include "services/device/public/mojom/usb_device.mojom.h"
WebUsbDetectorQt::WebUsbDetectorQt() = default;
@@ -50,22 +20,12 @@ WebUsbDetectorQt::~WebUsbDetectorQt() = default;
void WebUsbDetectorQt::Initialize()
{
-#if defined(OS_WIN)
- // The WebUSB device detector is disabled on Windows due to jank and hangs
- // caused by enumerating devices. The new USB backend is designed to resolve
- // these issues so enable it for testing. https://crbug.com/656702
- if (!base::FeatureList::IsEnabled(device::kNewUsbBackend))
- return;
-#endif // defined(OS_WIN)
-
if (!m_deviceManager) {
// Receive mojo::Remote<UsbDeviceManager> from DeviceService.
content::GetDeviceService().BindUsbDeviceManager(
m_deviceManager.BindNewPipeAndPassReceiver());
}
DCHECK(m_deviceManager);
- m_deviceManager.set_disconnect_handler(base::BindOnce(
- &WebUsbDetectorQt::OnDeviceManagerConnectionError, base::Unretained(this)));
// Listen for added/removed device events.
DCHECK(!m_clientReceiver.is_bound());
@@ -83,12 +43,3 @@ void WebUsbDetectorQt::OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device_in
Q_UNUSED(device_info);
QT_NOT_YET_IMPLEMENTED
}
-
-void WebUsbDetectorQt::OnDeviceManagerConnectionError()
-{
- m_deviceManager.reset();
- m_clientReceiver.reset();
-
- // Try to reconnect the device manager.
- Initialize();
-}
diff --git a/src/core/web_usb_detector_qt.h b/src/core/web_usb_detector_qt.h
index b1d7279bf..b9ab5e4bb 100644
--- a/src/core/web_usb_detector_qt.h
+++ b/src/core/web_usb_detector_qt.h
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef WEB_USB_DETECTOR_QT_H
#define WEB_USB_DETECTOR_QT_H
-#include "base/macros.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -61,15 +24,11 @@ private:
void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device_info) override;
void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device_info) override;
- void OnDeviceManagerConnectionError();
-
// Connection to |device_manager_instance_|.
mojo::Remote<device::mojom::UsbDeviceManager> m_deviceManager;
mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient> m_clientReceiver { this };
base::WeakPtrFactory<WebUsbDetectorQt> m_weakFactory { this };
-
- DISALLOW_COPY_AND_ASSIGN(WebUsbDetectorQt);
};
#endif // WEB_USB_DETECTOR_QT_H
diff --git a/src/gn/CMakeLists.txt b/src/gn/CMakeLists.txt
index 4d25debb9..0fe3e4e05 100644
--- a/src/gn/CMakeLists.txt
+++ b/src/gn/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
@@ -8,34 +11,61 @@ project(Gn
)
if(NOT DEFINED WEBENGINE_ROOT_SOURCE_DIR)
- get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." REALPATH)
+ set(path_mode REALPATH)
+ if(APPLE AND QT_ALLOW_SYMLINK_IN_PATHS)
+ set(path_mode ABSOLUTE)
+ endif()
+
+ get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ${path_mode})
endif()
include(${WEBENGINE_ROOT_SOURCE_DIR}/.cmake.conf)
set(GN_SOURCE_DIR ${WEBENGINE_ROOT_SOURCE_DIR}/src/3rdparty/gn)
set(GN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+set(GN_LINKER ${CMAKE_CXX_COMPILER})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${WEBENGINE_ROOT_SOURCE_DIR}/cmake")
-find_package(Python2 REQUIRED)
+find_package(Python3 REQUIRED)
find_package(Ninja 1.7.2 REQUIRED)
if(WIN32)
set(GN_EXECUTABLE gn.exe)
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT MINGW)
+ # Use lld-link instead of clang-cl.
+ set(GN_LINKER ${CMAKE_LINKER})
+ endif()
else()
set(GN_EXECUTABLE gn)
endif()
file(MAKE_DIRECTORY ${GN_BINARY_DIR})
+
+if((UNIX AND NOT APPLE) AND
+ (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR
+ CMAKE_CXX_COMPILER_ID STREQUAL Clang))
+ set(platform linux)
+elseif(MSVC)
+ set(platform msvc)
+elseif(MINGW)
+ set(platform mingw)
+elseif(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang)
+ set(platform darwin)
+else()
+ message(FATAL_ERROR "Unsupported gn platform !")
+endif()
+
add_custom_command(
OUTPUT ${GN_EXECUTABLE}
WORKING_DIRECTORY ${GN_BINARY_DIR}
- COMMAND ${Python2_EXECUTABLE} ${GN_SOURCE_DIR}/build/gen.py
+ COMMAND ${Python3_EXECUTABLE} ${GN_SOURCE_DIR}/build/gen.py
--no-last-commit-position
--out-path ${GN_BINARY_DIR}/$<CONFIG>
--cc ${CMAKE_C_COMPILER}
--cxx ${CMAKE_CXX_COMPILER}
- --ld ${CMAKE_CXX_COMPILER}
+ --ld ${GN_LINKER}
+ --platform ${platform}
+ --ar ${CMAKE_AR}
--qt-version "${QT_REPO_MODULE_VERSION}.qtwebengine.qt.io"
$<$<PLATFORM_ID:Darwin>:--isysroot>
$<$<PLATFORM_ID:Darwin>:${CMAKE_OSX_SYSROOT}>
diff --git a/src/host/BUILD.toolchain.gn.in b/src/host/BUILD.toolchain.gn.in
index df62aa88e..1beb9ee6d 100644
--- a/src/host/BUILD.toolchain.gn.in
+++ b/src/host/BUILD.toolchain.gn.in
@@ -12,6 +12,7 @@ gcc_toolchain("@GN_TOOLCHAIN@") {
current_cpu = "@GN_CPU@"
v8_current_cpu = "@GN_V8_CPU@"
is_clang = @GN_IS_CLANG@
+ is_mingw = @GN_IS_MINGW@
use_gold = false
}
}
diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt
index 822fa8a27..d40275217 100644
--- a/src/host/CMakeLists.txt
+++ b/src/host/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
if(NOT DEFINED WEBENGINE_ROOT_SOURCE_DIR)
@@ -16,15 +19,18 @@ project(QtWebEngineConfigure
VERSION "${QT_REPO_MODULE_VERSION}"
LANGUAGES CXX C)
-find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core)
+find_package(Qt6 6.5 CONFIG REQUIRED COMPONENTS BuildInternals Core)
+qt_internal_project_setup()
+get_gn_arch(target_arch ${GN_TARGET_CPU})
+get_gn_arch(host_arch ${TEST_architecture_arch})
+get_v8_arch(v8_arch ${target_arch} ${host_arch})
set(buildDir ${CMAKE_CURRENT_BINARY_DIR})
-configure_gn_toolchain(host ${TEST_architecture_arch} ${TEST_architecture_arch}
+configure_gn_toolchain(host ${host_arch} ${host_arch}
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
${buildDir}/host_toolchain
)
-get_v8_arch(GN_V8_HOST_CPU ${GN_TARGET_CPU} ${TEST_architecture_arch})
-configure_gn_toolchain(v8 ${GN_V8_HOST_CPU} ${GN_TARGET_CPU}
+configure_gn_toolchain(v8 ${v8_arch} ${target_arch}
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
${buildDir}/v8_toolchain)
@@ -45,3 +51,18 @@ if(QT_FEATURE_qtpdf_build)
)
endif()
+# TODO: this could be run as part of main configure with execute_process
+# Skip for qtpdf(android)
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL GNU AND TEST_architecture_arch STREQUAL "x86_64"
+ AND GN_TARGET_CPU STREQUAL "arm" AND NOT MINGW AND NOT ANDROID)
+ try_compile(
+ has32HostCompiler
+ "${CMAKE_CURRENT_BINARY_DIR}/config.tests/hostcompiler"
+ "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/hostcompiler"
+ hostcompiler
+ )
+ if(NOT has32HostCompiler)
+ MESSAGE(FATAL_ERROR "Compiler does not support 32bit compilation")
+ endif()
+endif()
diff --git a/src/host/config.tests/hostcompiler/CMakeLists.txt b/src/host/config.tests/hostcompiler/CMakeLists.txt
new file mode 100644
index 000000000..f36886d0a
--- /dev/null
+++ b/src/host/config.tests/hostcompiler/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(arch LANGUAGES CXX)
+
+add_executable(host_compiler_test)
+set_property(TARGET host_compiler_test PROPERTY MACOSX_BUNDLE FALSE)
+target_sources(host_compiler_test PRIVATE main.cpp)
+target_compile_options(host_compiler_test PRIVATE -m32)
+target_link_options(host_compiler_test PRIVATE -m32)
diff --git a/src/host/config.tests/hostcompiler/main.cpp b/src/host/config.tests/hostcompiler/main.cpp
new file mode 100644
index 000000000..9cd16a2e3
--- /dev/null
+++ b/src/host/config.tests/hostcompiler/main.cpp
@@ -0,0 +1,9 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include <stdio.h>
+int main()
+{
+ printf("This works\n");
+ return 0;
+}
diff --git a/src/ninja/CMakeLists.txt b/src/ninja/CMakeLists.txt
index f7ece52d4..0258b3da9 100644
--- a/src/ninja/CMakeLists.txt
+++ b/src/ninja/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
@@ -10,7 +13,7 @@ project(Ninja
set(NINJA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/ninja)
set(NINJA_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-find_package(Python2 REQUIRED)
+find_package(Python3 REQUIRED)
if(WIN32)
set(NINJA_EXECUTABLE ninja.exe)
@@ -25,7 +28,7 @@ add_custom_command(
WORKING_DIRECTORY ${NINJA_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${NINJA_BINARY_DIR}/$<CONFIG>
COMMAND ${CMAKE_COMMAND} -E chdir ${NINJA_BINARY_DIR}/$<CONFIG>
- ${Python2_EXECUTABLE} ${NINJA_SOURCE_DIR}/configure.py --bootstrap
+ ${Python3_EXECUTABLE} ${NINJA_SOURCE_DIR}/configure.py --bootstrap
USES_TERMINAL
VERBATIM
)
diff --git a/src/pdf/CMakeLists.txt b/src/pdf/CMakeLists.txt
index 9e4004adf..4a54b816e 100644
--- a/src/pdf/CMakeLists.txt
+++ b/src/pdf/CMakeLists.txt
@@ -1,14 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.19)
find_package(Ninja 1.7.2 REQUIRED)
-find_package(Python2 2.7.5 REQUIRED)
-find_package(Nodejs 10.19 REQUIRED)
+find_package(Nodejs 14.19 REQUIRED)
find_package(PkgConfig)
if(PkgConfig_FOUND)
create_pkg_config_host_wrapper(${CMAKE_CURRENT_BINARY_DIR})
endif()
set(buildDir "${CMAKE_CURRENT_BINARY_DIR}")
-add_subdirectory(plugins/imageformats/pdf)
##
# PDF MODULE
@@ -17,30 +18,35 @@ add_subdirectory(plugins/imageformats/pdf)
qt_internal_add_module(Pdf
SOURCES
qpdfbookmarkmodel.cpp qpdfbookmarkmodel.h
- qpdfdestination.cpp qpdfdestination.h qpdfdestination_p.h
qpdfdocument.cpp qpdfdocument.h qpdfdocument_p.h
qpdfdocumentrenderoptions.h
- qpdflinkmodel.cpp qpdflinkmodel_p.h qpdflinkmodel_p_p.h
- qpdfpagenavigation.cpp qpdfpagenavigation.h
+ qpdffile.cpp qpdffile_p.h
+ qpdflink.cpp qpdflink.h qpdflink_p.h
+ qpdflinkmodel.cpp qpdflinkmodel.h qpdflinkmodel_p.h
+ qpdfpagenavigator.cpp qpdfpagenavigator.h
qpdfpagerenderer.cpp qpdfpagerenderer.h
qpdfsearchmodel.cpp qpdfsearchmodel.h qpdfsearchmodel_p.h
- qpdfsearchresult.cpp qpdfsearchresult.h qpdfsearchresult_p.h
qpdfselection.cpp qpdfselection.h qpdfselection_p.h
qtpdfglobal.h
- qpdfnamespace.h
INCLUDE_DIRECTORIES
../3rdparty/chromium
DEFINES
QT_BUILD_PDF_LIB
- NOMINMAX
LIBRARIES
Qt::CorePrivate
Qt::Network
PUBLIC_LIBRARIES
Qt::Core
Qt::Gui
+ GENERATE_CPP_EXPORTS
)
+add_subdirectory(plugins/imageformats/pdf)
+
+get_install_config(config)
+get_architectures(archs)
+list(GET archs 0 arch)
+
##
# PDF DOCS
##
@@ -49,12 +55,22 @@ qt_internal_add_docs(Pdf
doc/qtpdf.qdocconf
)
+add_code_attributions_target(
+ TARGET generate_pdf_attributions
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pdf_attributions.qdoc
+ GN_TARGET :QtPdf
+ FILE_TEMPLATE doc/about_credits.tmpl
+ ENTRY_TEMPLATE doc/about_credits_entry.tmpl
+ BUILDDIR ${buildDir}/${config}/${arch}
+)
+add_dependencies(generate_pdf_attributions run_pdf_GnDone)
+add_dependencies(prepare_docs_Pdf generate_pdf_attributions)
##
# TOOLCHAIN SETUP
##
-if(LINUX)
+if(LINUX OR MINGW OR ANDROID)
setup_toolchains()
endif()
@@ -66,7 +82,6 @@ addSyncTargets(pdf)
get_configs(configs)
get_architectures(archs)
-
foreach(arch ${archs})
foreach(config ${configs})
@@ -76,7 +91,9 @@ foreach(arch ${archs})
set(buildGn pdf_${config}_${arch})
add_gn_target(${buildGn} ${config} ${arch}
- SOURCES DEFINES CXX_COMPILE_OPTIONS C_COMPILE_OPTIONS INCLUDES MOC_PATH
+ SOURCES DEFINES CXX_COMPILE_OPTIONS C_COMPILE_OPTIONS
+ INCLUDES MOC_PATH PNG_INCLUDES JPEG_INCLUDES HARFBUZZ_INCLUDES
+ FREETYPE_INCLUDES ZLIB_INCLUDES
)
resolve_target_includes(gnIncludes Pdf)
get_forward_declaration_macro(forwardDeclarationMacro)
@@ -99,27 +116,62 @@ foreach(arch ${archs})
list(APPEND gnArgArg
qtwebengine_target="${buildDir}/${config}/${arch}:QtPdf"
+ qt_libpng_config="${buildDir}/${config}/${arch}:qt_libpng_config"
+ qt_libjpeg_config="${buildDir}/${config}/${arch}:qt_libjpeg_config"
+ qt_harfbuzz_config="${buildDir}/${config}/${arch}:qt_harfbuzz_config"
+ qt_freetype_config="${buildDir}/${config}/${arch}:qt_freetype_config"
+ enable_swiftshader=false
+ enable_swiftshader_vulkan=false
+ angle_enable_swiftshader=false
+ dawn_use_swiftshader=false
+ use_dawn=false
+ build_dawn_tests=false
+ enable_ipc_fuzzer=false
enable_remoting=false
enable_resource_allowlist_generation=false
+ enable_vr=false
enable_web_speech=false
chrome_pgo_phase=0
+ strip_absolute_paths_from_debug_symbols=false
+ use_perfetto_client_library=false
+ v8_enable_webassembly=false
)
- if(LINUX)
- list(APPEND gnArgArg
- use_x11=false
- is_cfi=false
- ozone_auto_platforms=false
- use_gnome_keyring=false)
+ if(LINUX OR ANDROID)
+ list(APPEND gnArgArg
+ is_cfi=false
+ ozone_auto_platforms=false
+ enable_arcore=false
+ use_ml_inliner=false
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_system_icu
+ CONDITION QT_FEATURE_webengine_system_icu
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_system_libopenjpeg2
+ CONDITION QT_FEATURE_webengine_system_libopenjpeg2
+ )
endif()
if(MACOS)
- list(APPEND gnArgArg angle_enable_vulkan=false)
+ list(APPEND gnArgArg angle_enable_vulkan=false)
endif()
- if(WIN32)
+ if(IOS)
+ list(APPEND gnArgArg enable_base_tracing=false)
+ extend_gn_list(gnArgArg
+ ARGS enable_ios_bitcode
+ CONDITION QT_FEATURE_pdf_bitcode
+ )
+ endif()
+ if(WIN32 OR ANDROID)
list(APPEND gnArgArg
ninja_use_custom_environment_files=false
safe_browsing_mode=0
)
+ extend_gn_list(gnArgArg
+ ARGS qt_uses_static_runtime
+ CONDITION QT_FEATURE_pdf_static_runtime
+ )
endif()
extend_gn_list(gnArgArg
@@ -146,12 +198,40 @@ foreach(arch ${archs})
ARGS pdf_enable_xfa_tiff
CONDITION QT_FEATURE_pdf_xfa_tiff
)
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_zlib use_system_zlib
+ CONDITION QT_FEATURE_webengine_system_zlib
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_libpng use_system_libpng
+ CONDITION QT_FEATURE_webengine_system_libpng
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_qt_libpng
+ CONDITION QT_FEATURE_webengine_qt_libpng
+ )
+ extend_gn_list(gnArgArg
+ ARGS pdfium_use_system_libtiff
+ CONDITION QT_FEATURE_webengine_system_libtiff
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_qt_libjpeg
+ CONDITION QT_FEATURE_webengine_qt_libjpeg
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_qt_harfbuzz
+ CONDITION QT_FEATURE_webengine_qt_harfbuzz
+ )
+ extend_gn_list(gnArgArg
+ ARGS use_qt_freetype
+ CONDITION QT_FEATURE_webengine_qt_freetype
+ )
add_gn_command(
CMAKE_TARGET Pdf
NINJA_TARGETS QtPdf
GN_TARGET ${buildGn}
- GN_ARGS "${gnArgArg}"
+ GN_ARGS ${gnArgArg}
BUILDDIR ${buildDir}/${config}/${arch}
MODULE pdf
)
@@ -165,8 +245,16 @@ endforeach()
# PDF SETUP
##
-set(arch ${CMAKE_SYSTEM_PROCESSOR})
+get_architectures(archs)
+list(GET archs 0 arch)
target_include_directories(Pdf PRIVATE ${buildDir}/$<CONFIG>/${arch}/gen)
-add_gn_build_aritfacts_to_target(Pdf QtPdf pdf ${buildDir})
+add_gn_build_artifacts_to_target(
+ CMAKE_TARGET Pdf
+ NINJA_TARGET QtPdf
+ MODULE pdf
+ BUILDDIR ${buildDir}
+ COMPLETE_STATIC TRUE
+ NINJA_STAMP QtPdf.stamp
+)
add_dependencies(Pdf run_pdf_NinjaDone)
diff --git a/src/pdf/configure.cmake b/src/pdf/configure.cmake
index ce1203205..ac4e4e25f 100644
--- a/src/pdf/configure.cmake
+++ b/src/pdf/configure.cmake
@@ -1,7 +1,10 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_feature("pdf-v8" PRIVATE
LABEL "Support V8"
PURPOSE "Enables javascript support."
- AUTODETECT false
+ AUTODETECT FALSE
CONDITION NOT IOS
)
qt_feature("pdf-xfa" PRIVATE
@@ -29,6 +32,16 @@ qt_feature("pdf-xfa-tiff" PRIVATE
PURPOSE "Enables XFA-TIFF support."
CONDITION QT_FEATURE_pdf_xfa
)
+qt_feature("pdf-bitcode" PRIVATE
+ LABEL "Bitcode support"
+ PURPOSE "Enables bitcode"
+ CONDITION IOS
+)
+qt_feature("pdf-static-runtime" PRIVATE
+ LABEL "Use static runtime"
+ PURPOSE "Enables static runtime"
+ CONDITION WIN32 AND QT_FEATURE_static AND QT_FEATURE_static_runtime
+)
qt_configure_add_summary_section(NAME "Qt PDF")
qt_configure_add_summary_entry(ARGS "pdf-v8")
qt_configure_add_summary_entry(ARGS "pdf-xfa")
@@ -36,4 +49,6 @@ qt_configure_add_summary_entry(ARGS "pdf-xfa-bmp")
qt_configure_add_summary_entry(ARGS "pdf-xfa-gif")
qt_configure_add_summary_entry(ARGS "pdf-xfa-png")
qt_configure_add_summary_entry(ARGS "pdf-xfa-tiff")
+qt_configure_add_summary_entry(ARGS "pdf-bitcode")
+qt_configure_add_summary_entry(ARGS "pdf-static-runtime")
qt_configure_end_summary_section()
diff --git a/src/pdf/configure/BUILD.root.gn.in b/src/pdf/configure/BUILD.root.gn.in
index 5252b701a..e9f54ed6d 100644
--- a/src/pdf/configure/BUILD.root.gn.in
+++ b/src/pdf/configure/BUILD.root.gn.in
@@ -1,3 +1,28 @@
+import("//build/config/features.gni")
+
+config("qt_libpng_config") {
+ include_dirs = [ @GN_PNG_INCLUDES@ ]
+ defines = [ "USE_SYSTEM_LIBPNG" ]
+}
+config ("qt_libjpeg_config") {
+ include_dirs = [ @GN_JPEG_INCLUDES@ ]
+}
+config("qt_harfbuzz_config") {
+ visibility = [
+ "//third_party:freetype_harfbuzz",
+ "//third_party/freetype:freetype_source",
+ ]
+ include_dirs = [ @GN_HARFBUZZ_INCLUDES@ ]
+}
+config("qt_freetype_config") {
+ visibility = [
+ "//build/config/freetype:freetype",
+ "//third_party:freetype_harfbuzz",
+ "//third_party/harfbuzz-ng:harfbuzz_source",
+ ]
+ include_dirs = [ @GN_FREETYPE_INCLUDES@ ]
+}
+
config("QtPdf_config") {
cflags = [
@GN_CFLAGS_C@,
@@ -14,23 +39,35 @@ config("QtPdf_config") {
]
}
-config("cpp17_config") {
- # static initialized constexpr expressions must be compiled always as c++14 or always as c++17
- # and our qtwebengine core sources use them as c++17
+config("cpp20_config") {
+ # Chromium headers now use concepts and requires c++20
if (is_win) {
- cflags_cc = [ "/std:c++17" ]
+ cflags_cc = [ "/std:c++20" ]
} else {
- cflags_cc = [ "-std=c++17" ]
+ cflags_cc = [ "-std=c++20" ]
}
}
-shared_library("QtPdf") {
- rsp_types = [ "objects", "archives", "libs" ]
+static_library("QtPdf") {
+ complete_static_lib = true
+ rsp_types = [ "objects", "archives", "libs", "ldir" ]
configs += [
- ":cpp17_config",
+ ":cpp20_config",
":QtPdf_config"
]
deps = [
"//third_party/pdfium"
]
+ if (is_msvc) {
+ libs = [
+ "dloadhelper.lib",
+ "winmm.lib",
+ "usp10.lib",
+ ]
+ }
+ if (is_mingw) {
+ libs = [
+ "winmm",
+ ]
+ }
}
diff --git a/src/pdf/doc/about_credits.tmpl b/src/pdf/doc/about_credits.tmpl
new file mode 100644
index 000000000..57fae9e78
--- /dev/null
+++ b/src/pdf/doc/about_credits.tmpl
@@ -0,0 +1 @@
+{{entries}}
diff --git a/src/pdf/doc/about_credits_entry.tmpl b/src/pdf/doc/about_credits_entry.tmpl
new file mode 100644
index 000000000..294198709
--- /dev/null
+++ b/src/pdf/doc/about_credits_entry.tmpl
@@ -0,0 +1,13 @@
+/*!
+\page qtpdf-3rdparty-{{name-sanitized}}.html
+\attribution
+\ingroup qtpdf-licensing
+\brief {{license-type}}
+\title {{name}}
+
+\l{{{url}}}{Project Homepage}
+
+\badcode
+{{license}}
+\endcode
+*/
diff --git a/src/pdf/doc/images/multipageviewer.png b/src/pdf/doc/images/multipageviewer.png
new file mode 100644
index 000000000..2f0bb62a2
--- /dev/null
+++ b/src/pdf/doc/images/multipageviewer.png
Binary files differ
diff --git a/src/pdf/doc/images/pdfviewer.png b/src/pdf/doc/images/pdfviewer.png
new file mode 100644
index 000000000..ac8a31ac0
--- /dev/null
+++ b/src/pdf/doc/images/pdfviewer.png
Binary files differ
diff --git a/src/pdf/doc/images/search-results.png b/src/pdf/doc/images/search-results.png
new file mode 100644
index 000000000..91ee53b83
--- /dev/null
+++ b/src/pdf/doc/images/search-results.png
Binary files differ
diff --git a/src/pdf/doc/images/singlepageviewer.webp b/src/pdf/doc/images/singlepageviewer.webp
new file mode 100644
index 000000000..e429cb818
--- /dev/null
+++ b/src/pdf/doc/images/singlepageviewer.webp
Binary files differ
diff --git a/src/pdf/doc/images/wrapping-search-result.png b/src/pdf/doc/images/wrapping-search-result.png
new file mode 100644
index 000000000..108ec0444
--- /dev/null
+++ b/src/pdf/doc/images/wrapping-search-result.png
Binary files differ
diff --git a/src/pdf/doc/qtpdf.qdocconf b/src/pdf/doc/qtpdf.qdocconf
index 75d41af1d..d0340fe83 100644
--- a/src/pdf/doc/qtpdf.qdocconf
+++ b/src/pdf/doc/qtpdf.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtwebengine.qdocconf)
project = QtPdf
description = Qt Pdf Reference Documentation
@@ -29,6 +30,8 @@ qhp.QtPdf.subprojects.examples.indexTitle = Qt PDF Examples
qhp.QtPdf.subprojects.examples.selectors = doc:example
qhp.QtPdf.subprojects.examples.sortPages = true
+manifestmeta.highlighted.names += "QtPdf/PDF Multipage Viewer Example"
+
depends += qtcore \
qtwidgets \
qtgui \
@@ -36,14 +39,19 @@ depends += qtcore \
qmake \
qtdesigner \
qtquick \
- qtcmake
+ qtquickcontrols \
+ qtcmake \
+ qtsvg
-headerdirs += ../
+headerdirs += ../ \
+ ../../pdfwidgets
sourcedirs += ../ \
- ../../pdfquick
+ ../../pdfquick \
+ ../../pdfwidgets
exampledirs += ../../../examples/pdfwidgets \
+ ../../../examples/pdf \
snippets/
# add a generic thumbnail for an example that has no \image in its doc
@@ -55,5 +63,5 @@ navigation.landingpage = "Qt PDF"
navigation.cppclassespage = "Qt PDF C++ Classes"
navigation.qmltypespage = "Qt Quick PDF QML Types"
-# Fail the documentation build if there are more warnings than the limit
+# Enforce zero documentation warnings
warninglimit = 0
diff --git a/src/pdf/doc/snippets/multipageview.qml b/src/pdf/doc/snippets/multipageview.qml
new file mode 100644
index 000000000..113444165
--- /dev/null
+++ b/src/pdf/doc/snippets/multipageview.qml
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+import QtQuick
+import QtQuick.Pdf
+
+PdfMultiPageView {
+ document: PdfDocument { source: "my.pdf" }
+}
+//! [0]
diff --git a/src/pdf/doc/snippets/qtpdf-build.cmake b/src/pdf/doc/snippets/qtpdf-build.cmake
index d46b9c3ee..b4372d411 100644
--- a/src/pdf/doc/snippets/qtpdf-build.cmake
+++ b/src/pdf/doc/snippets/qtpdf-build.cmake
@@ -1,2 +1,2 @@
-find_package(Qt5 COMPONENTS Pdf REQUIRED)
-target_link_libraries(mytarget Qt5::Pdf)
+find_package(Qt6 REQUIRED COMPONENTS Pdf)
+target_link_libraries(mytarget Qt6::Pdf)
diff --git a/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc b/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc
index 25593b1ee..7d30ccdfd 100644
--- a/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc
+++ b/src/pdf/doc/snippets/qtpdf_build_snippet.qdoc
@@ -1,35 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [0]
QT += pdf
//! [0]
-
-
-//! [1]
-#include <QtPdf>
-//! [1]
diff --git a/src/pdf/doc/src/qtpdf-examples.qdoc b/src/pdf/doc/src/qtpdf-examples.qdoc
index 9daa0e7f8..02dc23dc2 100644
--- a/src/pdf/doc/src/qtpdf-examples.qdoc
+++ b/src/pdf/doc/src/qtpdf-examples.qdoc
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\group qtpdf-examples
- \ingroup all-examples
\title Qt PDF Examples
\brief Using the classes and types in the Qt PDF module.
diff --git a/src/pdf/doc/src/qtpdf-index.qdoc b/src/pdf/doc/src/qtpdf-index.qdoc
index 423a46873..b72619fbf 100644
--- a/src/pdf/doc/src/qtpdf-index.qdoc
+++ b/src/pdf/doc/src/qtpdf-index.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtpdf-index.html
@@ -36,8 +12,34 @@
and renders pages from it according to the options provided by
the \l QPdfDocumentRenderOptions class. The \l QPdfPageRenderer
class manages a queue that collects all render requests. The
- \l QPdfPageNavigation class handles the navigation through a
- PDF document.
+ \l QPdfPageNavigator class handles the navigation through a
+ PDF document. The \l QPdfSearchModel class searches for a string
+ and holds the search results. The QPdfBookmarkModel class holds the
+ table of contents, if present. The QPdfLinkModel holds information
+ about hyperlinks on a page. The \l QPdfView widget is a complete
+ PDF viewer, and the \l {PDF Viewer Widget Example} shows how to use it.
+
+ For Qt Quick applications, three kinds of full-featured viewer
+ components are provided. \l PdfMultiPageView should be your
+ first choice for the most common user experience: flicking
+ through the pages in the entire document.
+ \l PdfScrollablePageView shows one page at a time, with scrolling;
+ and \l PdfPageView shows one full page at a time, without scrolling.
+
+ The full-featured viewer components are composed of lower-level
+ QML components that can be used separately if you need to write a
+ more customized PDF viewing application: \l PdfDocument,
+ \l PdfPageImage, \l PdfPageNavigator, \l PdfSelection,
+ \l PdfSearchModel, \l PdfLinkModel, and \l PdfBookmarkModel.
+
+ If you only need to render page images, without features such as
+ text selection, search and navigation, this module includes a
+ \l QImageIOHandler plugin that treats PDF as a scalable
+ \l {Qt Image Formats}{image format}, similar to \l {Qt SVG}{SVG}.
+ You can simply use \l Image, and set the
+ \l {Image::currentFrame}{currentFrame} property to the page index
+ that you wish to display. If the PDF file does not render its own
+ background, the image has a transparent background.
\include module-use.qdocinc using qt module
\quotefile qtpdf-build.cmake
@@ -46,11 +48,6 @@
\section2 Building with qmake
- To include the definitions of the module's classes, use the
- following directive:
-
- \snippet qtpdf_build_snippet.qdoc 1
-
To link against the module, add this line to your qmake project file:
\snippet qtpdf_build_snippet.qdoc 0
@@ -67,4 +64,17 @@
\li \l{Qt PDF C++ Classes}
\li \l{Qt Quick PDF QML Types}
\endlist
+
+ \section1 Articles and Guides
+ \list
+ \li {Qt PDF Platform Notes} {Platform Notes}
+ \endlist
+
+ \section1 Licenses and Attributions
+
+ Qt PDF is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt PDF Licensing} for further details about this module.
*/
diff --git a/src/pdf/doc/src/qtpdf-licensing.qdoc b/src/pdf/doc/src/qtpdf-licensing.qdoc
new file mode 100644
index 000000000..190ee8331
--- /dev/null
+++ b/src/pdf/doc/src/qtpdf-licensing.qdoc
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \group qtpdf-licensing
+ \title Qt PDF Licensing
+
+ Qt PDF is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ The module includes a snapshot of PDFium. As such, users need to respect
+ the licenses of PDFium and third-party code included in it.
+
+ Third party licenses included in the sources are:
+*/
diff --git a/src/pdf/doc/src/qtpdf-module.qdoc b/src/pdf/doc/src/qtpdf-module.qdoc
index 4170deb38..e2ca8e4ce 100644
--- a/src/pdf/doc/src/qtpdf-module.qdoc
+++ b/src/pdf/doc/src/qtpdf-module.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
@@ -37,11 +13,6 @@
The Qt PDF module contains classes and functions for rendering
PDF documents.
- To include the definitions of the module's classes, use the
- following directive:
-
- \snippet qtpdf_build_snippet.qdoc 1
-
\if !defined(qtforpython)
To link against the module, add this line to your qmake project file:
diff --git a/src/pdf/doc/src/qtpdf-platformnotes.qdoc b/src/pdf/doc/src/qtpdf-platformnotes.qdoc
new file mode 100644
index 000000000..f50be120d
--- /dev/null
+++ b/src/pdf/doc/src/qtpdf-platformnotes.qdoc
@@ -0,0 +1,11 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtpdf-platformnotes.html
+ \title Qt PDF Platform Notes
+
+ Building Qt PDF for Android is currently
+ \l{https://bugreports.qt.io/browse/QTBUG-83459} {not supported} on Windows host platforms.
+*/
+
diff --git a/src/pdf/plugins/imageformats/pdf/CMakeLists.txt b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
index ee290782b..73a0b3144 100644
--- a/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
+++ b/src/pdf/plugins/imageformats/pdf/CMakeLists.txt
@@ -1,6 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_plugin(QPdfPlugin
OUTPUT_NAME qpdf
- TYPE imageformats
+ PLUGIN_TYPE imageformats
SOURCES
main.cpp
qpdfiohandler.cpp qpdfiohandler_p.h
diff --git a/src/pdf/plugins/imageformats/pdf/main.cpp b/src/pdf/plugins/imageformats/pdf/main.cpp
index b4d59353c..cb69c4ca1 100644
--- a/src/pdf/plugins/imageformats/pdf/main.cpp
+++ b/src/pdf/plugins/imageformats/pdf/main.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfiohandler_p.h"
diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
index 4f610935c..bb3e7c929 100644
--- a/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler.cpp
@@ -1,42 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfiohandler_p.h"
#include <QLoggingCategory>
#include <QPainter>
+#include <QtPdf/private/qpdffile_p.h>
QT_BEGIN_NAMESPACE
@@ -46,6 +14,12 @@ QPdfIOHandler::QPdfIOHandler()
{
}
+QPdfIOHandler::~QPdfIOHandler()
+{
+ if (m_ownsDocument)
+ delete m_doc;
+}
+
bool QPdfIOHandler::canRead() const
{
if (!device())
@@ -73,27 +47,27 @@ int QPdfIOHandler::currentImageNumber() const
QRect QPdfIOHandler::currentImageRect() const
{
- return QRect(QPoint(0, 0), m_doc.pageSize(m_page).toSize());
+ return QRect(QPoint(0, 0), m_doc->pagePointSize(m_page).toSize());
}
int QPdfIOHandler::imageCount() const
{
int ret = 0;
if (const_cast<QPdfIOHandler *>(this)->load(device()))
- ret = m_doc.pageCount();
- qCDebug(qLcPdf) << "imageCount" << ret;
+ ret = m_doc->pageCount();
+ qCDebug(qLcPdf) << ret;
return ret;
}
bool QPdfIOHandler::read(QImage *image)
{
if (load(device())) {
- if (m_page >= m_doc.pageCount())
+ if (m_doc.isNull() || m_page >= m_doc->pageCount())
return false;
if (m_page < 0)
m_page = 0;
const bool xform = (m_clipRect.isValid() || m_scaledSize.isValid() || m_scaledClipRect.isValid());
- QSize pageSize = m_doc.pageSize(m_page).toSize();
+ QSize pageSize = m_doc->pagePointSize(m_page).toSize();
QSize finalSize = pageSize;
QRectF bounds;
if (xform && !finalSize.isEmpty()) {
@@ -120,7 +94,7 @@ bool QPdfIOHandler::read(QImage *image)
t.translate(tr1.x(), tr1.y());
bounds = t.mapRect(bounds);
}
- qCDebug(qLcPdf) << Q_FUNC_INFO << m_page << finalSize;
+ qCDebug(qLcPdf) << m_page << finalSize;
if (image->size() != finalSize || !image->reinterpretAsFormat(QImage::Format_ARGB32_Premultiplied)) {
*image = QImage(finalSize, QImage::Format_ARGB32_Premultiplied);
if (!finalSize.isEmpty() && image->isNull()) {
@@ -136,9 +110,11 @@ bool QPdfIOHandler::read(QImage *image)
options.setScaledSize(pageSize);
image->fill(m_backColor.rgba());
QPainter p(image);
- QImage pageImage = m_doc.render(m_page, finalSize, options);
- p.drawImage(0, 0, pageImage);
- p.end();
+ if (!m_doc.isNull()) {
+ QImage pageImage = m_doc->render(m_page, finalSize, options);
+ p.drawImage(0, 0, pageImage);
+ p.end();
+ }
}
return true;
}
@@ -153,7 +129,7 @@ QVariant QPdfIOHandler::option(ImageOption option) const
return QImage::Format_ARGB32_Premultiplied;
case Size:
const_cast<QPdfIOHandler *>(this)->load(device());
- return m_doc.pageSize(qMax(0, m_page));
+ return m_doc->pagePointSize(qMax(0, m_page));
case ClipRect:
return m_clipRect;
case ScaledSize:
@@ -163,7 +139,7 @@ QVariant QPdfIOHandler::option(ImageOption option) const
case BackgroundColor:
return m_backColor;
case Name:
- return m_doc.metaData(QPdfDocument::Title);
+ return m_doc->metaData(QPdfDocument::MetaDataField::Title);
default:
break;
}
@@ -210,7 +186,7 @@ bool QPdfIOHandler::supportsOption(ImageOption option) const
bool QPdfIOHandler::jumpToImage(int frame)
{
- qCDebug(qLcPdf) << Q_FUNC_INFO << frame;
+ qCDebug(qLcPdf) << frame;
if (frame < 0 || frame >= imageCount())
return false;
m_page = frame;
@@ -230,8 +206,18 @@ bool QPdfIOHandler::load(QIODevice *device)
if (!canRead())
return false;
- m_doc.load(device);
- m_loaded = (m_doc.error() == QPdfDocument::DocumentError::NoError);
+ QPdfFile *pdfFile = qobject_cast<QPdfFile *>(device);
+ if (pdfFile) {
+ m_doc = pdfFile->document();
+ m_ownsDocument = false;
+ qCDebug(qLcPdf) << "loading via QPdfFile, reusing document instance" << m_doc;
+ } else {
+ m_doc = new QPdfDocument();
+ m_ownsDocument = true;
+ m_doc->load(device);
+ qCDebug(qLcPdf) << "loading via new document instance" << m_doc;
+ }
+ m_loaded = (m_doc->error() == QPdfDocument::Error::None);
return m_loaded;
}
diff --git a/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
index 99a91154c..c4d8e0f9a 100644
--- a/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
+++ b/src/pdf/plugins/imageformats/pdf/qpdfiohandler_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFIOHANDLER_H
#define QPDFIOHANDLER_H
@@ -57,6 +24,7 @@ class QPdfIOHandler : public QImageIOHandler
{
public:
QPdfIOHandler();
+ ~QPdfIOHandler() override;
bool canRead() const override;
static bool canRead(QIODevice *device);
int currentImageNumber() const override;
@@ -73,7 +41,7 @@ private:
bool load(QIODevice *device);
private:
- QPdfDocument m_doc;
+ QPointer<QPdfDocument> m_doc;
int m_page = -1;
QRect m_clipRect;
@@ -81,6 +49,7 @@ private:
QRect m_scaledClipRect;
QColor m_backColor = Qt::transparent;
bool m_loaded = false;
+ bool m_ownsDocument = false;
};
QT_END_NAMESPACE
diff --git a/src/pdf/qpdfbookmarkmodel.cpp b/src/pdf/qpdfbookmarkmodel.cpp
index 0450870a1..93dbf5d1f 100644
--- a/src/pdf/qpdfbookmarkmodel.cpp
+++ b/src/pdf/qpdfbookmarkmodel.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfbookmarkmodel.h"
@@ -42,19 +9,21 @@
#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdfview.h"
+#include <QLoggingCategory>
+#include <QMetaEnum>
#include <QPointer>
#include <QScopedPointer>
#include <private/qabstractitemmodel_p.h>
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(qLcBM, "qt.pdf.bookmarks")
+
class BookmarkNode
{
public:
explicit BookmarkNode(BookmarkNode *parentNode = nullptr)
: m_parentNode(parentNode)
- , m_level(0)
- , m_pageNumber(0)
{
}
@@ -81,7 +50,7 @@ public:
int childCount() const
{
- return m_childNodes.count();
+ return m_childNodes.size();
}
int row() const
@@ -127,32 +96,49 @@ public:
m_pageNumber = pageNumber;
}
+ QPointF location() const
+ {
+ return m_location;
+ }
+
+ void setLocation(qreal x, qreal y)
+ {
+ m_location = QPointF(x, y);
+ }
+
+ qreal zoom() const
+ {
+ return m_zoom;
+ }
+
+ void setZoom(qreal zoom)
+ {
+ m_zoom = zoom;
+ }
+
private:
QList<BookmarkNode*> m_childNodes;
BookmarkNode *m_parentNode;
QString m_title;
- int m_level;
- int m_pageNumber;
+ int m_level = 0;
+ int m_pageNumber = 0;
+ QPointF m_location;
+ qreal m_zoom = 0;
};
-class QPdfBookmarkModelPrivate : public QAbstractItemModelPrivate
+struct QPdfBookmarkModelPrivate
{
-public:
QPdfBookmarkModelPrivate()
- : QAbstractItemModelPrivate()
- , m_rootNode(new BookmarkNode(nullptr))
+ : m_rootNode(new BookmarkNode(nullptr))
, m_document(nullptr)
- , m_structureMode(QPdfBookmarkModel::TreeMode)
{
}
void rebuild()
{
- Q_Q(QPdfBookmarkModel);
-
- const bool documentAvailable = (m_document && m_document->status() == QPdfDocument::Ready);
+ const bool documentAvailable = (m_document && m_document->status() == QPdfDocument::Status::Ready);
if (documentAvailable) {
q->beginResetModel();
@@ -179,21 +165,29 @@ public:
while (bookmark) {
BookmarkNode *childBookmarkNode = nullptr;
- if (m_structureMode == QPdfBookmarkModel::TreeMode) {
- childBookmarkNode = new BookmarkNode(parentBookmarkNode);
- parentBookmarkNode->appendChild(childBookmarkNode);
- } else if (m_structureMode == QPdfBookmarkModel::ListMode) {
- childBookmarkNode = new BookmarkNode(m_rootNode.data());
- m_rootNode->appendChild(childBookmarkNode);
- }
+ childBookmarkNode = new BookmarkNode(parentBookmarkNode);
+ parentBookmarkNode->appendChild(childBookmarkNode);
+ Q_ASSERT(childBookmarkNode);
const int titleLength = int(FPDFBookmark_GetTitle(bookmark, nullptr, 0));
QList<char16_t> titleBuffer(titleLength);
- FPDFBookmark_GetTitle(bookmark, titleBuffer.data(), quint32(titleBuffer.length()));
+ FPDFBookmark_GetTitle(bookmark, titleBuffer.data(), quint32(titleBuffer.size()));
const FPDF_DEST dest = FPDFBookmark_GetDest(document, bookmark);
const int pageNumber = FPDFDest_GetDestPageIndex(document, dest);
+ const qreal pageHeight = m_document->pagePointSize(pageNumber).height();
+ FPDF_BOOL hasX, hasY, hasZoom;
+ FS_FLOAT x, y, zoom;
+ bool ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
+ if (ok) {
+ if (hasX && hasY)
+ childBookmarkNode->setLocation(x, pageHeight - y);
+ if (hasZoom)
+ childBookmarkNode->setZoom(zoom);
+ } else {
+ qCWarning(qLcBM) << "bookmark with invalid location and/or zoom" << x << y << zoom;
+ }
childBookmarkNode->setTitle(QString::fromUtf16(titleBuffer.data()));
childBookmarkNode->setLevel(level);
@@ -211,30 +205,67 @@ public:
rebuild();
}
- Q_DECLARE_PUBLIC(QPdfBookmarkModel)
+ QPdfBookmarkModel *q = nullptr;
QScopedPointer<BookmarkNode> m_rootNode;
QPointer<QPdfDocument> m_document;
- QPdfBookmarkModel::StructureMode m_structureMode;
+ QHash<int, QByteArray> m_roleNames;
};
+/*!
+ \class QPdfBookmarkModel
+ \since 5.10
+ \inmodule QtPdf
+ \inherits QAbstractItemModel
+
+ \brief The QPdfBookmarkModel class holds a tree of of links (anchors)
+ within a PDF document, such as the table of contents.
+
+ This is used in the \l {Model/View Programming} paradigm to display a
+ table of contents in the form of a tree or list.
+*/
+
+/*!
+ \enum QPdfBookmarkModel::Role
+
+ \value Title The name of the bookmark for display.
+ \value Level The level of indentation.
+ \value Page The page number of the destination (int).
+ \value Location The position of the destination (QPointF).
+ \value Zoom The suggested zoom level (qreal).
+ \omitvalue NRoles
+*/
+
+/*!
+ Constructs a new bookmark model with parent object \a parent.
+*/
QPdfBookmarkModel::QPdfBookmarkModel(QObject *parent)
- : QAbstractItemModel(*new QPdfBookmarkModelPrivate, parent)
+ : QAbstractItemModel(parent), d(new QPdfBookmarkModelPrivate)
{
+ d->q = this;
+ d->m_roleNames = QAbstractItemModel::roleNames();
+ QMetaEnum rolesMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("Role"));
+ for (int r = Qt::UserRole; r < int(Role::NRoles); ++r)
+ d->m_roleNames.insert(r, QByteArray(rolesMetaEnum.valueToKey(r)).toLower());
}
+/*!
+ Destroys the model.
+*/
+QPdfBookmarkModel::~QPdfBookmarkModel() = default;
+
QPdfDocument* QPdfBookmarkModel::document() const
{
- Q_D(const QPdfBookmarkModel);
-
return d->m_document;
}
+/*!
+ \property QPdfBookmarkModel::document
+ \brief the PDF document in which bookmarks are to be found.
+*/
void QPdfBookmarkModel::setDocument(QPdfDocument *document)
{
- Q_D(QPdfBookmarkModel);
-
if (d->m_document == document)
return;
@@ -250,65 +281,56 @@ void QPdfBookmarkModel::setDocument(QPdfDocument *document)
d->rebuild();
}
-QPdfBookmarkModel::StructureMode QPdfBookmarkModel::structureMode() const
-{
- Q_D(const QPdfBookmarkModel);
-
- return d->m_structureMode;
-}
-
-void QPdfBookmarkModel::setStructureMode(StructureMode mode)
-{
- Q_D(QPdfBookmarkModel);
-
- if (d->m_structureMode == mode)
- return;
-
- d->m_structureMode = mode;
- emit structureModeChanged(d->m_structureMode);
-
- d->rebuild();
-}
-
+/*!
+ \reimp
+*/
int QPdfBookmarkModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 1;
}
+/*!
+ \reimp
+*/
QHash<int, QByteArray> QPdfBookmarkModel::roleNames() const
{
- QHash<int, QByteArray> names;
-
- names[TitleRole] = "title";
- names[LevelRole] = "level";
- names[PageNumberRole] = "pageNumber";
-
- return names;
+ return d->m_roleNames;
}
+/*!
+ \reimp
+*/
QVariant QPdfBookmarkModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
const BookmarkNode *node = static_cast<BookmarkNode*>(index.internalPointer());
- switch (role) {
- case TitleRole:
+ switch (Role(role)) {
+ case Role::Title:
return node->title();
- case LevelRole:
+ case Role::Level:
return node->level();
- case PageNumberRole:
+ case Role::Page:
return node->pageNumber();
- default:
- return QVariant();
+ case Role::Location:
+ return node->location();
+ case Role::Zoom:
+ return node->zoom();
+ case Role::NRoles:
+ break;
}
+ if (role == Qt::DisplayRole)
+ return node->title();
+ return QVariant();
}
+/*!
+ \reimp
+*/
QModelIndex QPdfBookmarkModel::index(int row, int column, const QModelIndex &parent) const
{
- Q_D(const QPdfBookmarkModel);
-
if (!hasIndex(row, column, parent))
return QModelIndex();
@@ -326,10 +348,11 @@ QModelIndex QPdfBookmarkModel::index(int row, int column, const QModelIndex &par
return QModelIndex();
}
+/*!
+ \reimp
+*/
QModelIndex QPdfBookmarkModel::parent(const QModelIndex &index) const
{
- Q_D(const QPdfBookmarkModel);
-
if (!index.isValid())
return QModelIndex();
@@ -342,10 +365,11 @@ QModelIndex QPdfBookmarkModel::parent(const QModelIndex &index) const
return createIndex(parentNode->row(), 0, parentNode);
}
+/*!
+ \reimp
+*/
int QPdfBookmarkModel::rowCount(const QModelIndex &parent) const
{
- Q_D(const QPdfBookmarkModel);
-
if (parent.column() > 0)
return 0;
diff --git a/src/pdf/qpdfbookmarkmodel.h b/src/pdf/qpdfbookmarkmodel.h
index 8e06a1547..5a3c24f84 100644
--- a/src/pdf/qpdfbookmarkmodel.h
+++ b/src/pdf/qpdfbookmarkmodel.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFBOOKMARKMODEL_H
#define QPDFBOOKMARKMODEL_H
@@ -43,39 +10,33 @@
QT_BEGIN_NAMESPACE
class QPdfDocument;
-class QPdfBookmarkModelPrivate;
+struct QPdfBookmarkModelPrivate;
class Q_PDF_EXPORT QPdfBookmarkModel : public QAbstractItemModel
{
Q_OBJECT
Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(StructureMode structureMode READ structureMode WRITE setStructureMode NOTIFY structureModeChanged)
public:
- enum StructureMode
+ enum class Role : int
{
- TreeMode,
- ListMode
- };
- Q_ENUM(StructureMode)
-
- enum Role
- {
- TitleRole = Qt::DisplayRole,
- LevelRole = Qt::UserRole,
- PageNumberRole
+ Title = Qt::UserRole,
+ Level,
+ Page,
+ Location,
+ Zoom,
+ NRoles
};
Q_ENUM(Role)
- explicit QPdfBookmarkModel(QObject *parent = nullptr);
+ QPdfBookmarkModel() : QPdfBookmarkModel(nullptr) {}
+ explicit QPdfBookmarkModel(QObject *parent);
+ ~QPdfBookmarkModel() override;
QPdfDocument* document() const;
void setDocument(QPdfDocument *document);
- StructureMode structureMode() const;
- void setStructureMode(StructureMode mode);
-
QVariant data(const QModelIndex &index, int role) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
@@ -85,12 +46,13 @@ public:
Q_SIGNALS:
void documentChanged(QPdfDocument *document);
- void structureModeChanged(QPdfBookmarkModel::StructureMode structureMode);
private:
- Q_DECLARE_PRIVATE(QPdfBookmarkModel)
+ std::unique_ptr<QPdfBookmarkModelPrivate> d;
+
+ Q_PRIVATE_SLOT(d, void _q_documentStatusChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_documentStatusChanged())
+ friend struct QPdfBookmarkModelPrivate;
};
QT_END_NAMESPACE
diff --git a/src/pdf/qpdfdestination.cpp b/src/pdf/qpdfdestination.cpp
deleted file mode 100644
index b70e031ca..000000000
--- a/src/pdf/qpdfdestination.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "qpdfdestination.h"
-#include "qpdfdestination_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QPdfDestination
- \since 5.15
- \inmodule QtPdf
-
- \brief The QPdfDestination class defines a location on a page in a PDF
- document, and a suggested zoom level at which it is intended to be viewed.
-*/
-
-/*!
- Constructs an invalid Destination.
-
- \sa valid
-*/
-QPdfDestination::QPdfDestination()
- : d(new QPdfDestinationPrivate())
-{
-}
-
-QPdfDestination::QPdfDestination(int page, QPointF location, qreal zoom)
- : d(new QPdfDestinationPrivate(page, location, zoom))
-{
-}
-
-QPdfDestination::QPdfDestination(QPdfDestinationPrivate *d)
- : d(d)
-{
-}
-
-QPdfDestination::QPdfDestination(const QPdfDestination &other)
- : d(other.d)
-{
-}
-
-QPdfDestination::QPdfDestination(QPdfDestination &&other) noexcept
- : d(std::move(other.d))
-{
-}
-
-QPdfDestination::~QPdfDestination()
-{
-}
-
-QPdfDestination &QPdfDestination::operator=(const QPdfDestination &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- \property QPdfDestination::valid
-
- This property holds whether the destination is valid.
-*/
-bool QPdfDestination::isValid() const
-{
- return d->page >= 0;
-}
-
-/*!
- \property QPdfDestination::page
-
- This property holds the page number.
-*/
-int QPdfDestination::page() const
-{
- return d->page;
-}
-
-/*!
- \property QPdfDestination::location
-
- This property holds the location on the page, in units of points.
-*/
-QPointF QPdfDestination::location() const
-{
- return d->location;
-}
-
-/*!
- \property QPdfDestination::zoom
-
- This property holds the suggested magnification level, where 1.0 means default scale
- (1 pixel = 1 point).
-*/
-qreal QPdfDestination::zoom() const
-{
- return d->zoom;
-}
-
-QDebug operator<<(QDebug dbg, const QPdfDestination& dest)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace();
- dbg << "QPdfDestination(page=" << dest.page()
- << " location=" << dest.location()
- << " zoom=" << dest.zoom();
- dbg << ')';
- return dbg;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpdfdestination.cpp"
diff --git a/src/pdf/qpdfdestination.h b/src/pdf/qpdfdestination.h
deleted file mode 100644
index f9c186ff6..000000000
--- a/src/pdf/qpdfdestination.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFDESTINATION_H
-#define QPDFDESTINATION_H
-
-#include <QtPdf/qtpdfglobal.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qshareddata.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDestinationPrivate;
-
-class Q_PDF_EXPORT QPdfDestination
-{
- Q_GADGET
- Q_PROPERTY(bool valid READ isValid)
- Q_PROPERTY(int page READ page)
- Q_PROPERTY(QPointF location READ location)
- Q_PROPERTY(qreal zoom READ zoom)
-
-public:
- ~QPdfDestination();
- QPdfDestination(const QPdfDestination &other);
- QPdfDestination &operator=(const QPdfDestination &other);
- QPdfDestination(QPdfDestination &&other) noexcept;
- QPdfDestination &operator=(QPdfDestination &&other) noexcept { swap(other); return *this; }
- void swap(QPdfDestination &other) noexcept { d.swap(other.d); }
- bool isValid() const;
- int page() const;
- QPointF location() const;
- qreal zoom() const;
-
-protected:
- QPdfDestination();
- QPdfDestination(int page, QPointF location, qreal zoom);
- QPdfDestination(QPdfDestinationPrivate *d);
- friend class QPdfDocument;
- friend class QQuickPdfNavigationStack;
-
-protected:
- QExplicitlySharedDataPointer<QPdfDestinationPrivate> d;
-};
-
-Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfDestination &);
-
-QT_END_NAMESPACE
-
-#endif // QPDFDESTINATION_H
diff --git a/src/pdf/qpdfdestination_p.h b/src/pdf/qpdfdestination_p.h
deleted file mode 100644
index 3520fb795..000000000
--- a/src/pdf/qpdfdestination_p.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFDESTINATION_P_H
-#define QPDFDESTINATION_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 <QPointF>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDestinationPrivate : public QSharedData
-{
-public:
- QPdfDestinationPrivate() = default;
- QPdfDestinationPrivate(int page, QPointF location, qreal zoom)
- : page(page),
- location(location),
- zoom(zoom) { }
-
- int page = -1;
- QPointF location;
- qreal zoom = 1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFDESTINATION_P_H
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index dffc1e117..17fdb29b9 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfdocument.h"
#include "qpdfdocument_p.h"
@@ -46,9 +13,13 @@
#include <QFile>
#include <QHash>
#include <QLoggingCategory>
+#include <QMetaEnum>
#include <QMutex>
+#include <QPixmap>
#include <QVector2D>
+#include <QtCore/private/qtools_p.h>
+
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QRecursiveMutex, pdfMutex)
@@ -61,12 +32,83 @@ QPdfMutexLocker::QPdfMutexLocker()
{
}
+class Q_PDF_EXPORT QPdfPageModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ QPdfPageModel(QPdfDocument *doc) : QAbstractListModel(doc)
+ {
+ m_roleNames = QAbstractItemModel::roleNames();
+ QMetaEnum rolesMetaEnum = doc->metaObject()->enumerator(doc->metaObject()->indexOfEnumerator("PageModelRole"));
+ for (int r = Qt::UserRole; r < int(QPdfDocument::PageModelRole::NRoles); ++r) {
+ auto name = QByteArray(rolesMetaEnum.valueToKey(r));
+ name[0] = QtMiscUtils::toAsciiLower(name[0]);
+ m_roleNames.insert(r, name);
+ }
+ connect(doc, &QPdfDocument::statusChanged, this, [this](QPdfDocument::Status s) {
+ if (s == QPdfDocument::Status::Loading)
+ beginResetModel();
+ else if (s == QPdfDocument::Status::Ready)
+ endResetModel();
+ });
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (!index.isValid())
+ return QVariant();
+
+ switch (QPdfDocument::PageModelRole(role)) {
+ case QPdfDocument::PageModelRole::Label:
+ return document()->pageLabel(index.row());
+ case QPdfDocument::PageModelRole::PointSize:
+ return document()->pagePointSize(index.row());
+ case QPdfDocument::PageModelRole::NRoles:
+ break;
+ }
+
+ switch (role) {
+ case Qt::DecorationRole:
+ return pageThumbnail(index.row());
+ case Qt::DisplayRole:
+ return document()->pageLabel(index.row());
+ }
+
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override { return document()->pageCount(); }
+
+ QHash<int, QByteArray> roleNames() const override { return m_roleNames; }
+
+private:
+ QPdfDocument *document() const { return static_cast<QPdfDocument *>(parent()); }
+ QPixmap pageThumbnail(int page) const
+ {
+ auto it = m_thumbnails.constFind(page);
+ if (it == m_thumbnails.constEnd()) {
+ auto doc = document();
+ auto size = doc->pagePointSize(page);
+ size.scale(128, 128, Qt::KeepAspectRatio);
+ // TODO use QPdfPageRenderer for threading?
+ auto image = document()->render(page, size.toSize());
+ QPixmap ret = QPixmap::fromImage(image);
+ m_thumbnails.insert(page, ret);
+ return ret;
+ }
+ return it.value();
+ }
+
+ QHash<int, QByteArray> m_roleNames;
+ mutable QHash<int, QPixmap> m_thumbnails;
+};
+
QPdfDocumentPrivate::QPdfDocumentPrivate()
: avail(nullptr)
, doc(nullptr)
, loadComplete(false)
- , status(QPdfDocument::Null)
- , lastError(QPdfDocument::NoError)
+ , status(QPdfDocument::Status::Null)
+ , lastError(QPdfDocument::Error::None)
, pageCount(0)
{
asyncBuffer.setData(QByteArray());
@@ -74,8 +116,12 @@ QPdfDocumentPrivate::QPdfDocumentPrivate()
const QPdfMutexLocker lock;
- if (libraryRefCount == 0)
+ if (libraryRefCount == 0) {
+ QElapsedTimer timer;
+ timer.start();
FPDF_InitLibrary();
+ qCDebug(qLcDoc) << "FPDF_InitLibrary took" << timer.elapsed() << "ms";
+ }
++libraryRefCount;
// FPDF_FILEACCESS setup
@@ -97,8 +143,10 @@ QPdfDocumentPrivate::~QPdfDocumentPrivate()
const QPdfMutexLocker lock;
- if (!--libraryRefCount)
+ if (!--libraryRefCount) {
+ qCDebug(qLcDoc) << "FPDF_DestroyLibrary";
FPDF_DestroyLibrary();
+ }
}
void QPdfDocumentPrivate::clear()
@@ -117,6 +165,7 @@ void QPdfDocumentPrivate::clear()
if (pageCount != 0) {
pageCount = 0;
emit q->pageCountChanged(pageCount);
+ emit q->pageModelChanged();
}
loadComplete = false;
@@ -132,7 +181,7 @@ void QPdfDocumentPrivate::clear()
void QPdfDocumentPrivate::updateLastError()
{
if (doc) {
- lastError = QPdfDocument::NoError;
+ lastError = QPdfDocument::Error::None;
return;
}
@@ -141,15 +190,17 @@ void QPdfDocumentPrivate::updateLastError()
lock.unlock();
switch (error) {
- case FPDF_ERR_SUCCESS: lastError = QPdfDocument::NoError; break;
- case FPDF_ERR_UNKNOWN: lastError = QPdfDocument::UnknownError; break;
- case FPDF_ERR_FILE: lastError = QPdfDocument::FileNotFoundError; break;
- case FPDF_ERR_FORMAT: lastError = QPdfDocument::InvalidFileFormatError; break;
- case FPDF_ERR_PASSWORD: lastError = QPdfDocument::IncorrectPasswordError; break;
- case FPDF_ERR_SECURITY: lastError = QPdfDocument::UnsupportedSecuritySchemeError; break;
+ case FPDF_ERR_SUCCESS: lastError = QPdfDocument::Error::None; break;
+ case FPDF_ERR_UNKNOWN: lastError = QPdfDocument::Error::Unknown; break;
+ case FPDF_ERR_FILE: lastError = QPdfDocument::Error::FileNotFound; break;
+ case FPDF_ERR_FORMAT: lastError = QPdfDocument::Error::InvalidFileFormat; break;
+ case FPDF_ERR_PASSWORD: lastError = QPdfDocument::Error::IncorrectPassword; break;
+ case FPDF_ERR_SECURITY: lastError = QPdfDocument::Error::UnsupportedSecurityScheme; break;
default:
Q_UNREACHABLE();
}
+ if (lastError != QPdfDocument::Error::None)
+ qCDebug(qLcDoc) << "FPDF error" << error << "->" << lastError;
}
void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnership)
@@ -165,19 +216,19 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sequentialSourceDevice);
if (!reply) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
qWarning() << "QPdfDocument: Loading from sequential devices only supported with QNetworkAccessManager.";
return;
}
if (reply->isFinished() && reply->error() != QNetworkReply::NoError) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
QObject::connect(reply, &QNetworkReply::finished, q, [this, reply](){
if (reply->error() != QNetworkReply::NoError || reply->bytesAvailable() == 0) {
- this->setStatus(QPdfDocument::Error);
+ this->setStatus(QPdfDocument::Status::Error);
}
});
@@ -189,7 +240,7 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
device = newDevice;
initiateAsyncLoadWithTotalSizeKnown(device->size());
if (!avail) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
@@ -198,7 +249,7 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
if (!doc) {
updateLastError();
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
@@ -208,15 +259,16 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi
if (newPageCount != pageCount) {
pageCount = newPageCount;
emit q->pageCountChanged(pageCount);
+ emit q->pageModelChanged();
}
// If it's a local file, and the first couple of pages are available,
// probably the whole document is available.
if (checkPageComplete(0) && (pageCount < 2 || checkPageComplete(1))) {
- setStatus(QPdfDocument::Ready);
+ setStatus(QPdfDocument::Status::Ready);
} else {
updateLastError();
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
}
}
}
@@ -228,13 +280,13 @@ void QPdfDocumentPrivate::_q_tryLoadingWithSizeFromContentHeader()
const QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(sequentialSourceDevice);
if (!networkReply) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
const QVariant contentLength = networkReply->header(QNetworkRequest::ContentLengthHeader);
if (!contentLength.isValid()) {
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
return;
}
@@ -280,11 +332,10 @@ void QPdfDocumentPrivate::tryLoadDocument()
break;
case PDF_DATA_NOTAVAIL:
qCDebug(qLcDoc) << "data not yet available";
- lastError = QPdfDocument::DataNotYetAvailableError;
- setStatus(QPdfDocument::Error);
+ lastError = QPdfDocument::Error::DataNotYetAvailable;
break;
case PDF_DATA_AVAIL:
- // all good
+ lastError = QPdfDocument::Error::None;
break;
}
@@ -294,12 +345,14 @@ void QPdfDocumentPrivate::tryLoadDocument()
lock.unlock();
updateLastError();
+ if (lastError != QPdfDocument::Error::None)
+ setStatus(QPdfDocument::Status::Error);
- if (lastError == QPdfDocument::IncorrectPasswordError) {
+ if (lastError == QPdfDocument::Error::IncorrectPassword) {
FPDF_CloseDocument(doc);
doc = nullptr;
- setStatus(QPdfDocument::Error);
+ setStatus(QPdfDocument::Status::Error);
emit q->passwordRequired();
}
}
@@ -336,9 +389,10 @@ void QPdfDocumentPrivate::checkComplete()
if (newPageCount != pageCount) {
pageCount = newPageCount;
emit q->pageCountChanged(pageCount);
+ emit q->pageModelChanged();
}
- setStatus(QPdfDocument::Ready);
+ setStatus(QPdfDocument::Status::Ready);
}
}
@@ -392,7 +446,7 @@ void QPdfDocumentPrivate::fpdf_AddSegment(_FX_DOWNLOADHINTS *pThis, size_t offse
Q_UNUSED(size);
}
-QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count)
+QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int count) const
{
QList<ushort> buf(count + 1);
// TODO is that enough space in case one unicode character is more than one in utf-16?
@@ -401,23 +455,73 @@ QString QPdfDocumentPrivate::getText(FPDF_TEXTPAGE textPage, int startIndex, int
return QString::fromUtf16(reinterpret_cast<const char16_t *>(buf.constData()), len - 1);
}
-QPointF QPdfDocumentPrivate::getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex)
+QPointF QPdfDocumentPrivate::getCharPosition(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const
{
double x, y;
- int count = FPDFText_CountChars(textPage);
- bool ok = FPDFText_GetCharOrigin(textPage, qMin(count - 1, charIndex), &x, &y);
- if (!ok)
- return QPointF();
- return QPointF(x, pageHeight - y);
+ const int count = FPDFText_CountChars(textPage);
+ if (FPDFText_GetCharOrigin(textPage, qMin(count - 1, charIndex), &x, &y))
+ return mapPageToView(pdfPage, x, y);
+ return {};
}
-QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex)
+QRectF QPdfDocumentPrivate::getCharBox(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const
{
double l, t, r, b;
- bool ok = FPDFText_GetCharBox(textPage, charIndex, &l, &r, &b, &t);
- if (!ok)
- return QRectF();
- return QRectF(l, pageHeight - t, r - l, t - b);
+ if (FPDFText_GetCharBox(textPage, charIndex, &l, &r, &b, &t))
+ return mapPageToView(pdfPage, l, t, r, b);
+ return {};
+}
+
+/*! \internal
+ Convert the point \a x , \a y to the usual 1x (pixels = points)
+ 4th-quadrant "view" coordinate system relative to the top-left corner of
+ the rendered page. Some PDF files have internal transforms that make this
+ coordinate system different from "page coordinates", so we cannot just
+ subtract from page height to invert the y coordinates, in general.
+ */
+QPointF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double x, double y) const
+{
+ const auto pageHeight = FPDF_GetPageHeight(pdfPage);
+ const auto pageWidth = FPDF_GetPageWidth(pdfPage);
+ int rx, ry;
+ if (FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, x, y, &rx, &ry))
+ return QPointF(rx, ry);
+ return {};
+}
+
+/*! \internal
+ Convert the bounding box defined by \a left \a top \a right and \a bottom
+ to the usual 1x (pixels = points) 4th-quadrant "view" coordinate system
+ that we use for rendering things on top of the page image.
+ Some PDF files have internal transforms that make this coordinate
+ system different from "page coordinates", so we cannot just
+ subtract from page height to invert the y coordinates, in general.
+ */
+QRectF QPdfDocumentPrivate::mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) const
+{
+ const auto pageHeight = FPDF_GetPageHeight(pdfPage);
+ const auto pageWidth = FPDF_GetPageWidth(pdfPage);
+ int xfmLeft, xfmTop, xfmRight, xfmBottom;
+ if ( FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, left, top, &xfmLeft, &xfmTop) &&
+ FPDF_PageToDevice(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, right, bottom, &xfmRight, &xfmBottom) )
+ return QRectF(xfmLeft, xfmTop, xfmRight - xfmLeft, xfmBottom - xfmTop);
+ return {};
+}
+
+/*! \internal
+ Convert the point \a x , \a y \a from the usual 1x (pixels = points)
+ 4th-quadrant "view" coordinate system relative to the top-left corner of
+ the rendered page, to "page coordinates" suited to the given \a pdfPage,
+ which may have arbitrary internal transforms.
+ */
+QPointF QPdfDocumentPrivate::mapViewToPage(FPDF_PAGE pdfPage, QPointF position) const
+{
+ const auto pageHeight = FPDF_GetPageHeight(pdfPage);
+ const auto pageWidth = FPDF_GetPageWidth(pdfPage);
+ double rx, ry;
+ if (FPDF_DeviceToPage(pdfPage, 0, 0, qRound(pageWidth), qRound(pageHeight), 0, position.x(), position.y(), &rx, &ry))
+ return QPointF(rx, ry);
+ return {};
}
QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF position)
@@ -426,14 +530,14 @@ QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF
TextPosition result;
FPDF_PAGE pdfPage = FPDF_LoadPage(doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
- int hitIndex = FPDFText_GetCharIndexAtPos(textPage, position.x(), pageHeight - position.y(),
+ const QPointF pagePos = mapViewToPage(pdfPage, position);
+ int hitIndex = FPDFText_GetCharIndexAtPos(textPage, pagePos.x(), pagePos.y(),
CharacterHitTolerance, CharacterHitTolerance);
if (hitIndex >= 0) {
- QPointF charPos = getCharPosition(textPage, pageHeight, hitIndex);
+ QPointF charPos = getCharPosition(pdfPage, textPage, hitIndex);
if (!charPos.isNull()) {
- QRectF charBox = getCharBox(textPage, pageHeight, hitIndex);
+ QRectF charBox = getCharBox(pdfPage, textPage, hitIndex);
// If the given position is past the end of the line, i.e. if the right edge of the found character's
// bounding box is closer to it than the left edge is, we say that we "hit" the next character index after
if (qAbs(charBox.right() - position.x()) < qAbs(charPos.x() - position.x())) {
@@ -476,24 +580,39 @@ QPdfDocument::~QPdfDocument()
{
}
-QPdfDocument::DocumentError QPdfDocument::load(const QString &fileName)
+/*!
+ Loads the document contents from \a fileName.
+*/
+QPdfDocument::Error QPdfDocument::load(const QString &fileName)
{
qCDebug(qLcDoc) << "loading" << fileName;
close();
- d->setStatus(QPdfDocument::Loading);
+ d->setStatus(QPdfDocument::Status::Loading);
- QScopedPointer<QFile> f(new QFile(fileName));
+ std::unique_ptr<QFile> f(new QFile(fileName));
if (!f->open(QIODevice::ReadOnly)) {
- d->lastError = FileNotFoundError;
- d->setStatus(QPdfDocument::Error);
+ d->lastError = Error::FileNotFound;
+ d->setStatus(QPdfDocument::Status::Error);
} else {
- d->load(f.take(), /*transfer ownership*/true);
+ d->load(f.release(), /*transfer ownership*/true);
}
return d->lastError;
}
+/*! \internal
+ Returns the filename of the document that has been opened,
+ or an empty string if no document is open.
+*/
+QString QPdfDocument::fileName() const
+{
+ const QFile *f = qobject_cast<QFile *>(d->device.data());
+ if (f)
+ return f->fileName();
+ return QString();
+}
+
/*!
\enum QPdfDocument::Status
@@ -510,22 +629,35 @@ QPdfDocument::DocumentError QPdfDocument::load(const QString &fileName)
*/
/*!
- Returns the current status of the document.
+ \property QPdfDocument::status
+
+ This property holds the current status of the document.
*/
QPdfDocument::Status QPdfDocument::status() const
{
return d->status;
}
+/*!
+ Loads the document contents from \a device.
+*/
void QPdfDocument::load(QIODevice *device)
{
close();
- d->setStatus(QPdfDocument::Loading);
+ d->setStatus(QPdfDocument::Status::Loading);
d->load(device, /*transfer ownership*/false);
}
+/*!
+ \property QPdfDocument::password
+
+ This property holds the document password.
+
+ If the document is protected by a password, the user must provide it, and
+ the application must set this property. Otherwise, it's not needed.
+*/
void QPdfDocument::setPassword(const QString &password)
{
const QByteArray newPassword = password.toUtf8();
@@ -570,53 +702,36 @@ QVariant QPdfDocument::metaData(MetaDataField field) const
if (!d->doc)
return QString();
+ static QMetaEnum fieldsMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("MetaDataField"));
QByteArray fieldName;
switch (field) {
- case Title:
- fieldName = "Title";
- break;
- case Subject:
- fieldName = "Subject";
- break;
- case Author:
- fieldName = "Author";
- break;
- case Keywords:
- fieldName = "Keywords";
- break;
- case Producer:
- fieldName = "Producer";
- break;
- case Creator:
- fieldName = "Creator";
- break;
- case CreationDate:
- fieldName = "CreationDate";
- break;
- case ModificationDate:
+ case MetaDataField::ModificationDate:
fieldName = "ModDate";
break;
+ default:
+ fieldName = QByteArray(fieldsMetaEnum.valueToKey(int(field)));
+ break;
}
QPdfMutexLocker lock;
const unsigned long len = FPDF_GetMetaText(d->doc, fieldName.constData(), nullptr, 0);
QList<ushort> buf(len);
- FPDF_GetMetaText(d->doc, fieldName.constData(), buf.data(), buf.length());
+ FPDF_GetMetaText(d->doc, fieldName.constData(), buf.data(), buf.size());
lock.unlock();
QString text = QString::fromUtf16(reinterpret_cast<const char16_t *>(buf.data()));
switch (field) {
- case Title: // fall through
- case Subject:
- case Author:
- case Keywords:
- case Producer:
- case Creator:
+ case MetaDataField::Title: // fall through
+ case MetaDataField::Subject:
+ case MetaDataField::Author:
+ case MetaDataField::Keywords:
+ case MetaDataField::Producer:
+ case MetaDataField::Creator:
return text;
- case CreationDate: // fall through
- case ModificationDate:
+ case MetaDataField::CreationDate: // fall through
+ case MetaDataField::ModificationDate:
// convert a "D:YYYYMMDDHHmmSSOHH'mm'" into "YYYY-MM-DDTHH:mm:ss+HH:mm"
if (text.startsWith(QLatin1String("D:")))
text = text.mid(2);
@@ -635,20 +750,40 @@ QVariant QPdfDocument::metaData(MetaDataField field) const
return QVariant();
}
-QPdfDocument::DocumentError QPdfDocument::error() const
+/*!
+ \enum QPdfDocument::Error
+
+ This enum describes the error while attempting the last operation on the document.
+
+ \value None No error occurred.
+ \value Unknown Unknown type of error.
+ \value DataNotYetAvailable The document is still loading, it's too early to attempt the operation.
+ \value FileNotFound The file given to load() was not found.
+ \value InvalidFileFormat The file given to load() is not a valid PDF file.
+ \value IncorrectPassword The password given to setPassword() is not correct for this file.
+ \value UnsupportedSecurityScheme QPdfDocument is not able to unlock this kind of PDF file.
+
+ \sa QPdfDocument::error()
+*/
+
+/*!
+ Returns the type of error if \l status is \c Error, or \c NoError if there
+ is no error.
+*/
+QPdfDocument::Error QPdfDocument::error() const
{
return d->lastError;
}
/*!
- Closes the document.
+ Closes the document.
*/
void QPdfDocument::close()
{
if (!d->doc)
return;
- d->setStatus(Unloading);
+ d->setStatus(Status::Unloading);
d->clear();
@@ -657,19 +792,24 @@ void QPdfDocument::close()
emit passwordChanged();
}
- d->setStatus(Null);
+ d->setStatus(Status::Null);
}
/*!
- Returns the amount of pages for the loaded document or \c 0 if
- no document is loaded.
+ \property QPdfDocument::pageCount
+
+ This property holds the number of pages in the loaded document or \c 0 if
+ no document is loaded.
*/
int QPdfDocument::pageCount() const
{
return d->pageCount;
}
-QSizeF QPdfDocument::pageSize(int page) const
+/*!
+ Returns the size of page \a page in points (1/72 of an inch).
+*/
+QSizeF QPdfDocument::pagePointSize(int page) const
{
QSizeF result;
if (!d->doc || !d->checkPageComplete(page))
@@ -682,6 +822,74 @@ QSizeF QPdfDocument::pageSize(int page) const
}
/*!
+ \enum QPdfDocument::PageModelRole
+
+ Roles in pageModel().
+
+ \value Label The page number to be used for display purposes (QString).
+ \value PointSize The page size in points (1/72 of an inch) (QSizeF).
+ \omitvalue NRoles
+*/
+
+/*!
+ \property QPdfDocument::pageModel
+
+ This property holds an instance of QAbstractListModel to provide
+ page-specific metadata, containing one row for each page in the document.
+
+ \sa QPdfDocument::PageModelRole
+*/
+QAbstractListModel *QPdfDocument::pageModel()
+{
+ if (!d->pageModel)
+ d->pageModel = new QPdfPageModel(this);
+ return d->pageModel;
+}
+
+/*!
+ Returns the \a page number to be used for display purposes.
+
+ For example, a document may have multiple sections with different numbering.
+ Perhaps the preface uses roman numerals, the body starts on page 1, and the
+ appendix starts at A1. Whenever a PDF viewer shows a page number, to avoid
+ confusing the user it should be the same "number" as is printed on the
+ corner of the page, rather than the zero-based page index that we use in
+ APIs (assuming the document author has made the page labels match the
+ printed numbers).
+
+ If the document does not have custom page numbering, this function returns
+ \c {page + 1}.
+
+ \sa pageIndexForLabel()
+*/
+QString QPdfDocument::pageLabel(int page)
+{
+ const unsigned long len = FPDF_GetPageLabel(d->doc, page, nullptr, 0);
+ if (len == 0)
+ return QString::number(page + 1);
+ QList<char16_t> buf(len);
+ QPdfMutexLocker lock;
+ FPDF_GetPageLabel(d->doc, page, buf.data(), len);
+ lock.unlock();
+ return QString::fromUtf16(buf.constData());
+}
+
+/*!
+ Returns the index of the page that has the \a label, or \c -1 if not found.
+
+ \sa pageLabel()
+ \since 6.6
+*/
+int QPdfDocument::pageIndexForLabel(const QString &label)
+{
+ for (int i = 0; i < d->pageCount; ++i) {
+ if (pageLabel(i) == label)
+ return i;
+ }
+ return -1;
+}
+
+/*!
Renders the \a page into a QImage of size \a imageSize according to the
provided \a renderOptions.
@@ -709,37 +917,21 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
result.fill(Qt::transparent);
FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(result.width(), result.height(), FPDFBitmap_BGRA, result.bits(), result.bytesPerLine());
- int rotation = 0;
- switch (renderOptions.rotation()) {
- case QPdf::Rotate0:
- rotation = 0;
- break;
- case QPdf::Rotate90:
- rotation = 1;
- break;
- case QPdf::Rotate180:
- rotation = 2;
- break;
- case QPdf::Rotate270:
- rotation = 3;
- break;
- }
-
- const QPdf::RenderFlags renderFlags = renderOptions.renderFlags();
+ const QPdfDocumentRenderOptions::RenderFlags renderFlags = renderOptions.renderFlags();
int flags = 0;
- if (renderFlags & QPdf::RenderAnnotations)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::Annotations)
flags |= FPDF_ANNOT;
- if (renderFlags & QPdf::RenderOptimizedForLcd)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::OptimizedForLcd)
flags |= FPDF_LCD_TEXT;
- if (renderFlags & QPdf::RenderGrayscale)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::Grayscale)
flags |= FPDF_GRAYSCALE;
- if (renderFlags & QPdf::RenderForceHalftone)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::ForceHalftone)
flags |= FPDF_RENDER_FORCEHALFTONE;
- if (renderFlags & QPdf::RenderTextAliased)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::TextAliased)
flags |= FPDF_RENDER_NO_SMOOTHTEXT;
- if (renderFlags & QPdf::RenderImageAliased)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::ImageAliased)
flags |= FPDF_RENDER_NO_SMOOTHIMAGE;
- if (renderFlags & QPdf::RenderPathAliased)
+ if (renderFlags & QPdfDocumentRenderOptions::RenderFlag::PathAliased)
flags |= FPDF_RENDER_NO_SMOOTHPATH;
if (renderOptions.scaledClipRect().isValid()) {
@@ -752,7 +944,7 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
float y1 = clipRect.bottom();
float x2 = clipRect.right();
float y2 = clipRect.top();
- QSizeF origSize = pageSize(page);
+ QSizeF origSize = pagePointSize(page);
QVector2D pageScale(1, 1);
if (!renderOptions.scaledSize().isNull()) {
pageScale = QVector2D(renderOptions.scaledSize().width() / float(origSize.width()),
@@ -770,6 +962,7 @@ QImage QPdfDocument::render(int page, QSize imageSize, QPdfDocumentRenderOptions
qCDebug(qLcDoc) << "page" << page << "region" << renderOptions.scaledClipRect()
<< "size" << imageSize << "took" << timer.elapsed() << "ms";
} else {
+ const auto rotation = QPdfDocumentPrivate::toFPDFRotation(renderOptions.rotation());
FPDF_RenderPageBitmap(bitmap, pdfPage, 0, 0, result.width(), result.height(), rotation, flags);
qCDebug(qLcDoc) << "page" << page << "size" << imageSize << "took" << timer.elapsed() << "ms";
}
@@ -788,11 +981,12 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
{
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
+ const QPointF pageStart = d->mapViewToPage(pdfPage, start);
+ const QPointF pageEnd = d->mapViewToPage(pdfPage, end);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
- int startIndex = FPDFText_GetCharIndexAtPos(textPage, start.x(), pageHeight - start.y(),
+ int startIndex = FPDFText_GetCharIndexAtPos(textPage, pageStart.x(), pageStart.y(),
CharacterHitTolerance, CharacterHitTolerance);
- int endIndex = FPDFText_GetCharIndexAtPos(textPage, end.x(), pageHeight - end.y(),
+ int endIndex = FPDFText_GetCharIndexAtPos(textPage, pageEnd.x(), pageEnd.y(),
CharacterHitTolerance, CharacterHitTolerance);
QPdfSelection result;
@@ -803,7 +997,7 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
// If the given end position is past the end of the line, i.e. if the right edge of the last character's
// bounding box is closer to it than the left edge is, then extend the char range by one
- QRectF endCharBox = d->getCharBox(textPage, pageHeight, endIndex);
+ QRectF endCharBox = d->getCharBox(pdfPage, textPage, endIndex);
if (qAbs(endCharBox.right() - end.x()) < qAbs(endCharBox.x() - end.x()))
++endIndex;
@@ -815,7 +1009,7 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end)
for (int i = 0; i < rectCount; ++i) {
double l, r, b, t;
FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
- QRectF rect(l, pageHeight - t, r - l, t - b);
+ const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b);
if (hull.isNull())
hull = rect;
else
@@ -845,7 +1039,6 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma
return {};
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
int pageCount = FPDFText_CountChars(textPage);
if (startIndex >= pageCount)
@@ -856,11 +1049,11 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma
QString text;
if (maxLength > 0) {
text = d->getText(textPage, startIndex, maxLength);
- rectCount = FPDFText_CountRects(textPage, startIndex, text.length());
+ rectCount = FPDFText_CountRects(textPage, startIndex, text.size());
for (int i = 0; i < rectCount; ++i) {
double l, r, b, t;
FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
- QRectF rect(l, pageHeight - t, r - l, t - b);
+ const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b);
if (hull.isNull())
hull = rect;
else
@@ -869,14 +1062,14 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma
}
}
if (bounds.isEmpty())
- hull = QRectF(d->getCharPosition(textPage, pageHeight, startIndex), QSizeF());
+ hull = QRectF(d->getCharPosition(pdfPage, textPage, startIndex), QSizeF());
qCDebug(qLcDoc) << "on page" << page << "at index" << startIndex << "maxLength" << maxLength
- << "got" << text.length() << "chars," << rectCount << "rects within" << hull;
+ << "got" << text.size() << "chars," << rectCount << "rects within" << hull;
FPDFText_ClosePage(textPage);
FPDF_ClosePage(pdfPage);
- return QPdfSelection(text, bounds, hull, startIndex, startIndex + text.length());
+ return QPdfSelection(text, bounds, hull, startIndex, startIndex + text.size());
}
/*!
@@ -886,7 +1079,6 @@ QPdfSelection QPdfDocument::getAllText(int page)
{
const QPdfMutexLocker lock;
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
int count = FPDFText_CountChars(textPage);
if (count < 1)
@@ -898,7 +1090,7 @@ QPdfSelection QPdfDocument::getAllText(int page)
for (int i = 0; i < rectCount; ++i) {
double l, r, b, t;
FPDFText_GetRect(textPage, i, &l, &t, &r, &b);
- QRectF rect(l, pageHeight - t, r - l, t - b);
+ const QRectF rect = d->mapPageToView(pdfPage, l, t, r, b);
if (hull.isNull())
hull = rect;
else
@@ -915,4 +1107,5 @@ QPdfSelection QPdfDocument::getAllText(int page)
QT_END_NAMESPACE
+#include "qpdfdocument.moc"
#include "moc_qpdfdocument.cpp"
diff --git a/src/pdf/qpdfdocument.h b/src/pdf/qpdfdocument.h
index 54ca687fa..8355246ae 100644
--- a/src/pdf/qpdfdocument.h
+++ b/src/pdf/qpdfdocument.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFDOCUMENT_H
#define QPDFDOCUMENT_H
@@ -40,6 +7,7 @@
#include <QtPdf/qtpdfglobal.h>
#include <QtCore/qobject.h>
+#include <QtCore/QAbstractListModel>
#include <QtGui/qimage.h>
#include <QtPdf/qpdfdocumentrenderoptions.h>
#include <QtPdf/qpdfselection.h>
@@ -56,9 +24,10 @@ class Q_PDF_EXPORT QPdfDocument : public QObject
Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged FINAL)
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged FINAL)
Q_PROPERTY(Status status READ status NOTIFY statusChanged FINAL)
+ Q_PROPERTY(QAbstractListModel* pageModel READ pageModel NOTIFY pageModelChanged FINAL)
public:
- enum Status {
+ enum class Status {
Null,
Loading,
Ready,
@@ -67,18 +36,18 @@ public:
};
Q_ENUM(Status)
- enum DocumentError {
- NoError,
- UnknownError,
- DataNotYetAvailableError,
- FileNotFoundError,
- InvalidFileFormatError,
- IncorrectPasswordError,
- UnsupportedSecuritySchemeError
+ enum class Error {
+ None,
+ Unknown,
+ DataNotYetAvailable,
+ FileNotFound,
+ InvalidFileFormat,
+ IncorrectPassword,
+ UnsupportedSecurityScheme
};
- Q_ENUM(DocumentError)
+ Q_ENUM(Error)
- enum MetaDataField {
+ enum class MetaDataField {
Title,
Subject,
Author,
@@ -90,10 +59,18 @@ public:
};
Q_ENUM(MetaDataField)
- explicit QPdfDocument(QObject *parent = nullptr);
- ~QPdfDocument();
+ enum class PageModelRole {
+ Label = Qt::UserRole,
+ PointSize,
+ NRoles
+ };
+ Q_ENUM(PageModelRole)
+
+ QPdfDocument() : QPdfDocument(nullptr) {}
+ explicit QPdfDocument(QObject *parent);
+ ~QPdfDocument() override;
- DocumentError load(const QString &fileName);
+ Error load(const QString &fileName);
Status status() const;
@@ -103,13 +80,18 @@ public:
QVariant metaData(MetaDataField field) const;
- DocumentError error() const;
+ Error error() const;
void close();
int pageCount() const;
- QSizeF pageSize(int page) const;
+ Q_INVOKABLE QSizeF pagePointSize(int page) const;
+
+ Q_INVOKABLE QString pageLabel(int page);
+ Q_INVOKABLE int pageIndexForLabel(const QString &label);
+
+ QAbstractListModel *pageModel();
QImage render(int page, QSize imageSize, QPdfDocumentRenderOptions options = QPdfDocumentRenderOptions());
@@ -122,14 +104,19 @@ Q_SIGNALS:
void passwordRequired();
void statusChanged(QPdfDocument::Status status);
void pageCountChanged(int pageCount);
+ void pageModelChanged();
private:
- friend class QPdfBookmarkModelPrivate;
+ friend struct QPdfBookmarkModelPrivate;
+ friend class QPdfFile;
friend class QPdfLinkModelPrivate;
+ friend class QPdfPageModel;
friend class QPdfSearchModel;
friend class QPdfSearchModelPrivate;
friend class QQuickPdfSelection;
+ QString fileName() const;
+
Q_PRIVATE_SLOT(d, void _q_tryLoadingWithSizeFromContentHeader())
Q_PRIVATE_SLOT(d, void _q_copyFromSequentialSourceDevice())
QScopedPointer<QPdfDocumentPrivate> d;
diff --git a/src/pdf/qpdfdocument_p.h b/src/pdf/qpdfdocument_p.h
index b6ee2dfd0..cdb76d16f 100644
--- a/src/pdf/qpdfdocument_p.h
+++ b/src/pdf/qpdfdocument_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFDOCUMENT_P_H
#define QPDFDOCUMENT_P_H
@@ -49,6 +16,7 @@
//
#include "qpdfdocument.h"
+#include "qtpdfexports.h"
#include "third_party/pdfium/public/fpdfview.h"
#include "third_party/pdfium/public/fpdf_dataavail.h"
@@ -68,13 +36,16 @@ public:
QPdfMutexLocker();
};
-class Q_PDF_PRIVATE_EXPORT QPdfDocumentPrivate: public FPDF_FILEACCESS, public FX_FILEAVAIL, public FX_DOWNLOADHINTS
+class QPdfPageModel;
+
+class Q_PDF_EXPORT QPdfDocumentPrivate: public FPDF_FILEACCESS, public FX_FILEAVAIL, public FX_DOWNLOADHINTS
{
public:
QPdfDocumentPrivate();
~QPdfDocumentPrivate();
QPdfDocument *q;
+ QPdfPageModel *pageModel = nullptr;
FPDF_AVAIL avail;
FPDF_DOCUMENT doc;
@@ -87,7 +58,7 @@ public:
QByteArray password;
QPdfDocument::Status status;
- QPdfDocument::DocumentError lastError;
+ QPdfDocument::Error lastError;
int pageCount;
void clear();
@@ -107,9 +78,37 @@ public:
static int fpdf_GetBlock(void* param, unsigned long position, unsigned char* pBuf, unsigned long size);
static void fpdf_AddSegment(struct _FX_DOWNLOADHINTS* pThis, size_t offset, size_t size);
void updateLastError();
- QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count);
- QPointF getCharPosition(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex);
- QRectF getCharBox(FPDF_TEXTPAGE textPage, double pageHeight, int charIndex);
+ QString getText(FPDF_TEXTPAGE textPage, int startIndex, int count) const;
+ QPointF getCharPosition(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const;
+ QRectF getCharBox(FPDF_PAGE pdfPage, FPDF_TEXTPAGE textPage, int charIndex) const;
+ QPointF mapPageToView(FPDF_PAGE pdfPage, double x, double y) const;
+ QRectF mapPageToView(FPDF_PAGE pdfPage, double left, double top, double right, double bottom) const;
+ QPointF mapViewToPage(FPDF_PAGE pdfPage, QPointF position) const;
+
+ // FPDF takes the rotation parameter as an int.
+ // This enum is mapping the int values defined in fpdfview.h:956.
+ // (not using enum class to ensure int convertability)
+ enum QFPDFRotation {
+ Normal = 0,
+ ClockWise90 = 1,
+ ClockWise180 = 2,
+ CounterClockWise90 = 3
+ };
+
+ static constexpr QFPDFRotation toFPDFRotation(QPdfDocumentRenderOptions::Rotation rotation)
+ {
+ switch (rotation) {
+ case QPdfDocumentRenderOptions::Rotation::None:
+ return QFPDFRotation::Normal;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise90:
+ return QFPDFRotation::ClockWise90;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise180:
+ return QFPDFRotation::ClockWise180;
+ case QPdfDocumentRenderOptions::Rotation::Clockwise270:
+ return QFPDFRotation::CounterClockWise90;
+ }
+ Q_UNREACHABLE();
+ }
struct TextPosition {
QPointF position;
diff --git a/src/pdf/qpdfdocumentrenderoptions.h b/src/pdf/qpdfdocumentrenderoptions.h
index cafb4716f..af074d976 100644
--- a/src/pdf/qpdfdocumentrenderoptions.h
+++ b/src/pdf/qpdfdocumentrenderoptions.h
@@ -1,44 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFDOCUMENTRENDEROPTIONS_H
#define QPDFDOCUMENTRENDEROPTIONS_H
-#include <QtPdf/qpdfnamespace.h>
+#include <QtPdf/qtpdfglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
@@ -47,22 +14,41 @@ QT_BEGIN_NAMESPACE
class QPdfDocumentRenderOptions
{
public:
- Q_DECL_CONSTEXPR QPdfDocumentRenderOptions() noexcept : m_renderFlags(0), m_rotation(0), m_reserved(0) {}
-
- Q_DECL_CONSTEXPR QPdf::Rotation rotation() const noexcept { return static_cast<QPdf::Rotation>(m_rotation); }
- Q_DECL_RELAXED_CONSTEXPR void setRotation(QPdf::Rotation r) noexcept { m_rotation = r; }
-
- Q_DECL_CONSTEXPR QPdf::RenderFlags renderFlags() const noexcept { return static_cast<QPdf::RenderFlags>(m_renderFlags); }
- Q_DECL_RELAXED_CONSTEXPR void setRenderFlags(QPdf::RenderFlags r) noexcept { m_renderFlags = r; }
-
- Q_DECL_CONSTEXPR QRect scaledClipRect() const noexcept { return m_clipRect; }
- Q_DECL_RELAXED_CONSTEXPR void setScaledClipRect(const QRect &r) noexcept { m_clipRect = r; }
-
- Q_DECL_CONSTEXPR QSize scaledSize() const noexcept { return m_scaledSize; }
- Q_DECL_RELAXED_CONSTEXPR void setScaledSize(const QSize &s) noexcept { m_scaledSize = s; }
+ enum class Rotation {
+ None,
+ Clockwise90,
+ Clockwise180,
+ Clockwise270
+ };
+
+ enum class RenderFlag {
+ None = 0x000,
+ Annotations = 0x001,
+ OptimizedForLcd = 0x002,
+ Grayscale = 0x004,
+ ForceHalftone = 0x008,
+ TextAliased = 0x010,
+ ImageAliased = 0x020,
+ PathAliased = 0x040
+ };
+ Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
+
+ constexpr QPdfDocumentRenderOptions() noexcept : m_renderFlags(0), m_rotation(0), m_reserved(0) {}
+
+ constexpr Rotation rotation() const noexcept { return static_cast<Rotation>(m_rotation); }
+ constexpr void setRotation(Rotation r) noexcept { m_rotation = quint32(r); }
+
+ constexpr RenderFlags renderFlags() const noexcept { return static_cast<RenderFlags>(m_renderFlags); }
+ constexpr void setRenderFlags(RenderFlags r) noexcept { m_renderFlags = quint32(r.toInt()); }
+
+ constexpr QRect scaledClipRect() const noexcept { return m_clipRect; }
+ constexpr void setScaledClipRect(const QRect &r) noexcept { m_clipRect = r; }
+
+ constexpr QSize scaledSize() const noexcept { return m_scaledSize; }
+ constexpr void setScaledSize(const QSize &s) noexcept { m_scaledSize = s; }
private:
- friend Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept;
+ friend constexpr inline bool operator==(const QPdfDocumentRenderOptions &lhs, const QPdfDocumentRenderOptions &rhs) noexcept;
QRect m_clipRect;
QSize m_scaledSize;
@@ -74,15 +60,16 @@ private:
};
Q_DECLARE_TYPEINFO(QPdfDocumentRenderOptions, Q_PRIMITIVE_TYPE);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPdfDocumentRenderOptions::RenderFlags)
-Q_DECL_CONSTEXPR inline bool operator==(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept
+constexpr inline bool operator==(const QPdfDocumentRenderOptions &lhs, const QPdfDocumentRenderOptions &rhs) noexcept
{
return lhs.m_clipRect == rhs.m_clipRect && lhs.m_scaledSize == rhs.m_scaledSize &&
lhs.m_renderFlags == rhs.m_renderFlags && lhs.m_rotation == rhs.m_rotation &&
lhs.m_reserved == rhs.m_reserved && lhs.m_reserved2 == rhs.m_reserved2; // fix -Wunused-private-field
}
-Q_DECL_CONSTEXPR inline bool operator!=(QPdfDocumentRenderOptions lhs, QPdfDocumentRenderOptions rhs) noexcept
+constexpr inline bool operator!=(const QPdfDocumentRenderOptions &lhs, const QPdfDocumentRenderOptions &rhs) noexcept
{
return !operator==(lhs, rhs);
}
diff --git a/src/pdf/qpdfdocumentrenderoptions.qdoc b/src/pdf/qpdfdocumentrenderoptions.qdoc
index b8b506271..ad8e7bfdb 100644
--- a/src/pdf/qpdfdocumentrenderoptions.qdoc
+++ b/src/pdf/qpdfdocumentrenderoptions.qdoc
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfdocumentrenderoptions.h"
@@ -49,13 +16,42 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QPdfDocumentRenderOptions::Rotation
+
+ This enum describes the rotation of the page for rendering.
+
+ \value None Do not rotate (the default)
+ \value Clockwise90 Rotate 90 degrees clockwise
+ \value Clockwise180 Rotate 180 degrees
+ \value Clockwise270 Rotate 270 degrees clockwise
+
+ \sa QPdfDocument::render()
+*/
+/*!
+ \enum QPdfDocumentRenderOptions::RenderFlag
+
+ This enum is used to describe how a page should be rendered.
+
+ \value None The default value, representing no flags.
+ \value Annotations The page is rendered with annotations.
+ \value OptimizedForLcd The text of the page is rendered optimized for LCD display.
+ \value Grayscale The page is rendered grayscale.
+ \value ForceHalftone Always use halftones for rendering if the output image is stretched.
+ \value TextAliased Anti-aliasing is disabled for rendering text.
+ \value ImageAliased Anti-aliasing is disabled for rendering images.
+ \value PathAliased Anti-aliasing is disabled for rendering paths.
+
+ \sa QPdfDocument::render()
+*/
+
+/*!
\fn QPdfDocumentRenderOptions::QPdfDocumentRenderOptions()
Constructs a QPdfDocumentRenderOptions object.
*/
/*!
- \fn QPdf::Rotation QPdfDocumentRenderOptions::rotation() const
+ \fn QPdfDocumentRenderOptions::Rotation QPdfDocumentRenderOptions::rotation() const
Returns the rotation used for rendering a page from a PDF document.
@@ -63,7 +59,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QPdfDocumentRenderOptions::setRotation(QPdf::Rotation rotation)
+ \fn void QPdfDocumentRenderOptions::setRotation(QPdfDocumentRenderOptions::Rotation rotation)
Sets the \a rotation used for rendering a page from a PDF document.
@@ -71,7 +67,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QPdf::RenderFlags QPdfDocumentRenderOptions::renderFlags() const
+ \fn QPdfDocumentRenderOptions::RenderFlags QPdfDocumentRenderOptions::renderFlags() const
Returns the special flags used for rendering a page from a PDF document.
@@ -79,7 +75,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QPdfDocumentRenderOptions::setRenderFlags(QPdf::RenderFlags flags)
+ \fn void QPdfDocumentRenderOptions::setRenderFlags(QPdfDocumentRenderOptions::RenderFlags flags)
Sets the special \a flags used for rendering a page from a PDF document.
diff --git a/src/pdf/qpdffile.cpp b/src/pdf/qpdffile.cpp
new file mode 100644
index 000000000..a54f6a568
--- /dev/null
+++ b/src/pdf/qpdffile.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdffile_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QPdfFile
+ \inmodule QtPdf
+
+ QPdfFile is a means of passing a PDF file along with the associated
+ QPdfDocument together into QPdfIOHandler::load(QIODevice *device) so that
+ QPdfIOHandler does not need to construct its own redundant QPdfDocument
+ instance. If it succeeds in casting the QIODevice to a QPdfFile, it is
+ expected to use the QPdfDocument operations for all I/O, and thus the
+ normal QFile I/O functions are not needed for that use case.
+*/
+
+QPdfFile::QPdfFile(QPdfDocument *doc)
+ : QFile(doc->fileName()), m_document(doc)
+{
+}
+
+QT_END_NAMESPACE
+
+//#include "moc_qpdffile_p.cpp"
diff --git a/src/pdf/qpdffile_p.h b/src/pdf/qpdffile_p.h
new file mode 100644
index 000000000..f678cdcdc
--- /dev/null
+++ b/src/pdf/qpdffile_p.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFFILE_P_H
+#define QPDFFILE_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 "qpdfdocument.h"
+
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_PDF_EXPORT QPdfFile : public QFile
+{
+ Q_OBJECT
+public:
+ QPdfFile(QPdfDocument *doc);
+ QPdfDocument *document() { return m_document; }
+
+private:
+ QPdfDocument *m_document;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFFILE_P_H
diff --git a/src/pdf/qpdflink.cpp b/src/pdf/qpdflink.cpp
new file mode 100644
index 000000000..0c2867086
--- /dev/null
+++ b/src/pdf/qpdflink.cpp
@@ -0,0 +1,189 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdflink.h"
+#include "qpdflink_p.h"
+#include "qpdflinkmodel_p.h"
+#include <QGuiApplication>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPdfLink
+ \since 6.4
+ \inmodule QtPdf
+
+ \brief The QPdfLink class defines a link between a region on a page
+ (such as a hyperlink or a search result) and a destination
+ (page, location on the page, and zoom level at which to view it).
+*/
+
+/*!
+ Constructs an invalid Destination.
+
+ \sa valid
+*/
+QPdfLink::QPdfLink() :
+ QPdfLink(new QPdfLinkPrivate()) { }
+
+QPdfLink::QPdfLink(int page, QPointF location, qreal zoom)
+ : QPdfLink(new QPdfLinkPrivate(page, location, zoom))
+{
+}
+
+QPdfLink::QPdfLink(int page, QList<QRectF> rects,
+ QString contextBefore, QString contextAfter)
+ : QPdfLink(new QPdfLinkPrivate(page, std::move(rects),
+ std::move(contextBefore),
+ std::move(contextAfter)))
+{
+}
+
+QPdfLink::QPdfLink(QPdfLinkPrivate *d) : d(d) {}
+
+QPdfLink::~QPdfLink() = default;
+QPdfLink::QPdfLink(const QPdfLink &other) noexcept = default;
+QPdfLink::QPdfLink(QPdfLink &&other) noexcept = default;
+QPdfLink &QPdfLink::operator=(const QPdfLink &other) = default;
+
+/*!
+ \property QPdfLink::valid
+
+ This property holds whether the link is valid.
+*/
+bool QPdfLink::isValid() const
+{
+ return d->page >= 0;
+}
+
+/*!
+ \property QPdfLink::page
+
+ This property holds the page number.
+ If the link is a search result, it is the page number on which the result is found;
+ if the link is a hyperlink, it is the destination page number.
+*/
+int QPdfLink::page() const
+{
+ return d->page;
+}
+
+/*!
+ \property QPdfLink::location
+
+ This property holds the location on the \l page, in units of points.
+ If the link is a search result, it is the location where the result is found;
+ if the link is a hyperlink, it is the destination location.
+*/
+QPointF QPdfLink::location() const
+{
+ return d->location;
+}
+
+/*!
+ \property QPdfLink::zoom
+
+ This property holds the suggested magnification level, where 1.0 means default scale
+ (1 pixel = 1 point). If the link is a search result, this value is not used.
+*/
+qreal QPdfLink::zoom() const
+{
+ return d->zoom;
+}
+
+/*!
+ \property QPdfLink::url
+
+ This property holds the destination URL if the link is an external hyperlink;
+ otherwise, it's empty.
+*/
+QUrl QPdfLink::url() const
+{
+ return d->url;
+}
+
+/*!
+ \property QPdfLink::contextBefore
+
+ This property holds adjacent text found on the page before the search string.
+ If the link is a hyperlink, this string is empty.
+
+ \sa QPdfSearchModel::resultsOnPage(), QPdfSearchModel::resultAtIndex()
+*/
+QString QPdfLink::contextBefore() const
+{
+ return d->contextBefore;
+}
+
+/*!
+ \property QPdfLink::contextAfter
+
+ This property holds adjacent text found on the page after the search string.
+ If the link is a hyperlink, this string is empty.
+
+ \sa QPdfSearchModel::resultsOnPage(), QPdfSearchModel::resultAtIndex()
+*/
+QString QPdfLink::contextAfter() const
+{
+ return d->contextAfter;
+}
+
+/*!
+ \property QPdfLink::rectangles
+
+ This property holds the region (set of rectangles) occupied by the link or
+ search result on the page where it was found. If the text wraps around to
+ multiple lines on the page, there may be multiple rectangles:
+
+ \image wrapping-search-result.png
+
+ \sa QPdfSearchModel::resultsOnPage(), QPdfSearchModel::resultAtIndex()
+*/
+QList<QRectF> QPdfLink::rectangles() const
+{
+ return d->rects;
+}
+
+/*!
+ Returns a translated representation for display.
+
+ \sa copyToClipboard()
+*/
+QString QPdfLink::toString() const
+{
+ if (d->page <= 0)
+ return d->url.toString();
+ return QPdfLinkModel::tr("Page %1 location %2, %3 zoom %4")
+ .arg(d->page).arg(d->location.x(), 0, 'f', 1).arg(d->location.y(), 0, 'f', 1)
+ .arg(d->zoom, 0, 'f', 0);
+}
+
+/*!
+ Copies the toString() representation of the link to the
+ \l {QGuiApplication::clipboard()}{system clipboard} depending on the \a mode given.
+*/
+void QPdfLink::copyToClipboard(QClipboard::Mode mode) const
+{
+ QGuiApplication::clipboard()->setText(toString(), mode);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QPdfLink &link)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg << "QPdfLink(page=" << link.page()
+ << " location=" << link.location()
+ << " zoom=" << link.zoom()
+ << " contextBefore=" << link.contextBefore()
+ << " contextAfter=" << link.contextAfter()
+ << " rects=" << link.rectangles();
+ dbg << ')';
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qpdflink.cpp"
diff --git a/src/pdf/qpdflink.h b/src/pdf/qpdflink.h
new file mode 100644
index 000000000..63389afe6
--- /dev/null
+++ b/src/pdf/qpdflink.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINK_H
+#define QPDFLINK_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qshareddata.h>
+#include <QtGui/qclipboard.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+class QPdfLinkPrivate;
+
+class QPdfLink
+{
+ Q_GADGET_EXPORT(Q_PDF_EXPORT)
+ Q_PROPERTY(bool valid READ isValid)
+ Q_PROPERTY(int page READ page)
+ Q_PROPERTY(QPointF location READ location)
+ Q_PROPERTY(qreal zoom READ zoom)
+ Q_PROPERTY(QUrl url READ url)
+ Q_PROPERTY(QString contextBefore READ contextBefore)
+ Q_PROPERTY(QString contextAfter READ contextAfter)
+ Q_PROPERTY(QList<QRectF> rectangles READ rectangles)
+
+public:
+ Q_PDF_EXPORT QPdfLink();
+ Q_PDF_EXPORT ~QPdfLink();
+ Q_PDF_EXPORT QPdfLink &operator=(const QPdfLink &other);
+
+ Q_PDF_EXPORT QPdfLink(const QPdfLink &other) noexcept;
+ Q_PDF_EXPORT QPdfLink(QPdfLink &&other) noexcept;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QPdfLink)
+
+ void swap(QPdfLink &other) noexcept { d.swap(other.d); }
+
+ Q_PDF_EXPORT bool isValid() const;
+ Q_PDF_EXPORT int page() const;
+ Q_PDF_EXPORT QPointF location() const;
+ Q_PDF_EXPORT qreal zoom() const;
+ Q_PDF_EXPORT QUrl url() const;
+ Q_PDF_EXPORT QString contextBefore() const;
+ Q_PDF_EXPORT QString contextAfter() const;
+ Q_PDF_EXPORT QList<QRectF> rectangles() const;
+ Q_PDF_EXPORT Q_INVOKABLE QString toString() const;
+ Q_PDF_EXPORT Q_INVOKABLE void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
+
+private: // methods
+ QPdfLink(int page, QPointF location, qreal zoom);
+ QPdfLink(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter);
+ QPdfLink(QPdfLinkPrivate *d);
+ friend class QPdfDocument;
+ friend class QPdfLinkModelPrivate;
+ friend class QPdfSearchModelPrivate;
+ friend class QPdfPageNavigator;
+ friend class QQuickPdfPageNavigator;
+
+private: // storage
+ QExplicitlySharedDataPointer<QPdfLinkPrivate> d;
+
+};
+Q_DECLARE_SHARED(QPdfLink)
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfLink &);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPdfLink)
+
+#endif // QPDFLINK_H
diff --git a/src/pdf/qpdflink_p.h b/src/pdf/qpdflink_p.h
new file mode 100644
index 000000000..fa82f47c3
--- /dev/null
+++ b/src/pdf/qpdflink_p.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINK_P_H
+#define QPDFLINK_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 "qpdflink.h"
+
+#include <QPointF>
+#include <QRectF>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfLinkPrivate : public QSharedData
+{
+public:
+ QPdfLinkPrivate() = default;
+ QPdfLinkPrivate(int page, QPointF location, qreal zoom)
+ : page(page),
+ location(location),
+ zoom(zoom) { }
+ QPdfLinkPrivate(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter)
+ : page(page),
+ location(rects.first().topLeft()),
+ zoom(0),
+ contextBefore{std::move(contextBefore)},
+ contextAfter{std::move(contextAfter)},
+ rects{std::move(rects)} {}
+
+ int page = -1;
+ QPointF location;
+ qreal zoom = 1;
+ QString contextBefore;
+ QString contextAfter;
+ QUrl url;
+ QList<QRectF> rects;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFLINK_P_H
diff --git a/src/pdf/qpdflinkmodel.cpp b/src/pdf/qpdflinkmodel.cpp
index 5c2596bb9..0a8b1e812 100644
--- a/src/pdf/qpdflinkmodel.cpp
+++ b/src/pdf/qpdflinkmodel.cpp
@@ -1,41 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qpdflink_p.h"
+#include "qpdflinkmodel.h"
#include "qpdflinkmodel_p.h"
-#include "qpdflinkmodel_p_p.h"
#include "qpdfdocument_p.h"
#include "third_party/pdfium/public/fpdf_doc.h"
@@ -48,44 +16,85 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcLink, "qt.pdf.links")
+/*!
+ \class QPdfLinkModel
+ \since 6.6
+ \inmodule QtPdf
+ \inherits QAbstractListModel
+
+ \brief The QPdfLinkModel class holds the geometry and the destination for
+ each link that the specified \l page contains.
+
+ This is used in PDF viewers to implement the hyperlink mechanism.
+*/
+
+/*!
+ \enum QPdfLinkModel::Role
+
+ \value Link A QPdfLink object.
+ \value Rectangle Bounding rectangle around the link.
+ \value Url If the link is a web link, the URL for that; otherwise an empty URL.
+ \value Page If the link is an internal link, the page number to which the link should jump; otherwise \c {-1}.
+ \value Location If the link is an internal link, the location on the page to which the link should jump.
+ \value Zoom If the link is an internal link, the suggested zoom level on the destination page.
+ \omitvalue NRoles
+*/
+
+/*!
+ Constructs a new link model with parent object \a parent.
+*/
QPdfLinkModel::QPdfLinkModel(QObject *parent)
- : QAbstractListModel(*(new QPdfLinkModelPrivate()), parent)
+ : QAbstractListModel(parent),
+ d_ptr{std::make_unique<QPdfLinkModelPrivate>(this)}
{
+ Q_D(QPdfLinkModel);
QMetaEnum rolesMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("Role"));
- for (int r = Qt::UserRole; r < int(Role::_Count); ++r)
- m_roleNames.insert(r, QByteArray(rolesMetaEnum.valueToKey(r)).toLower());
+ for (int r = Qt::UserRole; r < int(Role::NRoles); ++r)
+ d->roleNames.insert(r, QByteArray(rolesMetaEnum.valueToKey(r)).toLower());
}
+/*!
+ Destroys the model.
+*/
QPdfLinkModel::~QPdfLinkModel() {}
QHash<int, QByteArray> QPdfLinkModel::roleNames() const
{
- return m_roleNames;
+ Q_D(const QPdfLinkModel);
+ return d->roleNames;
}
+/*!
+ \reimp
+*/
int QPdfLinkModel::rowCount(const QModelIndex &parent) const
{
Q_D(const QPdfLinkModel);
Q_UNUSED(parent);
- return d->links.count();
+ return d->links.size();
}
+/*!
+ \reimp
+*/
QVariant QPdfLinkModel::data(const QModelIndex &index, int role) const
{
Q_D(const QPdfLinkModel);
- const QPdfLinkModelPrivate::Link &link = d->links.at(index.row());
+ const auto &link = d->links.at(index.row());
switch (Role(role)) {
- case Role::Rect:
- return link.rect;
+ case Role::Link:
+ return QVariant::fromValue(link);
+ case Role::Rectangle:
+ return link.rectangles().empty() ? QVariant() : link.rectangles().constFirst();
case Role::Url:
- return link.url;
+ return link.url();
case Role::Page:
- return link.page;
+ return link.page();
case Role::Location:
- return link.location;
+ return link.location();
case Role::Zoom:
- return link.zoom;
- case Role::_Count:
+ return link.zoom();
+ case Role::NRoles:
break;
}
if (role == Qt::DisplayRole)
@@ -93,6 +102,10 @@ QVariant QPdfLinkModel::data(const QModelIndex &index, int role) const
return QVariant();
}
+/*!
+ \property QPdfLinkModel::document
+ \brief The document to load links from.
+*/
QPdfDocument *QPdfLinkModel::document() const
{
Q_D(const QPdfLinkModel);
@@ -115,6 +128,10 @@ void QPdfLinkModel::setDocument(QPdfDocument *document)
d->update();
}
+/*!
+ \property QPdfLinkModel::page
+ \brief The page to load links from.
+*/
int QPdfLinkModel::page() const
{
Q_D(const QPdfLinkModel);
@@ -132,8 +149,22 @@ void QPdfLinkModel::setPage(int page)
d->update();
}
-QPdfLinkModelPrivate::QPdfLinkModelPrivate() : QAbstractItemModelPrivate()
+/*!
+ Returns a \l {QPdfLink::isValid()}{valid} link if found under the \a point
+ (given in units of points, 1/72 of an inch), or an invalid link if it is
+ not found. In other words, this function is useful for picking, to handle
+ mouse click or hover.
+*/
+QPdfLink QPdfLinkModel::linkAt(QPointF point) const
{
+ Q_D(const QPdfLinkModel);
+ for (const auto &link : std::as_const(d->links)) {
+ for (const auto &rect : link.rectangles()) {
+ if (rect.contains(point))
+ return link;
+ }
+ }
+ return {};
}
void QPdfLinkModelPrivate::update()
@@ -148,7 +179,6 @@ void QPdfLinkModelPrivate::update()
qCWarning(qLcLink) << "failed to load page" << page;
return;
}
- double pageHeight = FPDF_GetPageHeight(pdfPage);
q->beginResetModel();
links.clear();
@@ -166,42 +196,68 @@ void QPdfLinkModelPrivate::update()
qCWarning(qLcLink) << "skipping link with invalid bounding box";
continue; // while enumerating links
}
- Link linkData;
- linkData.rect = QRectF(rect.left, pageHeight - rect.top,
- rect.right - rect.left, rect.top - rect.bottom);
+ // In case horizontal/vertical coordinates are flipped, swap them.
+ if (rect.right < rect.left)
+ std::swap(rect.right, rect.left);
+ if (rect.bottom > rect.top)
+ std::swap(rect.bottom, rect.top);
+
+ QPdfLink linkData;
+ // Use quad points if present; otherwise use the rect.
+ if (int quadPointsCount = FPDFLink_CountQuadPoints(linkAnnot) > 0) {
+ for (int i = 0; i < quadPointsCount; ++i) {
+ FS_QUADPOINTSF point;
+ if (FPDFLink_GetQuadPoints(linkAnnot, i, &point)) {
+ // Quadpoints are counter clockwise from bottom left (x1, y1)
+ QPolygonF poly;
+ poly << QPointF(point.x1, point.y1);
+ poly << QPointF(point.x2, point.y2);
+ poly << QPointF(point.x3, point.y3);
+ poly << QPointF(point.x4, point.y4);
+ QRectF bounds = poly.boundingRect();
+ bounds = document->d->mapPageToView(pdfPage, bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+ qCDebug(qLcLink) << "quadpoints" << i << "of" << quadPointsCount << ":" << poly << "mapped bounds" << bounds;
+ linkData.d->rects << bounds;
+ // QPdfLink could store polygons rather than rects, to get the benefit of quadpoints;
+ // so far we didn't bother. It would be an API change, and we'd need to use Shapes in PdfLinkDelegate.qml
+ }
+ }
+ } else {
+ linkData.d->rects << document->d->mapPageToView(pdfPage, rect.left, rect.top, rect.right, rect.bottom);
+ }
FPDF_DEST dest = FPDFLink_GetDest(doc, linkAnnot);
FPDF_ACTION action = FPDFLink_GetAction(linkAnnot);
switch (FPDFAction_GetType(action)) {
case PDFACTION_UNSUPPORTED: // this happens with valid links in some PDFs
case PDFACTION_GOTO: {
- linkData.page = FPDFDest_GetDestPageIndex(doc, dest);
- if (linkData.page < 0) {
- qCWarning(qLcLink) << "skipping link with invalid page number";
+ linkData.d->page = FPDFDest_GetDestPageIndex(doc, dest);
+ if (linkData.d->page < 0) {
+ qCWarning(qLcLink) << "skipping link with invalid page number" << linkData.d->page;
continue; // while enumerating links
}
FPDF_BOOL hasX, hasY, hasZoom;
FS_FLOAT x, y, zoom;
ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom);
if (!ok) {
- qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.rect;
+ qCWarning(qLcLink) << "link with invalid location and/or zoom @" << linkData.d->rects;
break; // at least we got a page number, so the link will jump there
}
if (hasX && hasY)
- linkData.location = QPointF(x, pageHeight - y);
+ linkData.d->location = document->d->mapPageToView(pdfPage, x, y);
if (hasZoom)
- linkData.zoom = zoom;
+ linkData.d->zoom = zoom;
break;
}
case PDFACTION_URI: {
unsigned long len = FPDFAction_GetURIPath(doc, action, nullptr, 0);
if (len < 1) {
- qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.rect;
+ qCWarning(qLcLink) << "skipping link with empty URI @" << linkData.d->rects;
continue; // while enumerating links
} else {
QByteArray buf(len, 0);
unsigned long got = FPDFAction_GetURIPath(doc, action, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QString::fromLatin1(buf.data(), got - 1);
+ linkData.d->url = QString::fromLatin1(buf.data(), got - 1);
}
break;
}
@@ -209,13 +265,13 @@ void QPdfLinkModelPrivate::update()
case PDFACTION_REMOTEGOTO: {
unsigned long len = FPDFAction_GetFilePath(action, nullptr, 0);
if (len < 1) {
- qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.rect;
+ qCWarning(qLcLink) << "skipping link with empty file path @" << linkData.d->rects;
continue; // while enumerating links
} else {
QByteArray buf(len, 0);
unsigned long got = FPDFAction_GetFilePath(action, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
+ linkData.d->url = QUrl::fromLocalFile(QString::fromLatin1(buf.data(), got - 1)).toString();
// Unfortunately, according to comments in fpdf_doc.h, if it's PDFACTION_REMOTEGOTO,
// we can't get the page and location without first opening the linked document
@@ -234,7 +290,7 @@ void QPdfLinkModelPrivate::update()
if (webLinks) {
int count = FPDFLink_CountWebLinks(webLinks);
for (int i = 0; i < count; ++i) {
- Link linkData;
+ QPdfLink linkData;
int len = FPDFLink_GetURL(webLinks, i, nullptr, 0);
if (len < 1) {
qCWarning(qLcLink) << "skipping link" << i << "with empty URL";
@@ -242,16 +298,15 @@ void QPdfLinkModelPrivate::update()
QList<unsigned short> buf(len);
int got = FPDFLink_GetURL(webLinks, i, buf.data(), len);
Q_ASSERT(got == len);
- linkData.url = QString::fromUtf16(
+ linkData.d->url = QString::fromUtf16(
reinterpret_cast<const char16_t *>(buf.data()), got - 1);
}
- FPDFLink_GetTextRange(webLinks, i, &linkData.textStart, &linkData.textCharCount);
len = FPDFLink_CountRects(webLinks, i);
for (int r = 0; r < len; ++r) {
double left, top, right, bottom;
bool success = FPDFLink_GetRect(webLinks, i, r, &left, &top, &right, &bottom);
if (success) {
- linkData.rect = QRectF(left, pageHeight - top, right - left, top - bottom);
+ linkData.d->rects << document->d->mapPageToView(pdfPage, left, top, right, bottom);
links << linkData;
}
}
@@ -264,8 +319,8 @@ void QPdfLinkModelPrivate::update()
// All done
FPDF_ClosePage(pdfPage);
if (Q_UNLIKELY(qLcLink().isDebugEnabled())) {
- for (const Link &l : links)
- qCDebug(qLcLink) << l.rect << l.toString();
+ for (const auto &l : links)
+ qCDebug(qLcLink) << l;
}
q->endResetModel();
}
@@ -274,21 +329,10 @@ void QPdfLinkModel::onStatusChanged(QPdfDocument::Status status)
{
Q_D(QPdfLinkModel);
qCDebug(qLcLink) << "sees document statusChanged" << status;
- if (status == QPdfDocument::Ready)
+ if (status == QPdfDocument::Status::Ready)
d->update();
}
-QString QPdfLinkModelPrivate::Link::toString() const
-{
- QString ret;
- if (page >= 0)
- return QLatin1String("page ") + QString::number(page) +
- QLatin1String(" location ") + QString::number(location.x()) + QLatin1Char(',') + QString::number(location.y()) +
- QLatin1String(" zoom ") + QString::number(zoom);
- else
- return url.toString();
-}
-
QT_END_NAMESPACE
#include "moc_qpdflinkmodel_p.cpp"
diff --git a/src/pdf/qpdflinkmodel.h b/src/pdf/qpdflinkmodel.h
new file mode 100644
index 000000000..be2ce890c
--- /dev/null
+++ b/src/pdf/qpdflinkmodel.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFLINKMODEL_H
+#define QPDFLINKMODEL_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtPdf/qpdfdocument.h>
+#include <QtPdf/qpdflink.h>
+
+#include <QtCore/QAbstractListModel>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfLinkModelPrivate;
+
+class Q_PDF_EXPORT QPdfLinkModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
+
+public:
+ enum class Role {
+ Link = Qt::UserRole,
+ Rectangle,
+ Url,
+ Page,
+ Location,
+ Zoom,
+ NRoles
+ };
+ Q_ENUM(Role)
+ explicit QPdfLinkModel(QObject *parent = nullptr);
+ ~QPdfLinkModel() override;
+
+ QPdfDocument *document() const;
+
+ QHash<int, QByteArray> roleNames() const override;
+ int rowCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+
+ int page() const;
+
+ QPdfLink linkAt(QPointF point) const;
+
+public Q_SLOTS:
+ void setDocument(QPdfDocument *document);
+ void setPage(int page);
+
+Q_SIGNALS:
+ void documentChanged();
+ void pageChanged(int page);
+
+private Q_SLOTS:
+ void onStatusChanged(QPdfDocument::Status status);
+
+private:
+ Q_DECLARE_PRIVATE(QPdfLinkModel)
+ const std::unique_ptr<QPdfLinkModelPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFLINKMODEL_H
diff --git a/src/pdf/qpdflinkmodel_p.h b/src/pdf/qpdflinkmodel_p.h
index cf9c0aad4..ba46a6e00 100644
--- a/src/pdf/qpdflinkmodel_p.h
+++ b/src/pdf/qpdflinkmodel_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFLINKMODEL_P_H
#define QPDFLINKMODEL_P_H
@@ -48,57 +15,26 @@
// We mean it.
//
-#include "qtpdfglobal.h"
-#include "qpdfdocument.h"
-
-#include <QObject>
-#include <QAbstractListModel>
+#include "qpdflinkmodel.h"
+#include <private/qabstractitemmodel_p.h>
QT_BEGIN_NAMESPACE
-class QPdfLinkModelPrivate;
-
-class Q_PDF_EXPORT QPdfLinkModel : public QAbstractListModel
+class QPdfLinkModelPrivate
{
- Q_OBJECT
- Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
- Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
+ QPdfLinkModel *q_ptr;
+ Q_DECLARE_PUBLIC(QPdfLinkModel)
public:
- enum class Role : int {
- Rect = Qt::UserRole,
- Url,
- Page,
- Location,
- Zoom,
- _Count
- };
- Q_ENUM(Role)
- explicit QPdfLinkModel(QObject *parent = nullptr);
- ~QPdfLinkModel();
-
- QPdfDocument *document() const;
-
- QHash<int, QByteArray> roleNames() const override;
- int rowCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
-
- int page() const;
-
-public Q_SLOTS:
- void setDocument(QPdfDocument *document);
- void setPage(int page);
-
-Q_SIGNALS:
- void documentChanged();
- void pageChanged(int page);
+ explicit QPdfLinkModelPrivate(QPdfLinkModel *qq)
+ : q_ptr(qq) {}
-private Q_SLOTS:
- void onStatusChanged(QPdfDocument::Status status);
+ void update();
-private:
- QHash<int, QByteArray> m_roleNames;
- Q_DECLARE_PRIVATE(QPdfLinkModel)
+ QHash<int, QByteArray> roleNames;
+ QPdfDocument *document = nullptr;
+ QList<QPdfLink> links;
+ int page = 0;
};
QT_END_NAMESPACE
diff --git a/src/pdf/qpdflinkmodel_p_p.h b/src/pdf/qpdflinkmodel_p_p.h
deleted file mode 100644
index 0606b4746..000000000
--- a/src/pdf/qpdflinkmodel_p_p.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFLINKMODEL_P_P_H
-#define QPDFLINKMODEL_P_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 "qpdflinkmodel_p.h"
-#include <private/qabstractitemmodel_p.h>
-
-#include "third_party/pdfium/public/fpdfview.h"
-
-#include <QUrl>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfLinkModelPrivate: public QAbstractItemModelPrivate
-{
- Q_DECLARE_PUBLIC(QPdfLinkModel)
-
-public:
- QPdfLinkModelPrivate();
-
- void update();
-
- struct Link {
- // where it is on the current page
- QRectF rect;
- int textStart = -1;
- int textCharCount = 0;
- // destination inside PDF
- int page = -1; // -1 means look at the url instead
- QPointF location;
- qreal zoom = 0; // 0 means no specified zoom: don't change when clicking
- // web destination
- QUrl url;
-
- QString toString() const;
- };
-
- QPdfDocument *document = nullptr;
- QList<Link> links;
- int page = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFLINKMODEL_P_P_H
diff --git a/src/pdf/qpdfnamespace.h b/src/pdf/qpdfnamespace.h
deleted file mode 100644
index e76d0abd9..000000000
--- a/src/pdf/qpdfnamespace.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFNAMESPACE_H
-#define QPDFNAMESPACE_H
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QPdf {
- Q_NAMESPACE
-
- enum Rotation {
- Rotate0,
- Rotate90,
- Rotate180,
- Rotate270
- };
- Q_ENUM_NS(Rotation)
-
- enum RenderFlag {
- NoRenderFlags = 0x000,
- RenderAnnotations = 0x001,
- RenderOptimizedForLcd = 0x002,
- RenderGrayscale = 0x004,
- RenderForceHalftone = 0x008,
- RenderTextAliased = 0x010,
- RenderImageAliased = 0x020,
- RenderPathAliased = 0x040
- };
- Q_FLAG_NS(RenderFlag)
- Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
-}
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QPdf::RenderFlags)
-
-QT_END_NAMESPACE
-#endif
diff --git a/src/pdf/qpdfnamespace.qdoc b/src/pdf/qpdfnamespace.qdoc
deleted file mode 100644
index 96bb090e9..000000000
--- a/src/pdf/qpdfnamespace.qdoc
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-
-/*!
- \namespace QPdf
- \inmodule QtPdf
- \keyword QPdf Namespace
-
- \brief The QPdf namespace contains miscellaneous identifiers
- used throughout the QtPdf module.
-*/
-
-/*!
- \enum QPdf::Rotation
-
- This enum describes the rotation of the page for rendering.
-
- \value Rotate0 Do not rotate (the default)
- \value Rotate90 Rotate 90 degrees clockwise
- \value Rotate180 Rotate 180 degrees
- \value Rotate270 Rotate 270 degrees clockwise
-
- \sa QPdfDocument::render()
-*/
-/*!
- \enum QPdf::RenderFlag
-
- This enum is used to describe how a page should be rendered.
-
- \value NoRenderFlags The default value, representing no flags.
- \value RenderAnnotations The page is rendered with annotations.
- \value RenderOptimizedForLcd The text of the page is rendered optimized for LCD display.
- \value RenderGrayscale The page is rendered grayscale.
- \value RenderForceHalftone Always use halftones for rendering if the output image is stretched.
- \value RenderTextAliased Anti-aliasing is disabled for rendering text.
- \value RenderImageAliased Anti-aliasing is disabled for rendering images.
- \value RenderPathAliased Anti-aliasing is disabled for rendering paths.
-
- \sa QPdfDocument::render()
-*/
-
diff --git a/src/pdf/qpdfpagenavigation.cpp b/src/pdf/qpdfpagenavigation.cpp
deleted file mode 100644
index 031b38962..000000000
--- a/src/pdf/qpdfpagenavigation.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "qpdfpagenavigation.h"
-
-#include "qpdfdocument.h"
-
-#include <private/qobject_p.h>
-
-#include <QPointer>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfPageNavigationPrivate
-{
-public:
- QPdfPageNavigationPrivate(QPdfPageNavigation *q) : q_ptr(q) { }
-
- void update()
- {
- const bool documentAvailable = m_document && m_document->status() == QPdfDocument::Ready;
-
- if (documentAvailable) {
- const int newPageCount = m_document->pageCount();
- if (m_pageCount != newPageCount) {
- m_pageCount = newPageCount;
- emit q_ptr->pageCountChanged(m_pageCount);
- }
- } else {
- if (m_pageCount != 0) {
- m_pageCount = 0;
- emit q_ptr->pageCountChanged(m_pageCount);
- }
- }
-
- if (m_currentPage != 0) {
- m_currentPage = 0;
- emit q_ptr->currentPageChanged(m_currentPage);
- }
-
- updatePrevNext();
- }
-
- void updatePrevNext()
- {
- const bool hasPreviousPage = m_currentPage > 0;
- const bool hasNextPage = m_currentPage < (m_pageCount - 1);
-
- if (m_canGoToPreviousPage != hasPreviousPage) {
- m_canGoToPreviousPage = hasPreviousPage;
- emit q_ptr->canGoToPreviousPageChanged(m_canGoToPreviousPage);
- }
-
- if (m_canGoToNextPage != hasNextPage) {
- m_canGoToNextPage = hasNextPage;
- emit q_ptr->canGoToNextPageChanged(m_canGoToNextPage);
- }
- }
-
- void documentStatusChanged()
- {
- update();
- }
-
- QPdfPageNavigation *q_ptr = nullptr;
- QPointer<QPdfDocument> m_document = nullptr;
- int m_currentPage = 0;
- int m_pageCount = 0;
- bool m_canGoToPreviousPage = false;
- bool m_canGoToNextPage = false;
-
- QMetaObject::Connection m_documentStatusChangedConnection;
-};
-
-/*!
- \class QPdfPageNavigation
- \since 5.10
- \inmodule QtPdf
-
- \brief The QPdfPageNavigation class handles the navigation through a PDF document.
-
- \sa QPdfDocument
-*/
-
-
-/*!
- Constructs a page navigation object with parent object \a parent.
-*/
-QPdfPageNavigation::QPdfPageNavigation(QObject *parent)
- : QObject(parent), d_ptr(new QPdfPageNavigationPrivate(this))
-{
-}
-
-/*!
- Destroys the page navigation object.
-*/
-QPdfPageNavigation::~QPdfPageNavigation()
-{
-}
-
-/*!
- \property QPdfPageNavigation::document
- \brief The document instance on which this object navigates.
-
- By default, this property is \c nullptr.
-
- \sa document(), setDocument(), QPdfDocument
-*/
-
-/*!
- Returns the document on which this object navigates, or a \c nullptr
- if none has set before.
-
- \sa QPdfDocument
-*/
-QPdfDocument* QPdfPageNavigation::document() const
-{
- return d_ptr->m_document;
-}
-
-/*!
- Sets the \a document this object navigates on.
-
- After a new document has been set, the currentPage will be \c 0.
-
- \sa QPdfDocument
-*/
-void QPdfPageNavigation::setDocument(QPdfDocument *document)
-{
- if (d_ptr->m_document == document)
- return;
-
- if (d_ptr->m_document)
- disconnect(d_ptr->m_documentStatusChangedConnection);
-
- d_ptr->m_document = document;
- emit documentChanged(d_ptr->m_document);
-
- if (d_ptr->m_document)
- d_ptr->m_documentStatusChangedConnection =
- connect(d_ptr->m_document.data(), &QPdfDocument::statusChanged, this,
- [this]() { d_ptr->documentStatusChanged(); });
-
- d_ptr->update();
-}
-
-/*!
- \property QPdfPageNavigation::currentPage
- \brief The current page number in the document.
-
- \sa currentPage(), setCurrentPage()
-*/
-
-/*!
- Returns the current page number or \c 0 if there is no document set.
-
- After a document has been loaded, the currentPage will always be \c 0.
-*/
-int QPdfPageNavigation::currentPage() const
-{
- return d_ptr->m_currentPage;
-}
-
-/*!
- \fn void QPdfPageNavigation::setCurrentPage(int page)
-
- Sets the current \a page number.
-*/
-void QPdfPageNavigation::setCurrentPage(int newPage)
-{
- if (newPage < 0 || newPage >= d_ptr->m_pageCount)
- return;
-
- if (d_ptr->m_currentPage == newPage)
- return;
-
- d_ptr->m_currentPage = newPage;
- emit currentPageChanged(d_ptr->m_currentPage);
-
- d_ptr->updatePrevNext();
-}
-
-/*!
- \property QPdfPageNavigation::pageCount
- \brief The number of pages in the document.
-
- \sa pageCount()
-*/
-
-/*!
- Returns the number of pages in the document or \c 0 if there
- is no document set.
-*/
-int QPdfPageNavigation::pageCount() const
-{
- return d_ptr->m_pageCount;
-}
-
-/*!
- \property QPdfPageNavigation::canGoToPreviousPage
- \brief Indicates whether there is a page before the current page.
-
- \sa canGoToPreviousPage(), goToPreviousPage()
-*/
-
-/*!
- Returns whether there is a page before the current one.
-*/
-bool QPdfPageNavigation::canGoToPreviousPage() const
-{
- return d_ptr->m_canGoToPreviousPage;
-}
-
-/*!
- \property QPdfPageNavigation::canGoToNextPage
- \brief Indicates whether there is a page after the current page.
-
- \sa canGoToNextPage(), goToNextPage()
-*/
-
-/*!
- Returns whether there is a page after the current one.
-*/
-bool QPdfPageNavigation::canGoToNextPage() const
-{
- return d_ptr->m_canGoToNextPage;
-}
-
-/*!
- Changes the current page to the previous page.
-
- If there is no previous page in the document, nothing happens.
-
- \sa canGoToPreviousPage
-*/
-void QPdfPageNavigation::goToPreviousPage()
-{
- if (d_ptr->m_currentPage > 0)
- setCurrentPage(d_ptr->m_currentPage - 1);
-}
-
-/*!
- Changes the current page to the next page.
-
- If there is no next page in the document, nothing happens.
-
- \sa canGoToNextPage
-*/
-void QPdfPageNavigation::goToNextPage()
-{
- if (d_ptr->m_currentPage < d_ptr->m_pageCount - 1)
- setCurrentPage(d_ptr->m_currentPage + 1);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpdfpagenavigation.cpp"
diff --git a/src/pdf/qpdfpagenavigation.h b/src/pdf/qpdfpagenavigation.h
deleted file mode 100644
index dc412c33b..000000000
--- a/src/pdf/qpdfpagenavigation.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFPAGENAVIGATION_H
-#define QPDFPAGENAVIGATION_H
-
-#include <QtPdf/qtpdfglobal.h>
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfDocument;
-class QPdfPageNavigationPrivate;
-
-class Q_PDF_EXPORT QPdfPageNavigation : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
-
- Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged)
- Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged)
- Q_PROPERTY(bool canGoToPreviousPage READ canGoToPreviousPage NOTIFY canGoToPreviousPageChanged)
- Q_PROPERTY(bool canGoToNextPage READ canGoToNextPage NOTIFY canGoToNextPageChanged)
-
-public:
- explicit QPdfPageNavigation(QObject *parent = nullptr);
- ~QPdfPageNavigation();
-
- QPdfDocument* document() const;
- void setDocument(QPdfDocument *document);
-
- int currentPage() const;
- void setCurrentPage(int currentPage);
-
- int pageCount() const;
-
- bool canGoToPreviousPage() const;
- bool canGoToNextPage() const;
-
-public Q_SLOTS:
- void goToPreviousPage();
- void goToNextPage();
-
-Q_SIGNALS:
- void documentChanged(QPdfDocument *document);
- void currentPageChanged(int currentPage);
- void pageCountChanged(int pageCount);
- void canGoToPreviousPageChanged(bool canGo);
- void canGoToNextPageChanged(bool canGo);
-
-private:
- QScopedPointer<QPdfPageNavigationPrivate> d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/pdf/qpdfpagenavigator.cpp b/src/pdf/qpdfpagenavigator.cpp
new file mode 100644
index 000000000..e077e2184
--- /dev/null
+++ b/src/pdf/qpdfpagenavigator.cpp
@@ -0,0 +1,362 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdfpagenavigator.h"
+#include "qpdfdocument.h"
+#include "qpdflink_p.h"
+
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.pagenavigator")
+
+struct QPdfPageNavigatorPrivate
+{
+ QPdfPageNavigator *q = nullptr;
+
+ QList<QExplicitlySharedDataPointer<QPdfLinkPrivate>> pageHistory;
+ int currentHistoryIndex = 0;
+ bool changing = false;
+};
+
+/*!
+ \class QPdfPageNavigator
+ \since 6.4
+ \inmodule QtPdf
+ \brief Navigation history within a PDF document.
+
+ The QPdfPageNavigator class remembers which destinations the user
+ has visited in a PDF document, and provides the ability to traverse
+ backward and forward. It is used to implement back and forward actions
+ similar to the back and forward buttons in a web browser.
+
+ \sa QPdfDocument
+*/
+
+/*!
+ Constructs a page navigation stack with parent object \a parent.
+*/
+QPdfPageNavigator::QPdfPageNavigator(QObject *parent)
+ : QObject(parent), d(new QPdfPageNavigatorPrivate)
+{
+ d->q = this;
+ clear();
+}
+
+/*!
+ Destroys the page navigation stack.
+*/
+QPdfPageNavigator::~QPdfPageNavigator()
+{
+}
+
+/*!
+ Goes back to the page, location and zoom level that was being viewed before
+ back() was called, and then emits the \l jumped() signal.
+
+ If a new destination was pushed since the last time \l back() was called,
+ the forward() function does nothing, because there is a branch in the
+ timeline which causes the "future" to be lost.
+*/
+void QPdfPageNavigator::forward()
+{
+ if (d->currentHistoryIndex >= d->pageHistory.size() - 1)
+ return;
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ QPointF currentLocationWas = currentLocation();
+ qreal currentZoomWas = currentZoom();
+ ++d->currentHistoryIndex;
+ d->changing = true;
+ emit jumped(currentLink());
+ if (currentZoomWas != currentZoom())
+ emit currentZoomChanged(currentZoom());
+ emit currentPageChanged(currentPage());
+ if (currentLocationWas != currentLocation())
+ emit currentLocationChanged(currentLocation());
+ if (!backAvailableWas)
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas != forwardAvailable())
+ emit forwardAvailableChanged(forwardAvailable());
+ d->changing = false;
+ qCDebug(qLcNav) << "forward: index" << d->currentHistoryIndex << "page" << currentPage()
+ << "@" << currentLocation() << "zoom" << currentZoom();
+}
+
+/*!
+ Pops the stack, updates the \l currentPage, \l currentLocation and
+ \l currentZoom properties to the most-recently-viewed destination, and then
+ emits the \l jumped() signal.
+*/
+void QPdfPageNavigator::back()
+{
+ if (d->currentHistoryIndex <= 0)
+ return;
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ QPointF currentLocationWas = currentLocation();
+ qreal currentZoomWas = currentZoom();
+ --d->currentHistoryIndex;
+ d->changing = true;
+ emit jumped(currentLink());
+ if (currentZoomWas != currentZoom())
+ emit currentZoomChanged(currentZoom());
+ emit currentPageChanged(currentPage());
+ if (currentLocationWas != currentLocation())
+ emit currentLocationChanged(currentLocation());
+ if (backAvailableWas != backAvailable())
+ emit backAvailableChanged(backAvailable());
+ if (!forwardAvailableWas)
+ emit forwardAvailableChanged(forwardAvailable());
+ d->changing = false;
+ qCDebug(qLcNav) << "back: index" << d->currentHistoryIndex << "page" << currentPage()
+ << "@" << currentLocation() << "zoom" << currentZoom();
+}
+/*!
+ \property QPdfPageNavigator::currentPage
+
+ This property holds the current page that is being viewed.
+ The default is \c 0.
+*/
+int QPdfPageNavigator::currentPage() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return -1; // only until ctor or clear() runs
+ return d->pageHistory.at(d->currentHistoryIndex)->page;
+}
+
+/*!
+ \property QPdfPageNavigator::currentLocation
+
+ This property holds the current location on the page that is being viewed
+ (the location that was last given to jump() or update()). The default is
+ \c {0, 0}.
+*/
+QPointF QPdfPageNavigator::currentLocation() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return QPointF();
+ return d->pageHistory.at(d->currentHistoryIndex)->location;
+}
+
+/*!
+ \property QPdfPageNavigator::currentZoom
+
+ This property holds the magnification scale (1 logical pixel = 1 point)
+ on the page that is being viewed. The default is \c 1.
+*/
+qreal QPdfPageNavigator::currentZoom() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return 1;
+ return d->pageHistory.at(d->currentHistoryIndex)->zoom;
+}
+
+QPdfLink QPdfPageNavigator::currentLink() const
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return QPdfLink();
+ return QPdfLink(d->pageHistory.at(d->currentHistoryIndex).data());
+}
+
+/*!
+ Clear the history and restore \l currentPage, \l currentLocation and
+ \l currentZoom to their default values.
+*/
+void QPdfPageNavigator::clear()
+{
+ d->pageHistory.clear();
+ d->currentHistoryIndex = 0;
+ // Begin with an implicit jump to page 0, so that
+ // backAvailable() will become true after jump() is called one more time.
+ d->pageHistory.append(QExplicitlySharedDataPointer<QPdfLinkPrivate>(new QPdfLinkPrivate(0, {}, 1)));
+}
+
+/*!
+ Adds the given \a destination to the history of visited locations.
+
+ In this case, PDF views respond to the \l jumped signal by scrolling to
+ place \c destination.rectangles in the viewport, as opposed to placing
+ \c destination.location in the viewport. So it's appropriate to call this
+ method to jump to a search result from QPdfSearchModel (because the
+ rectangles cover the region of text found). To jump to a hyperlink
+ destination, call jump(page, location, zoom) instead, because in that
+ case the QPdfLink object's \c rectangles cover the hyperlink origin
+ location rather than the destination.
+*/
+void QPdfPageNavigator::jump(QPdfLink destination)
+{
+ const bool zoomChange = !qFuzzyCompare(destination.zoom(), currentZoom());
+ const bool pageChange = (destination.page() != currentPage());
+ const bool locationChange = (destination.location() != currentLocation());
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ if (!d->changing) {
+ if (d->currentHistoryIndex >= 0 && forwardAvailableWas)
+ d->pageHistory.remove(d->currentHistoryIndex + 1, d->pageHistory.size() - d->currentHistoryIndex - 1);
+ d->pageHistory.append(destination.d);
+ d->currentHistoryIndex = d->pageHistory.size() - 1;
+ }
+ if (zoomChange)
+ emit currentZoomChanged(currentZoom());
+ if (pageChange)
+ emit currentPageChanged(currentPage());
+ if (locationChange)
+ emit currentLocationChanged(currentLocation());
+ if (d->changing)
+ return;
+ if (backAvailableWas != backAvailable())
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas != forwardAvailable())
+ emit forwardAvailableChanged(forwardAvailable());
+ emit jumped(currentLink());
+ qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << destination << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
+ Adds the given destination, consisting of \a page, \a location, and \a zoom,
+ to the history of visited locations.
+
+ The \a zoom argument represents magnification (where \c 1 is the default
+ scale, 1 logical pixel = 1 point). If \a zoom is not given or is \c 0,
+ currentZoom keeps its existing value, and currentZoomChanged is not emitted.
+
+ The \a location should be the same as QPdfLink::location() if the user is
+ following a link; and since that is specified as the upper-left corner of
+ the destination, it is best for consistency to always use the location
+ visible in the upper-left corner of the viewport, in points.
+
+ If forwardAvailable is \c true, calling this function represents a branch
+ in the timeline which causes the "future" to be lost, and therefore
+ forwardAvailable will change to \c false.
+*/
+void QPdfPageNavigator::jump(int page, const QPointF &location, qreal zoom)
+{
+ if (page == currentPage() && location == currentLocation() && zoom == currentZoom())
+ return;
+ if (qFuzzyIsNull(zoom))
+ zoom = currentZoom();
+ const bool zoomChange = !qFuzzyCompare(zoom, currentZoom());
+ const bool pageChange = (page != currentPage());
+ const bool locationChange = (location != currentLocation());
+ const bool backAvailableWas = backAvailable();
+ const bool forwardAvailableWas = forwardAvailable();
+ if (!d->changing) {
+ if (d->currentHistoryIndex >= 0 && forwardAvailableWas)
+ d->pageHistory.remove(d->currentHistoryIndex + 1, d->pageHistory.size() - d->currentHistoryIndex - 1);
+ d->pageHistory.append(QExplicitlySharedDataPointer<QPdfLinkPrivate>(new QPdfLinkPrivate(page, location, zoom)));
+ d->currentHistoryIndex = d->pageHistory.size() - 1;
+ }
+ if (zoomChange)
+ emit currentZoomChanged(currentZoom());
+ if (pageChange)
+ emit currentPageChanged(currentPage());
+ if (locationChange)
+ emit currentLocationChanged(currentLocation());
+ if (d->changing)
+ return;
+ if (backAvailableWas != backAvailable())
+ emit backAvailableChanged(backAvailable());
+ if (forwardAvailableWas != forwardAvailable())
+ emit forwardAvailableChanged(forwardAvailable());
+ emit jumped(currentLink());
+ qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << "page" << page
+ << "@" << location << "zoom" << zoom << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
+ Modifies the current destination, consisting of \a page, \a location and \a zoom.
+
+ This can be called periodically while the user is manually moving around
+ the document, so that after back() is called, forward() will jump back to
+ the most-recently-viewed destination rather than the destination that was
+ last specified by push().
+
+ The \c currentZoomChanged, \c currentPageChanged and \c currentLocationChanged
+ signals will be emitted if the respective properties are actually changed.
+ The \l jumped signal is not emitted, because this operation represents
+ smooth movement rather than a navigational jump.
+*/
+void QPdfPageNavigator::update(int page, const QPointF &location, qreal zoom)
+{
+ if (d->currentHistoryIndex < 0 || d->currentHistoryIndex >= d->pageHistory.size())
+ return;
+ int currentPageWas = currentPage();
+ QPointF currentLocationWas = currentLocation();
+ qreal currentZoomWas = currentZoom();
+ if (page == currentPageWas && location == currentLocationWas && zoom == currentZoomWas)
+ return;
+ d->pageHistory[d->currentHistoryIndex]->page = page;
+ d->pageHistory[d->currentHistoryIndex]->location = location;
+ d->pageHistory[d->currentHistoryIndex]->zoom = zoom;
+ if (currentZoomWas != zoom)
+ emit currentZoomChanged(currentZoom());
+ if (currentPageWas != page)
+ emit currentPageChanged(currentPage());
+ if (currentLocationWas != location)
+ emit currentLocationChanged(currentLocation());
+ qCDebug(qLcNav) << "update: index" << d->currentHistoryIndex << "page" << page
+ << "@" << location << "zoom" << zoom << "-> history" <<
+ [this]() {
+ QStringList ret;
+ for (auto d : d->pageHistory)
+ ret << QString::number(d->page);
+ return ret.join(QLatin1Char(','));
+ }();
+}
+
+/*!
+ \property QPdfPageNavigator::backAvailable
+ \readonly
+
+ Holds \c true if a \e back destination is available in the history:
+ that is, if push() or forward() has been called.
+*/
+bool QPdfPageNavigator::backAvailable() const
+{
+ return d->currentHistoryIndex > 0;
+}
+
+/*!
+ \property QPdfPageNavigator::forwardAvailable
+ \readonly
+
+ Holds \c true if a \e forward destination is available in the history:
+ that is, if back() has been previously called.
+*/
+bool QPdfPageNavigator::forwardAvailable() const
+{
+ return d->currentHistoryIndex < d->pageHistory.size() - 1;
+}
+
+/*!
+ \fn void QPdfPageNavigator::jumped(QPdfLink current)
+
+ This signal is emitted when an abrupt jump occurs, to the \a current
+ page index, location on the page, and zoom level; but \e not when simply
+ scrolling through the document one page at a time. That is, jump(),
+ forward() and back() emit this signal, but update() does not.
+
+ If \c {current.rectangles.length > 0}, they are rectangles that cover
+ a specific destination area: a search result that should be made
+ visible; otherwise, \c {current.location} is the destination location on
+ the \c page (a hyperlink destination, or during forward/back navigation).
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qpdfpagenavigator.cpp"
diff --git a/src/pdf/qpdfpagenavigator.h b/src/pdf/qpdfpagenavigator.h
new file mode 100644
index 000000000..cec89ef5a
--- /dev/null
+++ b/src/pdf/qpdfpagenavigator.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFPAGENAVIGATOR_H
+#define QPDFPAGENAVIGATOR_H
+
+#include <QtPdf/qtpdfglobal.h>
+#include <QtPdf/qpdflink.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QPdfPageNavigatorPrivate;
+
+class Q_PDF_EXPORT QPdfPageNavigator : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int currentPage READ currentPage NOTIFY currentPageChanged)
+ Q_PROPERTY(QPointF currentLocation READ currentLocation NOTIFY currentLocationChanged)
+ Q_PROPERTY(qreal currentZoom READ currentZoom NOTIFY currentZoomChanged)
+ Q_PROPERTY(bool backAvailable READ backAvailable NOTIFY backAvailableChanged)
+ Q_PROPERTY(bool forwardAvailable READ forwardAvailable NOTIFY forwardAvailableChanged)
+
+public:
+ QPdfPageNavigator() : QPdfPageNavigator(nullptr) {}
+ explicit QPdfPageNavigator(QObject *parent);
+ ~QPdfPageNavigator() override;
+
+ int currentPage() const;
+ QPointF currentLocation() const;
+ qreal currentZoom() const;
+
+ bool backAvailable() const;
+ bool forwardAvailable() const;
+
+public Q_SLOTS:
+ void clear();
+ void jump(QPdfLink destination);
+ void jump(int page, const QPointF &location, qreal zoom = 0);
+ void update(int page, const QPointF &location, qreal zoom);
+ void forward();
+ void back();
+
+Q_SIGNALS:
+ void currentPageChanged(int page);
+ void currentLocationChanged(QPointF location);
+ void currentZoomChanged(qreal zoom);
+ void backAvailableChanged(bool available);
+ void forwardAvailableChanged(bool available);
+ void jumped(QPdfLink current);
+
+protected:
+ QPdfLink currentLink() const;
+
+private:
+ QScopedPointer<QPdfPageNavigatorPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFPAGENAVIGATOR_H
diff --git a/src/pdf/qpdfpagerenderer.cpp b/src/pdf/qpdfpagerenderer.cpp
index 8be0cfa21..771fc67ef 100644
--- a/src/pdf/qpdfpagerenderer.cpp
+++ b/src/pdf/qpdfpagerenderer.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfpagerenderer.h"
@@ -122,7 +89,7 @@ void RenderWorker::requestPage(quint64 requestId, int pageNumber, QSize imageSiz
{
const QMutexLocker locker(&m_mutex);
- if (!m_document || m_document->status() != QPdfDocument::Ready)
+ if (!m_document || m_document->status() != QPdfDocument::Status::Ready)
return;
const QImage image = m_document->render(pageNumber, imageSize, options);
@@ -312,10 +279,10 @@ void QPdfPageRenderer::setDocument(QPdfDocument *document)
quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
QPdfDocumentRenderOptions options)
{
- if (!d_ptr->m_document || d_ptr->m_document->status() != QPdfDocument::Ready)
+ if (!d_ptr->m_document || d_ptr->m_document->status() != QPdfDocument::Status::Ready)
return 0;
- for (const auto &request : qAsConst(d_ptr->m_pendingRequests)) {
+ for (const auto &request : std::as_const(d_ptr->m_pendingRequests)) {
if (request.pageNumber == pageNumber
&& request.imageSize == imageSize
&& request.options == options)
@@ -340,3 +307,4 @@ quint64 QPdfPageRenderer::requestPage(int pageNumber, QSize imageSize,
QT_END_NAMESPACE
#include "qpdfpagerenderer.moc"
+#include "moc_qpdfpagerenderer.cpp"
diff --git a/src/pdf/qpdfpagerenderer.h b/src/pdf/qpdfpagerenderer.h
index faeaef8af..cb9be06fe 100644
--- a/src/pdf/qpdfpagerenderer.h
+++ b/src/pdf/qpdfpagerenderer.h
@@ -1,39 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFPAGERENDERER_H
#define QPDFPAGERENDERER_H
@@ -64,7 +31,8 @@ public:
};
Q_ENUM(RenderMode)
- explicit QPdfPageRenderer(QObject *parent = nullptr);
+ QPdfPageRenderer() : QPdfPageRenderer(nullptr) {}
+ explicit QPdfPageRenderer(QObject *parent);
~QPdfPageRenderer() override;
RenderMode renderMode() const;
@@ -78,7 +46,7 @@ public:
Q_SIGNALS:
void documentChanged(QPdfDocument *document);
- void renderModeChanged(RenderMode renderMode);
+ void renderModeChanged(QPdfPageRenderer::RenderMode renderMode);
void pageRendered(int pageNumber, QSize imageSize, const QImage &image,
QPdfDocumentRenderOptions options, quint64 requestId);
diff --git a/src/pdf/qpdfsearchmodel.cpp b/src/pdf/qpdfsearchmodel.cpp
index 4d4e86cee..a81ae77dc 100644
--- a/src/pdf/qpdfsearchmodel.cpp
+++ b/src/pdf/qpdfsearchmodel.cpp
@@ -1,47 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "qpdfdestination.h"
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#include "qpdfdocument_p.h"
+#include "qpdflink.h"
#include "qpdfsearchmodel.h"
#include "qpdfsearchmodel_p.h"
-#include "qpdfsearchresult_p.h"
-#include "third_party/pdfium/public/fpdf_doc.h"
#include "third_party/pdfium/public/fpdf_text.h"
+#include "third_party/pdfium/public/fpdfview.h"
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qloggingcategory.h>
@@ -53,28 +19,75 @@ Q_LOGGING_CATEGORY(qLcS, "qt.pdf.search")
static const int UpdateTimerInterval = 100;
static const int ContextChars = 64;
-static const double CharacterHitTolerance = 6.0;
+/*!
+ \class QPdfSearchModel
+ \since 5.15
+ \inmodule QtPdf
+ \inherits QAbstractListModel
+
+ \brief The QPdfSearchModel class searches for a string in a PDF document
+ and holds the results.
+
+ This is used in the \l {Model/View Programming} paradigm to display
+ a list of search results, to highlight them on the rendered PDF pages,
+ and to iterate through them using the "search forward" / "search backward"
+ buttons and shortcuts that would be found in a typical document-viewing UI:
+
+ \image search-results.png
+*/
+
+/*!
+ \enum QPdfSearchModel::Role
+
+ \value Page The page number where the search result is found (int).
+ \value IndexOnPage The index of the search result on the page (int).
+ \value Location The position of the search result on the page (QPointF).
+ \value ContextBefore The adjacent text on the page, before the search string (QString).
+ \value ContextAfter The adjacent text on the page, after the search string (QString).
+ \omitvalue NRoles
+
+ \sa QPdfLink
+*/
+
+/*!
+ Constructs a new search model with parent object \a parent.
+*/
QPdfSearchModel::QPdfSearchModel(QObject *parent)
: QAbstractListModel(*(new QPdfSearchModelPrivate()), parent)
{
QMetaEnum rolesMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("Role"));
- for (int r = Qt::UserRole; r < int(Role::_Count); ++r) {
+ for (int r = Qt::UserRole; r < int(Role::NRoles); ++r) {
QByteArray roleName = QByteArray(rolesMetaEnum.valueToKey(r));
if (roleName.isEmpty())
continue;
roleName[0] = QChar::toLower(roleName[0]);
m_roleNames.insert(r, roleName);
}
+ connect(this, &QAbstractListModel::dataChanged, this, &QPdfSearchModel::countChanged);
+ connect(this, &QAbstractListModel::modelReset, this, &QPdfSearchModel::countChanged);
+ connect(this, &QAbstractListModel::rowsRemoved, this, &QPdfSearchModel::countChanged);
+ connect(this, &QAbstractListModel::rowsInserted, this, &QPdfSearchModel::countChanged);
}
+/*!
+ Destroys the model.
+*/
QPdfSearchModel::~QPdfSearchModel() {}
+/*!
+ \reimp
+*/
QHash<int, QByteArray> QPdfSearchModel::roleNames() const
{
return m_roleNames;
}
+/*!
+ \reimp
+
+ The number of rows in the model is equal to the number of search results found.
+*/
int QPdfSearchModel::rowCount(const QModelIndex &parent) const
{
Q_D(const QPdfSearchModel);
@@ -82,6 +95,9 @@ int QPdfSearchModel::rowCount(const QModelIndex &parent) const
return d->rowCountSoFar;
}
+/*!
+ \reimp
+*/
QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
{
Q_D(const QPdfSearchModel);
@@ -99,7 +115,7 @@ QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
return d->searchResults[pi.page][pi.index].contextBefore();
case Role::ContextAfter:
return d->searchResults[pi.page][pi.index].contextAfter();
- case Role::_Count:
+ case Role::NRoles:
break;
}
if (role == Qt::DisplayRole) {
@@ -111,19 +127,33 @@ QVariant QPdfSearchModel::data(const QModelIndex &index, int role) const
return QVariant();
}
+/*!
+ \since 6.8
+ \property QPdfSearchModel::count
+ \brief the number of search results found
+*/
+int QPdfSearchModel::count() const
+{
+ return rowCount(QModelIndex());
+}
+
void QPdfSearchModel::updatePage(int page)
{
Q_D(QPdfSearchModel);
d->doSearch(page);
}
+/*!
+ \property QPdfSearchModel::searchString
+ \brief the string to search for
+*/
QString QPdfSearchModel::searchString() const
{
Q_D(const QPdfSearchModel);
return d->searchString;
}
-void QPdfSearchModel::setSearchString(QString searchString)
+void QPdfSearchModel::setSearchString(const QString &searchString)
{
Q_D(QPdfSearchModel);
if (d->searchString == searchString)
@@ -136,24 +166,35 @@ void QPdfSearchModel::setSearchString(QString searchString)
endResetModel();
}
-QList<QPdfSearchResult> QPdfSearchModel::resultsOnPage(int page) const
+/*!
+ Returns the list of all results found on the given \a page.
+*/
+QList<QPdfLink> QPdfSearchModel::resultsOnPage(int page) const
{
Q_D(const QPdfSearchModel);
const_cast<QPdfSearchModelPrivate *>(d)->doSearch(page);
- if (d->searchResults.count() <= page)
+ if (d->searchResults.size() <= page)
return {};
return d->searchResults[page];
}
-QPdfSearchResult QPdfSearchModel::resultAtIndex(int index) const
+/*!
+ Returns a result found by \a index in the \l document, regardless of the
+ page on which it was found. \a index must be less than \l rowCount.
+*/
+QPdfLink QPdfSearchModel::resultAtIndex(int index) const
{
Q_D(const QPdfSearchModel);
const auto pi = const_cast<QPdfSearchModelPrivate*>(d)->pageAndIndexForResult(index);
- if (pi.page < 0)
- return QPdfSearchResult();
+ if (pi.page < 0 || index < 0)
+ return {};
return d->searchResults[pi.page][pi.index];
}
+/*!
+ \property QPdfSearchModel::document
+ \brief the document to search
+*/
QPdfDocument *QPdfSearchModel::document() const
{
Q_D(const QPdfSearchModel);
@@ -166,6 +207,10 @@ void QPdfSearchModel::setDocument(QPdfDocument *document)
if (d->document == document)
return;
+ disconnect(d->documentConnection);
+ d->documentConnection = connect(document, &QPdfDocument::pageCountChanged, this,
+ [this]() { d_func()->clearResults(); });
+
d->document = document;
d->clearResults();
emit documentChanged();
@@ -178,7 +223,7 @@ void QPdfSearchModel::timerEvent(QTimerEvent *event)
return;
if (!d->document || d->nextPageToUpdate >= d->document->pageCount()) {
if (d->document)
- qCDebug(qLcS) << "done updating search results on" << d->searchResults.count() << "pages";
+ qCDebug(qLcS) << "done updating search results on" << d->searchResults.size() << "pages";
killTimer(d->updateTimerId);
d->updateTimerId = -1;
}
@@ -205,7 +250,7 @@ void QPdfSearchModelPrivate::clearResults()
bool QPdfSearchModelPrivate::doSearch(int page)
{
- if (page < 0 || page >= pagesSearched.count() || searchString.isEmpty())
+ if (page < 0 || page >= pagesSearched.size() || searchString.isEmpty())
return false;
if (pagesSearched[page])
return true;
@@ -219,7 +264,6 @@ bool QPdfSearchModelPrivate::doSearch(int page)
qWarning() << "failed to load page" << page;
return false;
}
- double pageHeight = FPDF_GetPageHeight(pdfPage);
FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
if (!textPage) {
qWarning() << "failed to load text of page" << page;
@@ -227,7 +271,8 @@ bool QPdfSearchModelPrivate::doSearch(int page)
return false;
}
FPDF_SCHHANDLE sh = FPDFText_FindStart(textPage, searchString.utf16(), 0, 0);
- QList<QPdfSearchResult> newSearchResults;
+ QList<QPdfLink> newSearchResults;
+ constexpr double CharacterHitTolerance = 6.0;
while (FPDFText_FindNext(sh)) {
int idx = FPDFText_GetSchResultIndex(sh);
int count = FPDFText_GetSchCount(sh);
@@ -236,9 +281,12 @@ bool QPdfSearchModelPrivate::doSearch(int page)
int startIndex = -1;
int endIndex = -1;
for (int r = 0; r < rectCount; ++r) {
+ // get bounding box of search result in page coordinates
double left, top, right, bottom;
FPDFText_GetRect(textPage, r, &left, &top, &right, &bottom);
- rects << QRectF(left, pageHeight - top, right - left, top - bottom);
+ // deal with any internal PDF transforms and
+ // convert to the 1x (pixels = points) 4th-quadrant coordinate system
+ rects << document->d->mapPageToView(pdfPage, left, top, right, bottom);
if (r == 0) {
startIndex = FPDFText_GetCharIndexAtPos(textPage, left, top,
CharacterHitTolerance, CharacterHitTolerance);
@@ -247,7 +295,8 @@ bool QPdfSearchModelPrivate::doSearch(int page)
endIndex = FPDFText_GetCharIndexAtPos(textPage, right, top,
CharacterHitTolerance, CharacterHitTolerance);
}
- qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex;
+ qCDebug(qLcS) << rects.last() << "char idx" << startIndex << "->" << endIndex
+ << "from page rect" << left << top << right << bottom;
}
QString contextBefore, contextAfter;
if (startIndex >= 0 || endIndex >= 0) {
@@ -269,25 +318,25 @@ bool QPdfSearchModelPrivate::doSearch(int page)
if (si < 0)
qWarning() << "search string" << searchString << "not found in context" << context;
contextBefore = context.mid(0, si);
- contextAfter = context.mid(si + searchString.length());
+ contextAfter = context.mid(si + searchString.size());
}
}
if (!rects.isEmpty())
- newSearchResults << QPdfSearchResult(page, rects, contextBefore, contextAfter);
+ newSearchResults << QPdfLink(page, rects, contextBefore, contextAfter);
}
FPDFText_FindClose(sh);
FPDFText_ClosePage(textPage);
FPDF_ClosePage(pdfPage);
qCDebug(qLcS) << searchString << "took" << timer.elapsed() << "ms to find"
- << newSearchResults.count() << "results on page" << page;
+ << newSearchResults.size() << "results on page" << page;
pagesSearched[page] = true;
searchResults[page] = newSearchResults;
- if (newSearchResults.count() > 0) {
+ if (newSearchResults.size() > 0) {
int rowsBefore = rowsBeforePage(page);
- qCDebug(qLcS) << "from row" << rowsBefore << "rowCount" << rowCountSoFar << "increasing by" << newSearchResults.count();
- rowCountSoFar += newSearchResults.count();
- q->beginInsertRows(QModelIndex(), rowsBefore, rowsBefore + newSearchResults.count() - 1);
+ qCDebug(qLcS) << "from row" << rowsBefore << "rowCount" << rowCountSoFar << "increasing by" << newSearchResults.size();
+ rowCountSoFar += newSearchResults.size();
+ q->beginInsertRows(QModelIndex(), rowsBefore, rowsBefore + newSearchResults.size() - 1);
q->endInsertRows();
}
return true;
@@ -295,13 +344,15 @@ bool QPdfSearchModelPrivate::doSearch(int page)
QPdfSearchModelPrivate::PageAndIndex QPdfSearchModelPrivate::pageAndIndexForResult(int resultIndex)
{
+ if (pagesSearched.isEmpty())
+ return {-1, -1};
const int pageCount = document->pageCount();
int totalSoFar = 0;
int previousTotalSoFar = 0;
for (int page = 0; page < pageCount; ++page) {
if (!pagesSearched[page])
doSearch(page);
- totalSoFar += searchResults[page].count();
+ totalSoFar += searchResults[page].size();
if (totalSoFar > resultIndex)
return {page, resultIndex - previousTotalSoFar};
previousTotalSoFar = totalSoFar;
@@ -313,7 +364,7 @@ int QPdfSearchModelPrivate::rowsBeforePage(int page)
{
int ret = 0;
for (int i = 0; i < page; ++i)
- ret += searchResults[i].count();
+ ret += searchResults[i].size();
return ret;
}
diff --git a/src/pdf/qpdfsearchmodel.h b/src/pdf/qpdfsearchmodel.h
index 1a413c763..04f8b9140 100644
--- a/src/pdf/qpdfsearchmodel.h
+++ b/src/pdf/qpdfsearchmodel.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFSEARCHMODEL_H
#define QPDFSEARCHMODEL_H
@@ -41,7 +8,7 @@
#include <QtCore/qabstractitemmodel.h>
#include <QtPdf/qpdfdocument.h>
-#include <QtPdf/qpdfsearchresult.h>
+#include <QtPdf/qpdflink.h>
QT_BEGIN_NAMESPACE
@@ -52,6 +19,7 @@ class Q_PDF_EXPORT QPdfSearchModel : public QAbstractListModel
Q_OBJECT
Q_PROPERTY(QPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
+ Q_PROPERTY(int count READ count NOTIFY countChanged REVISION(6, 8) FINAL)
public:
enum class Role : int {
@@ -60,14 +28,15 @@ public:
Location,
ContextBefore,
ContextAfter,
- _Count
+ NRoles
};
Q_ENUM(Role)
- explicit QPdfSearchModel(QObject *parent = nullptr);
- ~QPdfSearchModel();
+ QPdfSearchModel() : QPdfSearchModel(nullptr) {}
+ explicit QPdfSearchModel(QObject *parent);
+ ~QPdfSearchModel() override;
- QList<QPdfSearchResult> resultsOnPage(int page) const;
- QPdfSearchResult resultAtIndex(int index) const;
+ QList<QPdfLink> resultsOnPage(int page) const;
+ QPdfLink resultAtIndex(int index) const;
QPdfDocument *document() const;
QString searchString() const;
@@ -76,13 +45,16 @@ public:
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
+ int count() const;
+
public Q_SLOTS:
- void setSearchString(QString searchString);
+ void setSearchString(const QString &searchString);
void setDocument(QPdfDocument *document);
Q_SIGNALS:
void documentChanged();
void searchStringChanged();
+ Q_REVISION(6, 8) void countChanged();
protected:
void updatePage(int page);
diff --git a/src/pdf/qpdfsearchmodel_p.h b/src/pdf/qpdfsearchmodel_p.h
index 551eff47c..5ffa08f5d 100644
--- a/src/pdf/qpdfsearchmodel_p.h
+++ b/src/pdf/qpdfsearchmodel_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFSEARCHMODEL_P_H
#define QPDFSEARCHMODEL_P_H
@@ -49,7 +16,6 @@
//
#include "qpdfsearchmodel.h"
-#include "qpdfsearchresult_p.h"
#include <private/qabstractitemmodel_p.h>
#include "third_party/pdfium/public/fpdfview.h"
@@ -75,10 +41,12 @@ public:
QPdfDocument *document = nullptr;
QString searchString;
QList<bool> pagesSearched;
- QList<QList<QPdfSearchResult>> searchResults;
+ QList<QList<QPdfLink>> searchResults;
int rowCountSoFar = 0;
int updateTimerId = -1;
int nextPageToUpdate = 0;
+
+ QMetaObject::Connection documentConnection;
};
QT_END_NAMESPACE
diff --git a/src/pdf/qpdfsearchresult.cpp b/src/pdf/qpdfsearchresult.cpp
deleted file mode 100644
index 629a8765f..000000000
--- a/src/pdf/qpdfsearchresult.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "qpdfsearchresult.h"
-#include "qpdfsearchresult_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QPdfSearchResult::QPdfSearchResult() :
- QPdfSearchResult(new QPdfSearchResultPrivate()) { }
-
-QPdfSearchResult::QPdfSearchResult(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter) :
- QPdfSearchResult(new QPdfSearchResultPrivate(page, rects, contextBefore, contextAfter)) { }
-
-QPdfSearchResult::QPdfSearchResult(QPdfSearchResultPrivate *d) :
- QPdfDestination(static_cast<QPdfDestinationPrivate *>(d)) { }
-
-QString QPdfSearchResult::contextBefore() const
-{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->contextBefore;
-}
-
-QString QPdfSearchResult::contextAfter() const
-{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->contextAfter;
-}
-
-QList<QRectF> QPdfSearchResult::rectangles() const
-{
- return static_cast<QPdfSearchResultPrivate *>(d.data())->rects;
-}
-
-QDebug operator<<(QDebug dbg, const QPdfSearchResult &searchResult)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace();
- dbg << "QPdfSearchResult(page=" << searchResult.page()
- << " contextBefore=" << searchResult.contextBefore()
- << " contextAfter=" << searchResult.contextAfter()
- << " rects=" << searchResult.rectangles();
- dbg << ')';
- return dbg;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpdfsearchresult.cpp"
diff --git a/src/pdf/qpdfsearchresult.h b/src/pdf/qpdfsearchresult.h
deleted file mode 100644
index 0acf03d52..000000000
--- a/src/pdf/qpdfsearchresult.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFSEARCHRESULT_H
-#define QPDFSEARCHRESULT_H
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qrect.h>
-#include <QtPdf/qpdfdestination.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSearchResultPrivate;
-
-class Q_PDF_EXPORT QPdfSearchResult : public QPdfDestination
-{
- Q_GADGET
- Q_PROPERTY(QString contextBefore READ contextBefore)
- Q_PROPERTY(QString contextAfter READ contextAfter)
- Q_PROPERTY(QList<QRectF> rectangles READ rectangles)
-
-public:
- QPdfSearchResult();
- ~QPdfSearchResult() {}
-
- QString contextBefore() const;
- QString contextAfter() const;
- QList<QRectF> rectangles() const;
-
-private:
- QPdfSearchResult(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter);
- QPdfSearchResult(QPdfSearchResultPrivate *d);
- friend class QPdfDocument;
- friend class QPdfSearchModelPrivate;
- friend class QQuickPdfNavigationStack;
-};
-
-Q_PDF_EXPORT QDebug operator<<(QDebug, const QPdfSearchResult &);
-
-QT_END_NAMESPACE
-
-#endif // QPDFSEARCHRESULT_H
diff --git a/src/pdf/qpdfsearchresult_p.h b/src/pdf/qpdfsearchresult_p.h
deleted file mode 100644
index eca37890e..000000000
--- a/src/pdf/qpdfsearchresult_p.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QPDFSEARCHRESULT_P_H
-#define QPDFSEARCHRESULT_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 "qpdfdestination_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPdfSearchResultPrivate : public QPdfDestinationPrivate
-{
-public:
- QPdfSearchResultPrivate() = default;
- QPdfSearchResultPrivate(int page, QList<QRectF> rects, QString contextBefore, QString contextAfter) :
- QPdfDestinationPrivate(page, rects.first().topLeft(), 0),
- contextBefore(contextBefore),
- contextAfter(contextAfter),
- rects(rects) {}
-
- QString contextBefore;
- QString contextAfter;
- QList<QRectF> rects;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPDFSEARCHRESULT_P_H
diff --git a/src/pdf/qpdfselection.cpp b/src/pdf/qpdfselection.cpp
index 2b263f444..df30eb353 100644
--- a/src/pdf/qpdfselection.cpp
+++ b/src/pdf/qpdfselection.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfselection.h"
#include "qpdfselection_p.h"
@@ -77,25 +44,10 @@ QPdfSelection::QPdfSelection(QPdfSelectionPrivate *d)
{
}
-QPdfSelection::QPdfSelection(const QPdfSelection &other)
- : d(other.d)
-{
-}
-
-QPdfSelection::QPdfSelection(QPdfSelection &&other) noexcept
- : d(std::move(other.d))
-{
-}
-
-QPdfSelection::~QPdfSelection()
-{
-}
-
-QPdfSelection &QPdfSelection::operator=(const QPdfSelection &other)
-{
- d = other.d;
- return *this;
-}
+QPdfSelection::~QPdfSelection() = default;
+QPdfSelection::QPdfSelection(const QPdfSelection &other) = default;
+QPdfSelection::QPdfSelection(QPdfSelection &&other) noexcept = default;
+QPdfSelection &QPdfSelection::operator=(const QPdfSelection &other) = default;
/*!
\property QPdfSelection::valid
diff --git a/src/pdf/qpdfselection.h b/src/pdf/qpdfselection.h
index 70077fdb0..8fcfaf2d8 100644
--- a/src/pdf/qpdfselection.h
+++ b/src/pdf/qpdfselection.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFSELECTION_H
#define QPDFSELECTION_H
@@ -48,9 +15,9 @@ QT_BEGIN_NAMESPACE
class QPdfSelectionPrivate;
-class Q_PDF_EXPORT QPdfSelection
+class QPdfSelection
{
- Q_GADGET
+ Q_GADGET_EXPORT(Q_PDF_EXPORT)
Q_PROPERTY(bool valid READ isValid)
Q_PROPERTY(QList<QPolygonF> bounds READ bounds)
Q_PROPERTY(QRectF boundingRectangle READ boundingRectangle)
@@ -59,20 +26,23 @@ class Q_PDF_EXPORT QPdfSelection
Q_PROPERTY(int endIndex READ endIndex)
public:
- ~QPdfSelection();
- QPdfSelection(const QPdfSelection &other);
- QPdfSelection &operator=(const QPdfSelection &other);
- QPdfSelection(QPdfSelection &&other) noexcept;
- QPdfSelection &operator=(QPdfSelection &&other) noexcept { swap(other); return *this; }
+ Q_PDF_EXPORT ~QPdfSelection();
+ Q_PDF_EXPORT QPdfSelection(const QPdfSelection &other);
+ Q_PDF_EXPORT QPdfSelection &operator=(const QPdfSelection &other);
+
+ Q_PDF_EXPORT QPdfSelection(QPdfSelection &&other) noexcept;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QPdfSelection)
+
void swap(QPdfSelection &other) noexcept { d.swap(other.d); }
- bool isValid() const;
- QList<QPolygonF> bounds() const;
- QString text() const;
- QRectF boundingRectangle() const;
- int startIndex() const;
- int endIndex() const;
+
+ Q_PDF_EXPORT bool isValid() const;
+ Q_PDF_EXPORT QList<QPolygonF> bounds() const;
+ Q_PDF_EXPORT QString text() const;
+ Q_PDF_EXPORT QRectF boundingRectangle() const;
+ Q_PDF_EXPORT int startIndex() const;
+ Q_PDF_EXPORT int endIndex() const;
#if QT_CONFIG(clipboard)
- void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
+ Q_PDF_EXPORT void copyToClipboard(QClipboard::Mode mode = QClipboard::Clipboard) const;
#endif
private:
@@ -85,6 +55,7 @@ private:
private:
QExplicitlySharedDataPointer<QPdfSelectionPrivate> d;
};
+Q_DECLARE_SHARED(QPdfSelection)
QT_END_NAMESPACE
diff --git a/src/pdf/qpdfselection_p.h b/src/pdf/qpdfselection_p.h
index 0c176b324..541480746 100644
--- a/src/pdf/qpdfselection_p.h
+++ b/src/pdf/qpdfselection_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFSELECTION_P_H
#define QPDFSELECTION_P_H
@@ -48,6 +15,8 @@
// We mean it.
//
+#include "qpdfselection.h"
+
#include <QList>
#include <QPolygonF>
diff --git a/src/pdf/qtpdfglobal.h b/src/pdf/qtpdfglobal.h
index 8b4b0c206..2d0900029 100644
--- a/src/pdf/qtpdfglobal.h
+++ b/src/pdf/qtpdfglobal.h
@@ -1,61 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTPDFGLOBAL_H
#define QTPDFGLOBAL_H
#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef Q_PDF_EXPORT
-# ifndef QT_STATIC
-# if defined(QT_BUILD_PDF_LIB)
-# define Q_PDF_EXPORT Q_DECL_EXPORT
-# else
-# define Q_PDF_EXPORT Q_DECL_IMPORT
-# endif
-# else
-# define Q_PDF_EXPORT
-# endif
-#endif
-
-#define Q_PDF_PRIVATE_EXPORT Q_PDF_EXPORT
-
-QT_END_NAMESPACE
+#include <QtPdf/qtpdfexports.h>
#endif // QTPDFGLOBAL_H
diff --git a/src/pdfquick/+Material/PdfStyle.qml b/src/pdfquick/+Material/PdfStyle.qml
new file mode 100644
index 000000000..0728616a2
--- /dev/null
+++ b/src/pdfquick/+Material/PdfStyle.qml
@@ -0,0 +1,15 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+import QtQuick
+import QtQuick.Controls.Material
+
+QtObject {
+ property SystemPalette palette: SystemPalette { }
+ function withAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+ }
+ property color selectionColor: withAlpha(palette.highlight, 0.5)
+ property color pageSearchResultsColor: withAlpha(Qt.lighter(Material.accentColor, 1.5), 0.5)
+ property color currentSearchResultStrokeColor: Material.accentColor
+ property real currentSearchResultStrokeWidth: 2
+}
diff --git a/src/pdfquick/+Universal/PdfStyle.qml b/src/pdfquick/+Universal/PdfStyle.qml
new file mode 100644
index 000000000..4c559f068
--- /dev/null
+++ b/src/pdfquick/+Universal/PdfStyle.qml
@@ -0,0 +1,15 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+import QtQuick
+import QtQuick.Controls.Universal
+
+QtObject {
+ property SystemPalette palette: SystemPalette { }
+ function withAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+ }
+ property color selectionColor: withAlpha(palette.highlight, 0.5)
+ property color pageSearchResultsColor: withAlpha(Qt.lighter(Universal.accent, 1.5), 0.5)
+ property color currentSearchResultStrokeColor: Universal.accent
+ property real currentSearchResultStrokeWidth: 2
+}
diff --git a/src/pdfquick/CMakeLists.txt b/src/pdfquick/CMakeLists.txt
index 5bbe66959..d57ce04aa 100644
--- a/src/pdfquick/CMakeLists.txt
+++ b/src/pdfquick/CMakeLists.txt
@@ -1,32 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Qml Quick)
set(qml_files
-# TODO:
-# "qml/+material/PdfStyle.qml"
-# "qml/+universal/PdfStyle.qml"
- "qml/PdfMultiPageView.qml"
- "qml/PdfPageView.qml"
- "qml/PdfScrollablePageView.qml"
- "qml/PdfStyle.qml"
+ "+Material/PdfStyle.qml"
+ "+Universal/PdfStyle.qml"
+ "PdfLinkDelegate.qml"
+ "PdfMultiPageView.qml"
+ "PdfPageView.qml"
+ "PdfScrollablePageView.qml"
+ "PdfStyle.qml"
)
qt_internal_add_qml_module(PdfQuick
URI "QtQuick.Pdf"
VERSION "${PROJECT_VERSION}"
- CLASS_NAME QtQuick2PdfPlugin
- NO_GENERATE_PLUGIN_SOURCE
- NO_PLUGIN_OPTIONAL
- NO_GENERATE_QMLTYPES
- PLUGIN_TARGET qtpdfquickplugin
+ PAST_MAJOR_VERSIONS 5
QML_FILES ${qml_files}
- DEPENDENCIES QtQuickControls2
+ DEPENDENCIES QtQuick/auto
SOURCES
+ qquickpdfbookmarkmodel.cpp qquickpdfbookmarkmodel_p.h
qquickpdfdocument.cpp qquickpdfdocument_p.h
qquickpdflinkmodel.cpp qquickpdflinkmodel_p.h
- qquickpdfnavigationstack.cpp qquickpdfnavigationstack_p.h
+ qquickpdfpagenavigator.cpp qquickpdfpagenavigator_p.h
+ qquickpdfpageimage.cpp qquickpdfpageimage_p.h
qquickpdfsearchmodel.cpp qquickpdfsearchmodel_p.h
qquickpdfselection.cpp qquickpdfselection_p.h
- qquicktableviewextra.cpp qquicktableviewextra_p.h
qtpdfquickglobal_p.h
INCLUDE_DIRECTORIES
../3rdparty/chromium
@@ -36,15 +36,6 @@ qt_internal_add_qml_module(PdfQuick
Qt::Core
Qt::Gui
Qt::Qml
+ NO_GENERATE_CPP_EXPORTS
)
-qt_internal_extend_target(qtpdfquickplugin
- SOURCES
- plugin.cpp
- LIBRARIES
- Qt::CorePrivate
- Qt::PdfQuickPrivate
-)
-
-
-
diff --git a/src/pdfquick/PdfLinkDelegate.qml b/src/pdfquick/PdfLinkDelegate.qml
new file mode 100644
index 000000000..4ac54d161
--- /dev/null
+++ b/src/pdfquick/PdfLinkDelegate.qml
@@ -0,0 +1,74 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+import QtQuick
+import QtQuick.Controls
+
+/*!
+ \qmltype PdfLinkDelegate
+ \inqmlmodule QtQuick.Pdf
+ \brief A component to decorate hyperlinks on a PDF page.
+
+ PdfLinkDelegate provides the component that QML-based PDF viewers
+ instantiate on top of each hyperlink that is found on each PDF page.
+
+ This component does not provide any visual decoration, because often the
+ hyperlinks will already be formatted in a distinctive way; but when the
+ mouse cursor hovers, it changes to Qt::PointingHandCursor, and a tooltip
+ appears after a delay. Clicking emits the goToLocation() signal if the link
+ is internal, or calls Qt.openUrlExternally() if the link contains a URL.
+
+ \sa PdfPageView, PdfScrollablePageView, PdfMultiPageView
+*/
+Item {
+ id: root
+ required property var link
+ required property rect rectangle
+ required property url url
+ required property int page
+ required property point location
+ required property real zoom
+
+ /*!
+ \qmlsignal PdfLinkDelegate::tapped(link)
+
+ Emitted on mouse click or touch tap. The \a link argument is an
+ instance of QPdfLink with information about the hyperlink.
+ */
+ signal tapped(var link)
+
+ /*!
+ \qmlsignal PdfLinkDelegate::contextMenuRequested(link)
+
+ Emitted on mouse right-click or touch long-press. The \a link argument
+ is an instance of QPdfLink with information about the hyperlink.
+ */
+ signal contextMenuRequested(var link)
+
+ HoverHandler {
+ id: linkHH
+ cursorShape: Qt.PointingHandCursor
+ }
+ TapHandler {
+ gesturePolicy: TapHandler.ReleaseWithinBounds
+ onTapped: root.tapped(root.link)
+ }
+ TapHandler {
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
+ acceptedButtons: Qt.RightButton
+ gesturePolicy: TapHandler.ReleaseWithinBounds
+ onTapped: root.contextMenuRequested(root.link)
+ }
+ TapHandler {
+ acceptedDevices: PointerDevice.TouchScreen
+ onLongPressed: root.contextMenuRequested(root.link)
+ }
+ ToolTip {
+ visible: linkHH.hovered
+ delay: 1000
+ property string destFormat: qsTr("Page %1 location %2, %3 zoom %4")
+ text: root.page >= 0 ?
+ destFormat.arg(root.page + 1).arg(root.location.x.toFixed(1))
+ .arg(root.location.y.toFixed(1)).arg(root.zoom) :
+ root.url
+ }
+}
diff --git a/src/pdfquick/PdfMultiPageView.qml b/src/pdfquick/PdfMultiPageView.qml
new file mode 100644
index 000000000..194d7866e
--- /dev/null
+++ b/src/pdfquick/PdfMultiPageView.qml
@@ -0,0 +1,623 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Pdf
+import QtQuick.Shapes
+
+/*!
+ \qmltype PdfMultiPageView
+ \inqmlmodule QtQuick.Pdf
+ \brief A complete PDF viewer component for scrolling through multiple pages.
+
+ PdfMultiPageView provides a PDF viewer component that offers a user
+ experience similar to many common PDF viewer applications. It supports
+ flicking through the pages in the entire document, with narrow gaps between
+ the page images.
+
+ PdfMultiPageView also supports selecting text and copying it to the
+ clipboard, zooming in and out, clicking an internal link to jump to another
+ section in the document, rotating the view, and searching for text. The
+ \l {PDF Multipage Viewer Example} demonstrates how to use these features
+ in an application.
+
+ The implementation is a QML assembly of smaller building blocks that are
+ available separately. In case you want to make changes in your own version
+ of this component, you can copy the QML, which is installed into the
+ \c QtQuick/Pdf/qml module directory, and modify it as needed.
+
+ \sa PdfPageView, PdfScrollablePageView, PdfStyle
+*/
+Item {
+ /*!
+ \qmlproperty PdfDocument PdfMultiPageView::document
+
+ A PdfDocument object with a valid \c source URL is required:
+
+ \snippet multipageview.qml 0
+ */
+ required property PdfDocument document
+
+ /*!
+ \qmlproperty PdfDocument PdfMultiPageView::selectedText
+
+ The selected text.
+ */
+ property string selectedText
+
+ /*!
+ \qmlmethod void PdfMultiPageView::selectAll()
+
+ Selects all the text on the \l {currentPage}{current page}, and makes it
+ available as the system \l {QClipboard::Selection}{selection} on systems
+ that support that feature.
+
+ \sa copySelectionToClipboard()
+ */
+ function selectAll() {
+ const currentItem = tableView.itemAtCell(tableView.cellAtPos(root.width / 2, root.height / 2))
+ const pdfSelection = currentItem?.selection as PdfSelection
+ pdfSelection?.selectAll()
+ }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::copySelectionToClipboard()
+
+ Copies the selected text (if any) to the
+ \l {QClipboard::Clipboard}{system clipboard}.
+
+ \sa selectAll()
+ */
+ function copySelectionToClipboard() {
+ const currentItem = tableView.itemAtCell(tableView.cellAtPos(root.width / 2, root.height / 2))
+ const pdfSelection = currentItem?.selection as PdfSelection
+ console.log(lcMPV, "currentItem", currentItem, "sel", pdfSelection?.text)
+ pdfSelection?.copyToClipboard()
+ }
+
+ // --------------------------------
+ // page navigation
+
+ /*!
+ \qmlproperty int PdfMultiPageView::currentPage
+ \readonly
+
+ This property holds the zero-based page number of the page visible in the
+ scrollable view. If there is no current page, it holds -1.
+
+ This property is read-only, and is typically used in a binding (or
+ \c onCurrentPageChanged script) to update the part of the user interface
+ that shows the current page number, such as a \l SpinBox.
+
+ \sa PdfPageNavigator::currentPage
+ */
+ property alias currentPage: pageNavigator.currentPage
+
+ /*!
+ \qmlproperty bool PdfMultiPageView::backEnabled
+ \readonly
+
+ This property indicates if it is possible to go back in the navigation
+ history to a previous-viewed page.
+
+ \sa PdfPageNavigator::backAvailable, back()
+ */
+ property alias backEnabled: pageNavigator.backAvailable
+
+ /*!
+ \qmlproperty bool PdfMultiPageView::forwardEnabled
+ \readonly
+
+ This property indicates if it is possible to go to next location in the
+ navigation history.
+
+ \sa PdfPageNavigator::forwardAvailable, forward()
+ */
+ property alias forwardEnabled: pageNavigator.forwardAvailable
+
+ /*!
+ \qmlmethod void PdfMultiPageView::back()
+
+ Scrolls the view back to the previous page that the user visited most
+ recently; or does nothing if there is no previous location on the
+ navigation stack.
+
+ \sa PdfPageNavigator::back(), currentPage, backEnabled
+ */
+ function back() { pageNavigator.back() }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::forward()
+
+ Scrolls the view to the page that the user was viewing when the back()
+ method was called; or does nothing if there is no "next" location on the
+ navigation stack.
+
+ \sa PdfPageNavigator::forward(), currentPage
+ */
+ function forward() { pageNavigator.forward() }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::goToPage(int page)
+
+ Scrolls the view to the given \a page number, if possible.
+
+ \sa PdfPageNavigator::jump(), currentPage
+ */
+ function goToPage(page) {
+ if (page === pageNavigator.currentPage)
+ return
+ goToLocation(page, Qt.point(-1, -1), 0)
+ }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::goToLocation(int page, point location, real zoom)
+
+ Scrolls the view to the \a location on the \a page, if possible,
+ and sets the \a zoom level.
+
+ \sa PdfPageNavigator::jump(), currentPage
+ */
+ function goToLocation(page, location, zoom) {
+ if (tableView.rows === 0) {
+ // save this request for later
+ tableView.pendingRow = page
+ tableView.pendingLocation = location
+ tableView.pendingZoom = zoom
+ return
+ }
+ if (zoom > 0) {
+ pageNavigator.jumping = true // don't call pageNavigator.update() because we will jump() instead
+ root.renderScale = zoom
+ pageNavigator.jumping = false
+ }
+ pageNavigator.jump(page, location, zoom) // actually jump
+ }
+
+ /*!
+ \qmlproperty int PdfMultiPageView::currentPageRenderingStatus
+
+ This property holds the \l {QtQuick::Image::status}{rendering status} of
+ the \l {currentPage}{current page}.
+ */
+ property int currentPageRenderingStatus: Image.Null
+
+ // --------------------------------
+ // page scaling
+
+ /*!
+ \qmlproperty real PdfMultiPageView::renderScale
+
+ This property holds the ratio of pixels to points. The default is \c 1,
+ meaning one point (1/72 of an inch) equals 1 logical pixel.
+ */
+ property real renderScale: 1
+
+ /*!
+ \qmlproperty real PdfMultiPageView::pageRotation
+
+ This property holds the clockwise rotation of the pages.
+
+ The default value is \c 0 degrees (that is, no rotation relative to the
+ orientation of the pages as stored in the PDF file).
+ */
+ property real pageRotation: 0
+
+ /*!
+ \qmlmethod void PdfMultiPageView::resetScale()
+
+ Sets \l renderScale back to its default value of \c 1.
+ */
+ function resetScale() { root.renderScale = 1 }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::scaleToWidth(real width, real height)
+
+ Sets \l renderScale such that the width of the first page will fit into a
+ viewport with the given \a width and \a height. If the page is not rotated,
+ it will be scaled so that its width fits \a width. If it is rotated +/- 90
+ degrees, it will be scaled so that its width fits \a height.
+ */
+ function scaleToWidth(width, height) {
+ root.renderScale = width / (tableView.rot90 ? tableView.firstPagePointSize.height : tableView.firstPagePointSize.width)
+ }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::scaleToPage(real width, real height)
+
+ Sets \l renderScale such that the whole first page will fit into a viewport
+ with the given \a width and \a height. The resulting \l renderScale depends
+ on \l pageRotation: the page will fit into the viewport at a larger size if
+ it is first rotated to have a matching aspect ratio.
+ */
+ function scaleToPage(width, height) {
+ const windowAspect = width / height
+ const pageAspect = tableView.firstPagePointSize.width / tableView.firstPagePointSize.height
+ if (tableView.rot90) {
+ if (windowAspect > pageAspect) {
+ root.renderScale = height / tableView.firstPagePointSize.width
+ } else {
+ root.renderScale = width / tableView.firstPagePointSize.height
+ }
+ } else {
+ if (windowAspect > pageAspect) {
+ root.renderScale = height / tableView.firstPagePointSize.height
+ } else {
+ root.renderScale = width / tableView.firstPagePointSize.width
+ }
+ }
+ }
+
+ // --------------------------------
+ // text search
+
+ /*!
+ \qmlproperty PdfSearchModel PdfMultiPageView::searchModel
+
+ This property holds a PdfSearchModel containing the list of search results
+ for a given \l searchString.
+
+ \sa PdfSearchModel
+ */
+ property alias searchModel: searchModel
+
+ /*!
+ \qmlproperty string PdfMultiPageView::searchString
+
+ This property holds the search string that the user may choose to search
+ for. It is typically used in a binding to the \c text property of a
+ TextField.
+
+ \sa searchModel
+ */
+ property alias searchString: searchModel.searchString
+
+ /*!
+ \qmlmethod void PdfMultiPageView::searchBack()
+
+ Decrements the
+ \l{PdfSearchModel::currentResult}{searchModel's current result}
+ so that the view will jump to the previous search result.
+ */
+ function searchBack() { --searchModel.currentResult }
+
+ /*!
+ \qmlmethod void PdfMultiPageView::searchForward()
+
+ Increments the
+ \l{PdfSearchModel::currentResult}{searchModel's current result}
+ so that the view will jump to the next search result.
+ */
+ function searchForward() { ++searchModel.currentResult }
+
+ LoggingCategory {
+ id: lcMPV
+ name: "qt.pdf.multipageview"
+ }
+
+ id: root
+ PdfStyle { id: style }
+ TableView {
+ id: tableView
+ property bool debug: false
+ property real minScale: 0.1
+ property real maxScale: 10
+ property point jumpLocationMargin: Qt.point(10, 10) // px away from viewport edges
+ anchors.fill: parent
+ anchors.leftMargin: 2
+ model: root.document ? root.document.pageCount : 0
+ rowSpacing: 6
+ property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360)
+ property bool rot90: rotationNorm == 90 || rotationNorm == 270
+ onRot90Changed: forceLayout()
+ onHeightChanged: forceLayout()
+ onWidthChanged: forceLayout()
+ property size firstPagePointSize: root.document?.status === PdfDocument.Ready ? root.document.pagePointSize(0) : Qt.size(1, 1)
+ property real pageHolderWidth: Math.max(root.width, ((rot90 ? root.document?.maxPageHeight : root.document?.maxPageWidth) ?? 0) * root.renderScale)
+ columnWidthProvider: function(col) { return root.document ? pageHolderWidth + vscroll.width + 2 : 0 }
+ rowHeightProvider: function(row) { return (rot90 ? root.document.pagePointSize(row).width : root.document.pagePointSize(row).height) * root.renderScale }
+
+ // delayed-jump feature in case the user called goToPage() or goToLocation() too early
+ property int pendingRow: -1
+ property point pendingLocation
+ property real pendingZoom: -1
+ onRowsChanged: {
+ if (rows > 0 && tableView.pendingRow >= 0) {
+ console.log(lcMPV, "initiating delayed jump to page", tableView.pendingRow, "loc", tableView.pendingLocation, "zoom", tableView.pendingZoom)
+ root.goToLocation(tableView.pendingRow, tableView.pendingLocation, tableView.pendingZoom)
+ tableView.pendingRow = -1
+ tableView.pendingLocation = Qt.point(-1, -1)
+ tableView.pendingZoom = -1
+ }
+ }
+
+ delegate: Rectangle {
+ id: pageHolder
+ required property int index
+ color: tableView.debug ? "beige" : "transparent"
+ Text {
+ visible: tableView.debug
+ anchors { right: parent.right; verticalCenter: parent.verticalCenter }
+ rotation: -90; text: pageHolder.width.toFixed(1) + "x" + pageHolder.height.toFixed(1) + "\n" +
+ image.width.toFixed(1) + "x" + image.height.toFixed(1)
+ }
+ property alias selection: selection
+ Rectangle {
+ id: paper
+ width: image.width
+ height: image.height
+ rotation: root.pageRotation
+ anchors.centerIn: pinch.active ? undefined : parent
+ property size pagePointSize: root.document.pagePointSize(pageHolder.index)
+ property real pageScale: image.paintedWidth / pagePointSize.width
+ PdfPageImage {
+ id: image
+ document: root.document
+ currentFrame: pageHolder.index
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ width: paper.pagePointSize.width * root.renderScale
+ height: paper.pagePointSize.height * root.renderScale
+ property real renderScale: root.renderScale
+ property real oldRenderScale: 1
+ onRenderScaleChanged: {
+ image.sourceSize.width = paper.pagePointSize.width * renderScale * Screen.devicePixelRatio
+ image.sourceSize.height = 0
+ paper.scale = 1
+ searchHighlights.update()
+ }
+ onStatusChanged: {
+ if (pageHolder.index === pageNavigator.currentPage)
+ root.currentPageRenderingStatus = status
+ }
+ }
+ Shape {
+ anchors.fill: parent
+ visible: image.status === Image.Ready
+ onVisibleChanged: searchHighlights.update()
+ ShapePath {
+ strokeWidth: -1
+ fillColor: style.pageSearchResultsColor
+ scale: Qt.size(paper.pageScale, paper.pageScale)
+ PathMultiline {
+ id: searchHighlights
+ function update() {
+ // paths could be a binding, but we need to be able to "kick" it sometimes
+ paths = searchModel.boundingPolygonsOnPage(pageHolder.index)
+ }
+ }
+ }
+ Connections {
+ target: searchModel
+ // whenever the highlights on the _current_ page change, they actually need to change on _all_ pages
+ // (usually because the search string has changed)
+ function onCurrentPageBoundingPolygonsChanged() { searchHighlights.update() }
+ }
+ ShapePath {
+ strokeWidth: -1
+ fillColor: style.selectionColor
+ scale: Qt.size(paper.pageScale, paper.pageScale)
+ PathMultiline {
+ paths: selection.geometry
+ }
+ }
+ }
+ Shape {
+ anchors.fill: parent
+ visible: image.status === Image.Ready && searchModel.currentPage === pageHolder.index
+ ShapePath {
+ strokeWidth: style.currentSearchResultStrokeWidth
+ strokeColor: style.currentSearchResultStrokeColor
+ fillColor: "transparent"
+ scale: Qt.size(paper.pageScale, paper.pageScale)
+ PathMultiline {
+ paths: searchModel.currentResultBoundingPolygons
+ }
+ }
+ }
+ PinchHandler {
+ id: pinch
+ minimumScale: tableView.minScale / root.renderScale
+ maximumScale: Math.max(1, tableView.maxScale / root.renderScale)
+ minimumRotation: root.pageRotation
+ maximumRotation: root.pageRotation
+ onActiveChanged:
+ if (active) {
+ paper.z = 10
+ } else {
+ paper.z = 0
+ const centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
+ pinch.centroid.position.y / root.renderScale)
+ const centroidInFlickable = tableView.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
+ const newSourceWidth = image.sourceSize.width * paper.scale
+ const ratio = newSourceWidth / image.sourceSize.width
+ console.log(lcMPV, "pinch ended on page", pageHolder.index,
+ "with scale", paper.scale.toFixed(3), "ratio", ratio.toFixed(3),
+ "centroid", pinch.centroid.position, centroidInPoints,
+ "wrt flickable", centroidInFlickable,
+ "page at", pageHolder.x.toFixed(2), pageHolder.y.toFixed(2),
+ "contentX/Y were", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2))
+ if (ratio > 1.1 || ratio < 0.9) {
+ const centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
+ paper.scale = 1
+ pinch.persistentScale = 1
+ paper.x = 0
+ paper.y = 0
+ root.renderScale *= ratio
+ tableView.forceLayout()
+ if (tableView.rotationNorm == 0) {
+ tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.x - centroidInFlickable.x
+ tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.y - centroidInFlickable.y
+ } else if (tableView.rotationNorm == 90) {
+ tableView.contentX = pageHolder.x + tableView.originX + image.height - centroidOnPage.y - centroidInFlickable.x
+ tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.x - centroidInFlickable.y
+ } else if (tableView.rotationNorm == 180) {
+ tableView.contentX = pageHolder.x + tableView.originX + image.width - centroidOnPage.x - centroidInFlickable.x
+ tableView.contentY = pageHolder.y + tableView.originY + image.height - centroidOnPage.y - centroidInFlickable.y
+ } else if (tableView.rotationNorm == 270) {
+ tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.y - centroidInFlickable.x
+ tableView.contentY = pageHolder.y + tableView.originY + image.width - centroidOnPage.x - centroidInFlickable.y
+ }
+ console.log(lcMPV, "contentX/Y adjusted to", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2), "y @top", pageHolder.y)
+ tableView.returnToBounds()
+ }
+ }
+ grabPermissions: PointerHandler.CanTakeOverFromAnything
+ }
+ DragHandler {
+ id: textSelectionDrag
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ target: null
+ }
+ TapHandler {
+ id: mouseClickHandler
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ }
+ TapHandler {
+ id: touchTapHandler
+ acceptedDevices: PointerDevice.TouchScreen
+ onTapped: {
+ selection.clear()
+ selection.forceActiveFocus()
+ }
+ }
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: root.document
+ page: image.currentFrame
+ }
+ delegate: PdfLinkDelegate {
+ x: rectangle.x * paper.pageScale
+ y: rectangle.y * paper.pageScale
+ width: rectangle.width * paper.pageScale
+ height: rectangle.height * paper.pageScale
+ visible: image.status === Image.Ready
+ onTapped:
+ (link) => {
+ if (link.page >= 0)
+ root.goToLocation(link.page, link.location, link.zoom)
+ else
+ Qt.openUrlExternally(url)
+ }
+ }
+ }
+ PdfSelection {
+ id: selection
+ anchors.fill: parent
+ document: root.document
+ page: image.currentFrame
+ renderScale: image.renderScale
+ from: textSelectionDrag.centroid.pressPosition
+ to: textSelectionDrag.centroid.position
+ hold: !textSelectionDrag.active && !mouseClickHandler.pressed
+ onTextChanged: root.selectedText = text
+ focus: true
+ }
+ }
+ }
+ ScrollBar.vertical: ScrollBar {
+ id: vscroll
+ property bool moved: false
+ onPositionChanged: moved = true
+ onPressedChanged: if (pressed) {
+ // When the user starts scrolling, push the location where we came from so the user can go "back" there
+ const cell = tableView.cellAtPos(root.width / 2, root.height / 2)
+ const currentItem = tableView.itemAtCell(cell)
+ const currentLocation = currentItem
+ ? Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
+ (tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
+ : Qt.point(0, 0) // maybe the delegate wasn't loaded yet
+ pageNavigator.jump(cell.y, currentLocation, root.renderScale)
+ }
+ onActiveChanged: if (!active ) {
+ // When the scrollbar stops moving, tell navstack where we are, so as to update currentPage etc.
+ const cell = tableView.cellAtPos(root.width / 2, root.height / 2)
+ const currentItem = tableView.itemAtCell(cell)
+ const currentLocation = currentItem
+ ? Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
+ (tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
+ : Qt.point(0, 0) // maybe the delegate wasn't loaded yet
+ pageNavigator.update(cell.y, currentLocation, root.renderScale)
+ }
+ }
+ ScrollBar.horizontal: ScrollBar { }
+ }
+ onRenderScaleChanged: {
+ // if pageNavigator.jumped changes the scale, don't turn around and update the stack again;
+ // and don't force layout either, because positionViewAtCell() will do that
+ if (pageNavigator.jumping)
+ return
+ // page size changed: TableView needs to redo layout to avoid overlapping delegates or gaps between them
+ tableView.forceLayout()
+ const cell = tableView.cellAtPos(root.width / 2, root.height / 2)
+ const currentItem = tableView.itemAtCell(cell)
+ if (currentItem) {
+ const currentLocation = Qt.point((tableView.contentX - currentItem.x + tableView.jumpLocationMargin.x) / root.renderScale,
+ (tableView.contentY - currentItem.y + tableView.jumpLocationMargin.y) / root.renderScale)
+ pageNavigator.update(cell.y, currentLocation, renderScale)
+ }
+ }
+ PdfPageNavigator {
+ id: pageNavigator
+ property bool jumping: false
+ property int previousPage: 0
+ onJumped: function(current) {
+ jumping = true
+ if (current.zoom > 0)
+ root.renderScale = current.zoom
+ const pageSize = root.document.pagePointSize(current.page)
+ if (current.location.y < 0) {
+ // invalid to indicate that a specific location was not needed,
+ // so attempt to position the new page just as the current page is
+ const previousPageDelegate = tableView.itemAtCell(0, previousPage)
+ const currentYOffset = previousPageDelegate
+ ? tableView.contentY - previousPageDelegate.y
+ : 0
+ tableView.positionViewAtRow(current.page, Qt.AlignTop, currentYOffset)
+ console.log(lcMPV, "going from page", previousPage, "to", current.page, "offset", currentYOffset,
+ "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
+ } else if (current.rectangles.length > 0) {
+ // jump to a search result and position the covered area within the viewport
+ pageSize.width *= root.renderScale
+ pageSize.height *= root.renderScale
+ const rectPts = current.rectangles[0]
+ const rectPx = Qt.rect(rectPts.x * root.renderScale - tableView.jumpLocationMargin.x,
+ rectPts.y * root.renderScale - tableView.jumpLocationMargin.y,
+ rectPts.width * root.renderScale + tableView.jumpLocationMargin.x * 2,
+ rectPts.height * root.renderScale + tableView.jumpLocationMargin.y * 2)
+ tableView.positionViewAtCell(0, current.page, TableView.Contain, Qt.point(0, 0), rectPx)
+ console.log(lcMPV, "going to zoom", root.renderScale, "rect", rectPx, "on page", current.page,
+ "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
+ } else {
+ // jump to a page and position the given location relative to the top-left corner of the viewport
+ pageSize.width *= root.renderScale
+ pageSize.height *= root.renderScale
+ const rectPx = Qt.rect(current.location.x * root.renderScale - tableView.jumpLocationMargin.x,
+ current.location.y * root.renderScale - tableView.jumpLocationMargin.y,
+ tableView.jumpLocationMargin.x * 2, tableView.jumpLocationMargin.y * 2)
+ tableView.positionViewAtCell(0, current.page, TableView.AlignLeft | TableView.AlignTop, Qt.point(0, 0), rectPx)
+ console.log(lcMPV, "going to zoom", root.renderScale, "loc", current.location, "on page", current.page,
+ "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
+ }
+ jumping = false
+ previousPage = current.page
+ }
+
+ property url documentSource: root.document.source
+ onDocumentSourceChanged: {
+ pageNavigator.clear()
+ root.resetScale()
+ tableView.contentX = 0
+ tableView.contentY = 0
+ }
+ }
+ PdfSearchModel {
+ id: searchModel
+ document: root.document === undefined ? null : root.document
+ onCurrentResultChanged: pageNavigator.jump(currentResultLink)
+ }
+}
diff --git a/src/pdfquick/PdfPageView.qml b/src/pdfquick/PdfPageView.qml
new file mode 100644
index 000000000..290570f2b
--- /dev/null
+++ b/src/pdfquick/PdfPageView.qml
@@ -0,0 +1,439 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Pdf
+import QtQuick.Shapes
+
+/*!
+ \qmltype PdfPageView
+ \inqmlmodule QtQuick.Pdf
+ \brief A PDF viewer component to show one page a time.
+
+ PdfPageView provides a PDF viewer component that shows one whole page at a
+ time, without scrolling. It supports selecting text and copying it to the
+ clipboard, zooming in and out, clicking an internal link to jump to another
+ section in the document, rotating the view, and searching for text.
+
+ The implementation is a QML assembly of smaller building blocks that are
+ available separately. In case you want to make changes in your own version
+ of this component, you can copy the QML, which is installed into the
+ \c QtQuick/Pdf/qml module directory, and modify it as needed.
+
+ \sa PdfScrollablePageView, PdfMultiPageView, PdfStyle
+*/
+Rectangle {
+ /*!
+ \qmlproperty PdfDocument PdfPageView::document
+
+ A PdfDocument object with a valid \c source URL is required:
+
+ \snippet multipageview.qml 0
+ */
+ required property PdfDocument document
+
+ /*!
+ \qmlproperty int PdfPageView::status
+
+ This property holds the \l {QtQuick::Image::status}{rendering status} of
+ the \l {currentPage}{current page}.
+ */
+ property alias status: image.status
+
+ /*!
+ \qmlproperty PdfDocument PdfPageView::selectedText
+
+ The selected text.
+ */
+ property alias selectedText: selection.text
+
+ /*!
+ \qmlmethod void PdfPageView::selectAll()
+
+ Selects all the text on the \l {currentPage}{current page}, and makes it
+ available as the system \l {QClipboard::Selection}{selection} on systems
+ that support that feature.
+
+ \sa copySelectionToClipboard()
+ */
+ function selectAll() {
+ selection.selectAll()
+ }
+
+ /*!
+ \qmlmethod void PdfPageView::copySelectionToClipboard()
+
+ Copies the selected text (if any) to the
+ \l {QClipboard::Clipboard}{system clipboard}.
+
+ \sa selectAll()
+ */
+ function copySelectionToClipboard() {
+ selection.copyToClipboard()
+ }
+
+ // --------------------------------
+ // page navigation
+
+ /*!
+ \qmlproperty int PdfPageView::currentPage
+ \readonly
+
+ This property holds the zero-based page number of the page visible in the
+ scrollable view. If there is no current page, it holds -1.
+
+ This property is read-only, and is typically used in a binding (or
+ \c onCurrentPageChanged script) to update the part of the user interface
+ that shows the current page number, such as a \l SpinBox.
+
+ \sa PdfPageNavigator::currentPage
+ */
+ property alias currentPage: pageNavigator.currentPage
+
+ /*!
+ \qmlproperty bool PdfPageView::backEnabled
+ \readonly
+
+ This property indicates if it is possible to go back in the navigation
+ history to a previous-viewed page.
+
+ \sa PdfPageNavigator::backAvailable, back()
+ */
+ property alias backEnabled: pageNavigator.backAvailable
+
+ /*!
+ \qmlproperty bool PdfPageView::forwardEnabled
+ \readonly
+
+ This property indicates if it is possible to go to next location in the
+ navigation history.
+
+ \sa PdfPageNavigator::forwardAvailable, forward()
+ */
+ property alias forwardEnabled: pageNavigator.forwardAvailable
+
+ /*!
+ \qmlmethod void PdfPageView::back()
+
+ Scrolls the view back to the previous page that the user visited most
+ recently; or does nothing if there is no previous location on the
+ navigation stack.
+
+ \sa PdfPageNavigator::back(), currentPage, backEnabled
+ */
+ function back() { pageNavigator.back() }
+
+ /*!
+ \qmlmethod void PdfPageView::forward()
+
+ Scrolls the view to the page that the user was viewing when the back()
+ method was called; or does nothing if there is no "next" location on the
+ navigation stack.
+
+ \sa PdfPageNavigator::forward(), currentPage
+ */
+ function forward() { pageNavigator.forward() }
+
+ /*!
+ \qmlmethod void PdfPageView::goToPage(int page)
+
+ Changes the view to the \a page, if possible.
+
+ \sa PdfPageNavigator::jump(), currentPage
+ */
+ function goToPage(page) { goToLocation(page, Qt.point(0, 0), 0) }
+
+ /*!
+ \qmlmethod void PdfPageView::goToLocation(int page, point location, real zoom)
+
+ Scrolls the view to the \a location on the \a page, if possible,
+ and sets the \a zoom level.
+
+ \sa PdfPageNavigator::jump(), currentPage
+ */
+ function goToLocation(page, location, zoom) {
+ if (zoom > 0)
+ root.renderScale = zoom
+ pageNavigator.jump(page, location, zoom)
+ }
+
+ // --------------------------------
+ // page scaling
+
+ /*!
+ \qmlproperty bool PdfPageView::zoomEnabled
+
+ This property holds whether the user can use the pinch gesture or
+ Control + mouse wheel to zoom. The default is \c true.
+
+ When the user zooms the page, the size of PdfPageView changes.
+ */
+ property bool zoomEnabled: true
+
+ /*!
+ \qmlproperty real PdfPageView::renderScale
+
+ This property holds the ratio of pixels to points. The default is \c 1,
+ meaning one point (1/72 of an inch) equals 1 logical pixel.
+ */
+ property real renderScale: 1
+
+ /*!
+ \qmlproperty size PdfPageView::sourceSize
+
+ This property holds the scaled width and height of the full-frame image.
+
+ \sa {QtQuick::Image::sourceSize}{Image.sourceSize}
+ */
+ property alias sourceSize: image.sourceSize
+
+ /*!
+ \qmlmethod void PdfPageView::resetScale()
+
+ Sets \l renderScale back to its default value of \c 1.
+ */
+ function resetScale() {
+ image.sourceSize.width = 0
+ image.sourceSize.height = 0
+ root.scale = 1
+ }
+
+ /*!
+ \qmlmethod void PdfPageView::scaleToWidth(real width, real height)
+
+ Sets \l renderScale such that the width of the first page will fit into a
+ viewport with the given \a width and \a height. If the page is not rotated,
+ it will be scaled so that its width fits \a width. If it is rotated +/- 90
+ degrees, it will be scaled so that its width fits \a height.
+ */
+ function scaleToWidth(width, height) {
+ const halfRotation = Math.abs(root.rotation % 180)
+ image.sourceSize = Qt.size((halfRotation > 45 && halfRotation < 135) ? height : width, 0)
+ image.centerInSize = Qt.size(width, height)
+ image.centerOnLoad = true
+ image.vCenterOnLoad = (halfRotation > 45 && halfRotation < 135)
+ root.scale = 1
+ }
+
+ /*!
+ \qmlmethod void PdfPageView::scaleToPage(real width, real height)
+
+ Sets \l renderScale such that the whole first page will fit into a viewport
+ with the given \a width and \a height. The resulting \l renderScale depends
+ on page rotation: the page will fit into the viewport at a larger size if it
+ is first rotated to have a matching aspect ratio.
+ */
+ function scaleToPage(width, height) {
+ const windowAspect = width / height
+ const halfRotation = Math.abs(root.rotation % 180)
+ const pagePointSize = document.pagePointSize(pageNavigator.currentPage)
+ const pageAspect = pagePointSize.height / pagePointSize.width
+ if (halfRotation > 45 && halfRotation < 135) {
+ // rotated 90 or 270º
+ if (windowAspect > pageAspect) {
+ image.sourceSize = Qt.size(height, 0)
+ } else {
+ image.sourceSize = Qt.size(0, width)
+ }
+ } else {
+ if (windowAspect > pageAspect) {
+ image.sourceSize = Qt.size(0, height)
+ } else {
+ image.sourceSize = Qt.size(width, 0)
+ }
+ }
+ image.centerInSize = Qt.size(width, height)
+ image.centerOnLoad = true
+ image.vCenterOnLoad = true
+ root.scale = 1
+ }
+
+ // --------------------------------
+ // text search
+
+ /*!
+ \qmlproperty PdfSearchModel PdfPageView::searchModel
+
+ This property holds a PdfSearchModel containing the list of search results
+ for a given \l searchString.
+
+ \sa PdfSearchModel
+ */
+ property alias searchModel: searchModel
+
+ /*!
+ \qmlproperty string PdfPageView::searchString
+
+ This property holds the search string that the user may choose to search
+ for. It is typically used in a binding to the \c text property of a
+ TextField.
+
+ \sa searchModel
+ */
+ property alias searchString: searchModel.searchString
+
+ /*!
+ \qmlmethod void PdfPageView::searchBack()
+
+ Decrements the
+ \l{PdfSearchModel::currentResult}{searchModel's current result}
+ so that the view will jump to the previous search result.
+ */
+ function searchBack() { --searchModel.currentResult }
+
+ /*!
+ \qmlmethod void PdfPageView::searchForward()
+
+ Increments the
+ \l{PdfSearchModel::currentResult}{searchModel's current result}
+ so that the view will jump to the next search result.
+ */
+ function searchForward() { ++searchModel.currentResult }
+
+ // --------------------------------
+ // implementation
+ id: root
+ width: image.width
+ height: image.height
+
+ PdfSelection {
+ id: selection
+ document: root.document
+ page: pageNavigator.currentPage
+ from: Qt.point(textSelectionDrag.centroid.pressPosition.x / image.pageScale, textSelectionDrag.centroid.pressPosition.y / image.pageScale)
+ to: Qt.point(textSelectionDrag.centroid.position.x / image.pageScale, textSelectionDrag.centroid.position.y / image.pageScale)
+ hold: !textSelectionDrag.active && !tapHandler.pressed
+ }
+
+ PdfSearchModel {
+ id: searchModel
+ document: root.document === undefined ? null : root.document
+ onCurrentPageChanged: root.goToPage(currentPage)
+ }
+
+ PdfPageNavigator {
+ id: pageNavigator
+ onCurrentPageChanged: searchModel.currentPage = currentPage
+ onCurrentZoomChanged: root.renderScale = currentZoom
+
+ property url documentSource: root.document.source
+ onDocumentSourceChanged: {
+ pageNavigator.clear()
+ root.goToPage(0)
+ }
+ }
+
+ PdfPageImage {
+ id: image
+ document: root.document
+ currentFrame: pageNavigator.currentPage
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ property bool centerOnLoad: false
+ property bool vCenterOnLoad: false
+ property size centerInSize
+ property real pageScale: image.paintedWidth / document.pagePointSize(pageNavigator.currentPage).width
+ function reRenderIfNecessary() {
+ const newSourceWidth = image.sourceSize.width * root.scale * Screen.devicePixelRatio
+ const ratio = newSourceWidth / image.sourceSize.width
+ if (ratio > 1.1 || ratio < 0.9) {
+ image.sourceSize.width = newSourceWidth
+ image.sourceSize.height = 0
+ root.scale = 1
+ }
+ }
+ onStatusChanged:
+ if (status == Image.Ready && centerOnLoad) {
+ root.x = (centerInSize.width - image.implicitWidth) / 2
+ root.y = vCenterOnLoad ? (centerInSize.height - image.implicitHeight) / 2 : 0
+ centerOnLoad = false
+ vCenterOnLoad = false
+ }
+ }
+ onRenderScaleChanged: {
+ image.sourceSize.width = document.pagePointSize(pageNavigator.currentPage).width * renderScale
+ image.sourceSize.height = 0
+ root.scale = 1
+ }
+
+ Shape {
+ anchors.fill: parent
+ opacity: 0.25
+ visible: image.status === Image.Ready
+ ShapePath {
+ strokeWidth: 1
+ strokeColor: "cyan"
+ fillColor: "steelblue"
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: searchModel.currentPageBoundingPolygons
+ }
+ }
+ ShapePath {
+ strokeWidth: 1
+ strokeColor: "orange"
+ fillColor: "cyan"
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: searchModel.currentResultBoundingPolygons
+ }
+ }
+ ShapePath {
+ fillColor: "orange"
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: selection.geometry
+ }
+ }
+ }
+
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: root.document
+ page: pageNavigator.currentPage
+ }
+ delegate: PdfLinkDelegate {
+ x: rectangle.x * image.pageScale
+ y: rectangle.y * image.pageScale
+ width: rectangle.width * image.pageScale
+ height: rectangle.height * image.pageScale
+ visible: image.status === Image.Ready
+ onTapped:
+ (link) => {
+ if (link.page >= 0)
+ pageNavigator.jump(link)
+ else
+ Qt.openUrlExternally(url)
+ }
+ }
+ }
+
+ PinchHandler {
+ id: pinch
+ enabled: root.zoomEnabled && root.scale * root.renderScale <= 10 && root.scale * root.renderScale >= 0.1
+ minimumScale: 0.1
+ maximumScale: 10
+ minimumRotation: 0
+ maximumRotation: 0
+ onActiveChanged: if (!active) image.reRenderIfNecessary()
+ grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started
+ }
+ WheelHandler {
+ enabled: pinch.enabled
+ acceptedModifiers: Qt.ControlModifier
+ property: "scale"
+ onActiveChanged: if (!active) image.reRenderIfNecessary()
+ }
+ DragHandler {
+ id: textSelectionDrag
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ target: null
+ }
+ TapHandler {
+ id: tapHandler
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ }
+}
diff --git a/src/pdfquick/PdfScrollablePageView.qml b/src/pdfquick/PdfScrollablePageView.qml
new file mode 100644
index 000000000..9fa0547c6
--- /dev/null
+++ b/src/pdfquick/PdfScrollablePageView.qml
@@ -0,0 +1,487 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Pdf
+import QtQuick.Shapes
+
+/*!
+ \qmltype PdfScrollablePageView
+ \inqmlmodule QtQuick.Pdf
+ \brief A complete PDF viewer component to show one page a time, with scrolling.
+
+ PdfScrollablePageView provides a PDF viewer component that shows one page
+ at a time, with scrollbars to move around the page. It also supports
+ selecting text and copying it to the clipboard, zooming in and out,
+ clicking an internal link to jump to another section in the document,
+ rotating the view, and searching for text. The pdfviewer example
+ demonstrates how to use these features in an application.
+
+ The implementation is a QML assembly of smaller building blocks that are
+ available separately. In case you want to make changes in your own version
+ of this component, you can copy the QML, which is installed into the
+ \c QtQuick/Pdf/qml module directory, and modify it as needed.
+
+ \sa PdfPageView, PdfMultiPageView, PdfStyle
+*/
+Flickable {
+ /*!
+ \qmlproperty PdfDocument PdfScrollablePageView::document
+
+ A PdfDocument object with a valid \c source URL is required:
+
+ \snippet multipageview.qml 0
+ */
+ required property PdfDocument document
+
+ /*!
+ \qmlproperty int PdfScrollablePageView::status
+
+ This property holds the \l {QtQuick::Image::status}{rendering status} of
+ the \l {currentPage}{current page}.
+ */
+ property alias status: image.status
+
+ /*!
+ \qmlproperty PdfDocument PdfScrollablePageView::selectedText
+
+ The selected text.
+ */
+ property alias selectedText: selection.text
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::selectAll()
+
+ Selects all the text on the \l {currentPage}{current page}, and makes it
+ available as the system \l {QClipboard::Selection}{selection} on systems
+ that support that feature.
+
+ \sa copySelectionToClipboard()
+ */
+ function selectAll() {
+ selection.selectAll()
+ }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::copySelectionToClipboard()
+
+ Copies the selected text (if any) to the
+ \l {QClipboard::Clipboard}{system clipboard}.
+
+ \sa selectAll()
+ */
+ function copySelectionToClipboard() {
+ selection.copyToClipboard()
+ }
+
+ // --------------------------------
+ // page navigation
+
+ /*!
+ \qmlproperty int PdfScrollablePageView::currentPage
+ \readonly
+
+ This property holds the zero-based page number of the page visible in the
+ scrollable view. If there is no current page, it holds -1.
+
+ This property is read-only, and is typically used in a binding (or
+ \c onCurrentPageChanged script) to update the part of the user interface
+ that shows the current page number, such as a \l SpinBox.
+
+ \sa PdfPageNavigator::currentPage
+ */
+ property alias currentPage: pageNavigator.currentPage
+
+ /*!
+ \qmlproperty bool PdfScrollablePageView::backEnabled
+ \readonly
+
+ This property indicates if it is possible to go back in the navigation
+ history to a previous-viewed page.
+
+ \sa PdfPageNavigator::backAvailable, back()
+ */
+ property alias backEnabled: pageNavigator.backAvailable
+
+ /*!
+ \qmlproperty bool PdfScrollablePageView::forwardEnabled
+ \readonly
+
+ This property indicates if it is possible to go to next location in the
+ navigation history.
+
+ \sa PdfPageNavigator::forwardAvailable, forward()
+ */
+ property alias forwardEnabled: pageNavigator.forwardAvailable
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::back()
+
+ Scrolls the view back to the previous page that the user visited most
+ recently; or does nothing if there is no previous location on the
+ navigation stack.
+
+ \sa PdfPageNavigator::back(), currentPage, backEnabled
+ */
+ function back() { pageNavigator.back() }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::forward()
+
+ Scrolls the view to the page that the user was viewing when the back()
+ method was called; or does nothing if there is no "next" location on the
+ navigation stack.
+
+ \sa PdfPageNavigator::forward(), currentPage
+ */
+ function forward() { pageNavigator.forward() }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::goToPage(int page)
+
+ Changes the view to the \a page, if possible.
+
+ \sa PdfPageNavigator::jump(), currentPage
+ */
+ function goToPage(page) {
+ if (page === pageNavigator.currentPage)
+ return
+ goToLocation(page, Qt.point(0, 0), 0)
+ }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::goToLocation(int page, point location, real zoom)
+
+ Scrolls the view to the \a location on the \a page, if possible,
+ and sets the \a zoom level.
+
+ \sa PdfPageNavigator::jump(), currentPage
+ */
+ function goToLocation(page, location, zoom) {
+ if (zoom > 0)
+ root.renderScale = zoom
+ pageNavigator.jump(page, location, zoom)
+ }
+
+ // --------------------------------
+ // page scaling
+
+ /*!
+ \qmlproperty real PdfScrollablePageView::renderScale
+
+ This property holds the ratio of pixels to points. The default is \c 1,
+ meaning one point (1/72 of an inch) equals 1 logical pixel.
+ */
+ property real renderScale: 1
+
+ /*!
+ \qmlproperty real PdfScrollablePageView::pageRotation
+
+ This property holds the clockwise rotation of the pages.
+
+ The default value is \c 0 degrees (that is, no rotation relative to the
+ orientation of the pages as stored in the PDF file).
+ */
+ property real pageRotation: 0
+
+ /*!
+ \qmlproperty size PdfScrollablePageView::sourceSize
+
+ This property holds the scaled width and height of the full-frame image.
+
+ \sa {QtQuick::Image::sourceSize}{Image.sourceSize}
+ */
+ property alias sourceSize: image.sourceSize
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::resetScale()
+
+ Sets \l renderScale back to its default value of \c 1.
+ */
+ function resetScale() {
+ paper.scale = 1
+ root.renderScale = 1
+ }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::scaleToWidth(real width, real height)
+
+ Sets \l renderScale such that the width of the first page will fit into a
+ viewport with the given \a width and \a height. If the page is not rotated,
+ it will be scaled so that its width fits \a width. If it is rotated +/- 90
+ degrees, it will be scaled so that its width fits \a height.
+ */
+ function scaleToWidth(width, height) {
+ const pagePointSize = document.pagePointSize(pageNavigator.currentPage)
+ root.renderScale = root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width)
+ console.log(lcSPV, "scaling", pagePointSize, "to fit", root.width, "rotated?", paper.rot90, "scale", root.renderScale)
+ root.contentX = 0
+ root.contentY = 0
+ }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::scaleToPage(real width, real height)
+
+ Sets \l renderScale such that the whole first page will fit into a viewport
+ with the given \a width and \a height. The resulting \l renderScale depends
+ on \l pageRotation: the page will fit into the viewport at a larger size if
+ it is first rotated to have a matching aspect ratio.
+ */
+ function scaleToPage(width, height) {
+ const pagePointSize = document.pagePointSize(pageNavigator.currentPage)
+ root.renderScale = Math.min(
+ root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width),
+ root.height / (paper.rot90 ? pagePointSize.width : pagePointSize.height) )
+ root.contentX = 0
+ root.contentY = 0
+ }
+
+ // --------------------------------
+ // text search
+
+ /*!
+ \qmlproperty PdfSearchModel PdfScrollablePageView::searchModel
+
+ This property holds a PdfSearchModel containing the list of search results
+ for a given \l searchString.
+
+ \sa PdfSearchModel
+ */
+ property alias searchModel: searchModel
+
+ /*!
+ \qmlproperty string PdfScrollablePageView::searchString
+
+ This property holds the search string that the user may choose to search
+ for. It is typically used in a binding to the \c text property of a
+ TextField.
+
+ \sa searchModel
+ */
+ property alias searchString: searchModel.searchString
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::searchBack()
+
+ Decrements the
+ \l{PdfSearchModel::currentResult}{searchModel's current result}
+ so that the view will jump to the previous search result.
+ */
+ function searchBack() { --searchModel.currentResult }
+
+ /*!
+ \qmlmethod void PdfScrollablePageView::searchForward()
+
+ Increments the
+ \l{PdfSearchModel::currentResult}{searchModel's current result}
+ so that the view will jump to the next search result.
+ */
+ function searchForward() { ++searchModel.currentResult }
+
+ // --------------------------------
+ // implementation
+ id: root
+ PdfStyle { id: style }
+ contentWidth: paper.width
+ contentHeight: paper.height
+ ScrollBar.vertical: ScrollBar {
+ onActiveChanged:
+ if (!active ) {
+ const currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
+ (root.contentY + root.height / 2) / root.renderScale)
+ pageNavigator.update(pageNavigator.currentPage, currentLocation, root.renderScale)
+ }
+ }
+ ScrollBar.horizontal: ScrollBar {
+ onActiveChanged:
+ if (!active ) {
+ const currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
+ (root.contentY + root.height / 2) / root.renderScale)
+ pageNavigator.update(pageNavigator.currentPage, currentLocation, root.renderScale)
+ }
+ }
+
+ onRenderScaleChanged: {
+ paper.scale = 1
+ const currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
+ (root.contentY + root.height / 2) / root.renderScale)
+ pageNavigator.update(pageNavigator.currentPage, currentLocation, root.renderScale)
+ }
+
+ PdfSearchModel {
+ id: searchModel
+ document: root.document === undefined ? null : root.document
+ onCurrentResultChanged: pageNavigator.jump(currentResultLink)
+ }
+
+ PdfPageNavigator {
+ id: pageNavigator
+ onJumped: function(current) {
+ root.renderScale = current.zoom
+ const dx = Math.max(0, current.location.x * root.renderScale - root.width / 2) - root.contentX
+ const dy = Math.max(0, current.location.y * root.renderScale - root.height / 2) - root.contentY
+ // don't jump if location is in the viewport already, i.e. if the "error" between desired and actual contentX/Y is small
+ if (Math.abs(dx) > root.width / 3)
+ root.contentX += dx
+ if (Math.abs(dy) > root.height / 3)
+ root.contentY += dy
+ console.log(lcSPV, "going to zoom", current.zoom, "loc", current.location,
+ "on page", current.page, "ended up @", root.contentX + ", " + root.contentY)
+ }
+ onCurrentPageChanged: searchModel.currentPage = currentPage
+
+ property url documentSource: root.document.source
+ onDocumentSourceChanged: {
+ pageNavigator.clear()
+ root.resetScale()
+ root.contentX = 0
+ root.contentY = 0
+ }
+ }
+
+ LoggingCategory {
+ id: lcSPV
+ name: "qt.pdf.singlepageview"
+ }
+
+ Rectangle {
+ id: paper
+ width: rot90 ? image.height : image.width
+ height: rot90 ? image.width : image.height
+ property real rotationModulus: Math.abs(root.pageRotation % 180)
+ property bool rot90: rotationModulus > 45 && rotationModulus < 135
+ property real minScale: 0.1
+ property real maxScale: 10
+
+ PdfPageImage {
+ id: image
+ document: root.document
+ currentFrame: pageNavigator.currentPage
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ rotation: root.pageRotation
+ anchors.centerIn: parent
+ property real pageScale: image.paintedWidth / document.pagePointSize(pageNavigator.currentPage).width
+ width: document.pagePointSize(pageNavigator.currentPage).width * root.renderScale
+ height: document.pagePointSize(pageNavigator.currentPage).height * root.renderScale
+ sourceSize.width: width * Screen.devicePixelRatio
+ sourceSize.height: 0
+
+ Shape {
+ anchors.fill: parent
+ visible: image.status === Image.Ready
+ ShapePath {
+ strokeWidth: -1
+ fillColor: style.pageSearchResultsColor
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: searchModel.currentPageBoundingPolygons
+ }
+ }
+ ShapePath {
+ strokeWidth: style.currentSearchResultStrokeWidth
+ strokeColor: style.currentSearchResultStrokeColor
+ fillColor: "transparent"
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: searchModel.currentResultBoundingPolygons
+ }
+ }
+ ShapePath {
+ fillColor: style.selectionColor
+ scale: Qt.size(image.pageScale, image.pageScale)
+ PathMultiline {
+ paths: selection.geometry
+ }
+ }
+ }
+
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: root.document
+ page: pageNavigator.currentPage
+ }
+ delegate: PdfLinkDelegate {
+ x: rectangle.x * image.pageScale
+ y: rectangle.y * image.pageScale
+ width: rectangle.width * image.pageScale
+ height: rectangle.height * image.pageScale
+ visible: image.status === Image.Ready
+ onTapped:
+ (link) => {
+ if (link.page >= 0)
+ pageNavigator.jump(link.page, link.location, link.zoom)
+ else
+ Qt.openUrlExternally(url)
+ }
+ }
+ }
+ DragHandler {
+ id: textSelectionDrag
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ target: null
+ }
+ TapHandler {
+ id: mouseClickHandler
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ }
+ TapHandler {
+ id: touchTapHandler
+ acceptedDevices: PointerDevice.TouchScreen
+ onTapped: {
+ selection.clear()
+ selection.focus = true
+ }
+ }
+ }
+
+ PdfSelection {
+ id: selection
+ anchors.fill: parent
+ document: root.document
+ page: pageNavigator.currentPage
+ renderScale: image.pageScale == 0 ? 1.0 : image.pageScale
+ from: textSelectionDrag.centroid.pressPosition
+ to: textSelectionDrag.centroid.position
+ hold: !textSelectionDrag.active && !mouseClickHandler.pressed
+ focus: true
+ }
+
+ PinchHandler {
+ id: pinch
+ minimumScale: paper.minScale / root.renderScale
+ maximumScale: Math.max(1, paper.maxScale / root.renderScale)
+ minimumRotation: 0
+ maximumRotation: 0
+ onActiveChanged:
+ if (!active) {
+ const centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
+ pinch.centroid.position.y / root.renderScale)
+ const centroidInFlickable = root.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
+ const newSourceWidth = image.sourceSize.width * paper.scale
+ const ratio = newSourceWidth / image.sourceSize.width
+ console.log(lcSPV, "pinch ended with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
+ "page at", paper.x.toFixed(2), paper.y.toFixed(2),
+ "contentX/Y were", root.contentX.toFixed(2), root.contentY.toFixed(2))
+ if (ratio > 1.1 || ratio < 0.9) {
+ const centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
+ paper.scale = 1
+ paper.x = 0
+ paper.y = 0
+ root.contentX = centroidOnPage.x - centroidInFlickable.x
+ root.contentY = centroidOnPage.y - centroidInFlickable.y
+ root.renderScale *= ratio // onRenderScaleChanged calls pageNavigator.update() so we don't need to here
+ console.log(lcSPV, "contentX/Y adjusted to", root.contentX.toFixed(2), root.contentY.toFixed(2))
+ } else {
+ paper.x = 0
+ paper.y = 0
+ }
+ }
+ grabPermissions: PointerHandler.CanTakeOverFromAnything
+ }
+ }
+}
diff --git a/src/pdfquick/PdfStyle.qml b/src/pdfquick/PdfStyle.qml
new file mode 100644
index 000000000..a22276143
--- /dev/null
+++ b/src/pdfquick/PdfStyle.qml
@@ -0,0 +1,71 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+import QtQuick
+
+/*!
+ \qmltype PdfStyle
+ \inqmlmodule QtQuick.Pdf
+ \brief A styling interface for the PDF viewer components.
+
+ PdfStyle provides properties to modify the appearance of PdfMultiPageView,
+ PdfScrollablePageView, and PdfPageView.
+
+ Default styles are provided to match the
+ \l {Styling Qt Quick Controls}{styles in Qt Quick Controls}.
+ \l {Using File Selectors with Qt Quick Controls}{File selectors}
+ are used to load the PDF style corresponding to the Controls style in use.
+ Custom styles are possible, using different \l {QFileSelector}{file selectors}.
+*/
+QtObject {
+ /*! \internal
+ \qmlproperty SystemPalette PdfStyle::palette
+ */
+ property SystemPalette palette: SystemPalette { }
+
+ /*! \internal
+ \qmlmethod color PdfStyle::withAlpha()
+ */
+ function withAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+ }
+
+ /*!
+ \qmlproperty color PdfStyle::selectionColor
+
+ The color of translucent rectangles that are overlaid on
+ \l {PdfMultiPageView::selectedText}{selected text}.
+
+ \sa PdfSelection
+ */
+ property color selectionColor: withAlpha(palette.highlight, 0.5)
+
+ /*!
+ \qmlproperty color PdfStyle::pageSearchResultsColor
+
+ The color of translucent rectangles that are overlaid on text that
+ matches the \l {PdfMultiPageView::searchString}{search string}.
+
+ \sa PdfSearchModel
+ */
+ property color pageSearchResultsColor: "#80B0C4DE"
+
+ /*!
+ \qmlproperty color PdfStyle::currentSearchResultStrokeColor
+
+ The color of the box outline around the
+ \l {PdfSearchModel::currentResult}{current search result}.
+
+ \sa PdfMultiPageView::searchBack(), PdfMultiPageView::searchForward(), PdfSearchModel::currentResult
+ */
+ property color currentSearchResultStrokeColor: "cyan"
+
+ /*!
+ \qmlproperty real PdfStyle::currentSearchResultStrokeWidth
+
+ The line width of the box outline around the
+ \l {PdfSearchModel::currentResult}{current search result}.
+
+ \sa PdfMultiPageView::searchBack(), PdfMultiPageView::searchForward(), PdfSearchModel::currentResult
+ */
+ property real currentSearchResultStrokeWidth: 2
+}
diff --git a/src/pdfquick/doc/src/qtquickpdf-module.qdoc b/src/pdfquick/doc/src/qtquickpdf-module.qdoc
new file mode 100644
index 000000000..a4ca0d9e8
--- /dev/null
+++ b/src/pdfquick/doc/src/qtquickpdf-module.qdoc
@@ -0,0 +1,18 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \qmlmodule QtQuick.Pdf
+ \title Qt Quick PDF QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for handling PDF documents.
+ \since 5.14
+
+ This QML module contains types for handling PDF documents.
+
+ To use the types in this module, import the module with the following line:
+
+ \qml
+ import QtQuick.Pdf
+ \endqml
+*/
diff --git a/src/pdfquick/plugin.cpp b/src/pdfquick/plugin.cpp
deleted file mode 100644
index 23f32bc39..000000000
--- a/src/pdfquick/plugin.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 <QtQml/qqml.h>
-#include <QtQml/qqmlcomponent.h>
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlextensionplugin.h>
-#include "qquickpdfdocument_p.h"
-#include "qquickpdflinkmodel_p.h"
-#include "qquickpdfnavigationstack_p.h"
-#include "qquickpdfsearchmodel_p.h"
-#include "qquickpdfselection_p.h"
-#include "qquicktableviewextra_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlmodule QtQuick.Pdf
- \title Qt Quick PDF QML Types
- \ingroup qmlmodules
- \brief Provides QML types for handling PDF documents.
-
- This QML module contains types for handling PDF documents.
-
- To use the types in this module, import the module with the following line:
-
- \code
- import QtQuick.Pdf
- \endcode
-*/
-
-class QtQuick2PdfPlugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
-
-public:
- QtQuick2PdfPlugin() : QQmlExtensionPlugin() { }
-
- void initializeEngine(QQmlEngine *engine, const char *uri) override {
- Q_UNUSED(uri);
-#ifdef QT_STATIC
- Q_UNUSED(engine);
-#else
- engine->addImportPath(QStringLiteral("qrc:/"));
-#endif
- }
-
- void registerTypes(const char *uri) override {
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Pdf"));
-
- // Register the latest version, even if there are no new types or new revisions for existing types yet.
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
-
- qmlRegisterType<QQuickPdfDocument>(uri, 5, 15, "PdfDocument");
- qmlRegisterType<QQuickPdfLinkModel>(uri, 5, 15, "PdfLinkModel");
- qmlRegisterType<QQuickPdfNavigationStack>(uri, 5, 15, "PdfNavigationStack");
- qmlRegisterType<QQuickPdfSearchModel>(uri, 5, 15, "PdfSearchModel");
- qmlRegisterType<QQuickPdfSelection>(uri, 5, 15, "PdfSelection");
- qmlRegisterType<QQuickTableViewExtra>(uri, 5, 15, "TableViewExtra");
- }
-};
-
-QT_END_NAMESPACE
-
-#include "plugin.moc"
diff --git a/src/pdfquick/plugins.qmltypes b/src/pdfquick/plugins.qmltypes
deleted file mode 100644
index a30361d33..000000000
--- a/src/pdfquick/plugins.qmltypes
+++ /dev/null
@@ -1,52 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Pdf 5.14'
-
-Module {
- dependencies: [
- "QtGraphicalEffects 1.12",
- "QtQuick 2.14",
- "QtQuick.Controls 2.14",
- "QtQuick.Controls.Fusion 2.14",
- "QtQuick.Controls.Fusion.impl 2.14",
- "QtQuick.Controls.Imagine 2.14",
- "QtQuick.Controls.Imagine.impl 2.14",
- "QtQuick.Controls.Material 2.14",
- "QtQuick.Controls.Material.impl 2.14",
- "QtQuick.Controls.Universal 2.14",
- "QtQuick.Controls.Universal.impl 2.12",
- "QtQuick.Controls.impl 2.14",
- "QtQuick.Shapes 1.14",
- "QtQuick.Templates 2.14",
- "QtQuick.Window 2.2"
- ]
- Component {
- name: "QQuickPdfDocument"
- prototype: "QObject"
- exports: ["QtQuick.Pdf/PdfDocument 5.14"]
- exportMetaObjectRevisions: [0]
- Property { name: "source"; type: "QUrl" }
- Property { name: "pageCount"; type: "int"; isReadonly: true }
- Property { name: "password"; type: "string" }
- Property { name: "status"; type: "QPdfDocument::Status"; isReadonly: true }
- Property { name: "title"; type: "string"; isReadonly: true }
- Property { name: "subject"; type: "string"; isReadonly: true }
- Property { name: "author"; type: "string"; isReadonly: true }
- Property { name: "keywords"; type: "string"; isReadonly: true }
- Property { name: "producer"; type: "string"; isReadonly: true }
- Property { name: "creator"; type: "string"; isReadonly: true }
- Property { name: "creationDate"; type: "QDateTime"; isReadonly: true }
- Property { name: "modificationDate"; type: "QDateTime"; isReadonly: true }
- Signal { name: "passwordRequired" }
- Signal { name: "metaDataLoaded" }
- Method {
- name: "pagePointSize"
- type: "QSizeF"
- Parameter { name: "page"; type: "int" }
- }
- }
-}
diff --git a/src/pdfquick/qml/+material/PdfStyle.qml b/src/pdfquick/qml/+material/PdfStyle.qml
deleted file mode 100644
index 12df30466..000000000
--- a/src/pdfquick/qml/+material/PdfStyle.qml
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-import QtQml 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Controls.Material 2.14
-import QtQuick.Shapes 1.14
-
-QtObject {
- property Control prototypeControl: Control { }
- function withAlpha(color, alpha) {
- return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
- }
- property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
- property color pageSearchResultsColor: withAlpha(Qt.lighter(Material.accentColor, 1.5), 0.5)
- property color currentSearchResultStrokeColor: Material.accentColor
- property real currentSearchResultStrokeWidth: 2
- property color linkUnderscoreColor: prototypeControl.palette.link
- property real linkUnderscoreStrokeWidth: 1
- property var linkUnderscoreStrokeStyle: ShapePath.DashLine
- property var linkUnderscoreDashPattern: [ 1, 4 ]
-}
diff --git a/src/pdfquick/qml/+universal/PdfStyle.qml b/src/pdfquick/qml/+universal/PdfStyle.qml
deleted file mode 100644
index e92f2a080..000000000
--- a/src/pdfquick/qml/+universal/PdfStyle.qml
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-import QtQml 2.14
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Controls.Universal 2.14
-import QtQuick.Shapes 1.14
-
-QtObject {
- property Control prototypeControl: Control { }
- function withAlpha(color, alpha) {
- return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
- }
- property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
- property color pageSearchResultsColor: withAlpha(Qt.lighter(Universal.accent, 1.5), 0.5)
- property color currentSearchResultStrokeColor: Universal.accent
- property real currentSearchResultStrokeWidth: 2
- property color linkUnderscoreColor: prototypeControl.palette.link
- property real linkUnderscoreStrokeWidth: 1
- property var linkUnderscoreStrokeStyle: ShapePath.DashLine
- property var linkUnderscoreDashPattern: [ 1, 4 ]
-}
diff --git a/src/pdfquick/qml/PdfMultiPageView.qml b/src/pdfquick/qml/PdfMultiPageView.qml
deleted file mode 100644
index 71485c214..000000000
--- a/src/pdfquick/qml/PdfMultiPageView.qml
+++ /dev/null
@@ -1,434 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Layouts 1.14
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import QtQuick.Window 2.14
-
-Item {
- // public API
- // TODO 5.15: required property
- property var document: undefined
- property bool debug: false
-
- property string selectedText
- function selectAll() {
- var currentItem = tableHelper.itemAtCell(tableHelper.cellAtPos(root.width / 2, root.height / 2))
- if (currentItem)
- currentItem.selection.selectAll()
- }
- function copySelectionToClipboard() {
- var currentItem = tableHelper.itemAtCell(tableHelper.cellAtPos(root.width / 2, root.height / 2))
- if (debug)
- console.log("currentItem", currentItem, "sel", currentItem.selection.text)
- if (currentItem)
- currentItem.selection.copyToClipboard()
- }
-
- // page navigation
- property alias currentPage: navigationStack.currentPage
- property alias backEnabled: navigationStack.backAvailable
- property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- function goToPage(page) {
- if (page === navigationStack.currentPage)
- return
- goToLocation(page, Qt.point(-1, -1), 0)
- }
- function goToLocation(page, location, zoom) {
- if (zoom > 0) {
- navigationStack.jumping = true // don't call navigationStack.update() because we will push() instead
- root.renderScale = zoom
- tableView.forceLayout() // but do ensure that the table layout is correct before we try to jump
- navigationStack.jumping = false
- }
- navigationStack.push(page, location, zoom) // actually jump
- }
- property vector2d jumpLocationMargin: Qt.vector2d(10, 10) // px from top-left corner
- property int currentPageRenderingStatus: Image.Null
-
- // page scaling
- property real renderScale: 1
- property real pageRotation: 0
- function resetScale() { root.renderScale = 1 }
- function scaleToWidth(width, height) {
- root.renderScale = width / (tableView.rot90 ? tableView.firstPagePointSize.height : tableView.firstPagePointSize.width)
- }
- function scaleToPage(width, height) {
- var windowAspect = width / height
- var pageAspect = tableView.firstPagePointSize.width / tableView.firstPagePointSize.height
- if (tableView.rot90) {
- if (windowAspect > pageAspect) {
- root.renderScale = height / tableView.firstPagePointSize.width
- } else {
- root.renderScale = width / tableView.firstPagePointSize.height
- }
- } else {
- if (windowAspect > pageAspect) {
- root.renderScale = height / tableView.firstPagePointSize.height
- } else {
- root.renderScale = width / tableView.firstPagePointSize.width
- }
- }
- }
-
- // text search
- property alias searchModel: searchModel
- property alias searchString: searchModel.searchString
- function searchBack() { --searchModel.currentResult }
- function searchForward() { ++searchModel.currentResult }
-
- id: root
- PdfStyle { id: style }
- TableView {
- id: tableView
- anchors.fill: parent
- anchors.leftMargin: 2
- model: modelInUse && root.document !== undefined ? root.document.pageCount : 0
- // workaround to make TableView do scheduleRebuildTable(RebuildOption::All) in cases when forceLayout() doesn't
- property bool modelInUse: true
- function rebuild() {
- modelInUse = false
- modelInUse = true
- }
- // end workaround
- rowSpacing: 6
- property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360)
- property bool rot90: rotationNorm == 90 || rotationNorm == 270
- onRot90Changed: forceLayout()
- property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0)
- property real pageHolderWidth: Math.max(root.width, document === undefined ? 0 :
- (rot90 ? document.maxPageHeight : document.maxPageWidth) * root.renderScale)
- contentWidth: document === undefined ? 0 : pageHolderWidth + vscroll.width + 2
- rowHeightProvider: function(row) { return (rot90 ? document.pagePointSize(row).width : document.pagePointSize(row).height) * root.renderScale }
- TableViewExtra {
- id: tableHelper
- tableView: tableView
- }
- delegate: Rectangle {
- id: pageHolder
- color: root.debug ? "beige" : "transparent"
- Text {
- visible: root.debug
- anchors { right: parent.right; verticalCenter: parent.verticalCenter }
- rotation: -90; text: pageHolder.width.toFixed(1) + "x" + pageHolder.height.toFixed(1) + "\n" +
- image.width.toFixed(1) + "x" + image.height.toFixed(1)
- }
- implicitWidth: tableView.pageHolderWidth
- implicitHeight: tableView.rot90 ? image.width : image.height
- property alias selection: selection
- Rectangle {
- id: paper
- width: image.width
- height: image.height
- rotation: root.pageRotation
- anchors.centerIn: pinch.active ? undefined : parent
- property size pagePointSize: document.pagePointSize(index)
- property real pageScale: image.paintedWidth / pagePointSize.width
- Image {
- id: image
- source: document.source
- currentFrame: index
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- width: paper.pagePointSize.width * root.renderScale
- height: paper.pagePointSize.height * root.renderScale
- property real renderScale: root.renderScale
- property real oldRenderScale: 1
- onRenderScaleChanged: {
- image.sourceSize.width = paper.pagePointSize.width * renderScale
- image.sourceSize.height = 0
- paper.scale = 1
- searchHighlights.update()
- }
- onStatusChanged: {
- if (index === navigationStack.currentPage)
- root.currentPageRenderingStatus = status
- }
- }
- Shape {
- anchors.fill: parent
- visible: image.status === Image.Ready
- onVisibleChanged: searchHighlights.update()
- ShapePath {
- strokeWidth: -1
- fillColor: style.pageSearchResultsColor
- scale: Qt.size(paper.pageScale, paper.pageScale)
- PathMultiline {
- id: searchHighlights
- function update() {
- // paths could be a binding, but we need to be able to "kick" it sometimes
- paths = searchModel.boundingPolygonsOnPage(index)
- }
- }
- }
- Connections {
- target: searchModel
- // whenever the highlights on the _current_ page change, they actually need to change on _all_ pages
- // (usually because the search string has changed)
- function onCurrentPageBoundingPolygonsChanged() { searchHighlights.update() }
- }
- ShapePath {
- strokeWidth: -1
- fillColor: style.selectionColor
- scale: Qt.size(paper.pageScale, paper.pageScale)
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
- Shape {
- anchors.fill: parent
- visible: image.status === Image.Ready && searchModel.currentPage === index
- ShapePath {
- strokeWidth: style.currentSearchResultStrokeWidth
- strokeColor: style.currentSearchResultStrokeColor
- fillColor: "transparent"
- scale: Qt.size(paper.pageScale, paper.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- }
- PinchHandler {
- id: pinch
- minimumScale: 0.1
- maximumScale: root.renderScale < 4 ? 2 : 1
- minimumRotation: root.pageRotation
- maximumRotation: root.pageRotation
- enabled: image.sourceSize.width < 5000
- onActiveChanged:
- if (active) {
- paper.z = 10
- } else {
- paper.z = 0
- var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
- pinch.centroid.position.y / root.renderScale)
- var centroidInFlickable = tableView.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
- var newSourceWidth = image.sourceSize.width * paper.scale
- var ratio = newSourceWidth / image.sourceSize.width
- if (root.debug)
- console.log("pinch ended on page", index, "with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
- "page at", pageHolder.x.toFixed(2), pageHolder.y.toFixed(2),
- "contentX/Y were", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2))
- if (ratio > 1.1 || ratio < 0.9) {
- var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
- paper.scale = 1
- paper.x = 0
- paper.y = 0
- root.renderScale *= ratio
- tableView.forceLayout()
- if (tableView.rotationNorm == 0) {
- tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.x - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.y - centroidInFlickable.y
- } else if (tableView.rotationNorm == 90) {
- tableView.contentX = pageHolder.x + tableView.originX + image.height - centroidOnPage.y - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.x - centroidInFlickable.y
- } else if (tableView.rotationNorm == 180) {
- tableView.contentX = pageHolder.x + tableView.originX + image.width - centroidOnPage.x - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + image.height - centroidOnPage.y - centroidInFlickable.y
- } else if (tableView.rotationNorm == 270) {
- tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.y - centroidInFlickable.x
- tableView.contentY = pageHolder.y + tableView.originY + image.width - centroidOnPage.x - centroidInFlickable.y
- }
- if (root.debug)
- console.log("contentX/Y adjusted to", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2), "y @top", pageHolder.y)
- tableView.returnToBounds()
- }
- }
- grabPermissions: PointerHandler.CanTakeOverFromAnything
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- TapHandler {
- id: mouseClickHandler
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- }
- TapHandler {
- id: touchTapHandler
- acceptedDevices: PointerDevice.TouchScreen
- onTapped: {
- selection.clear()
- selection.forceActiveFocus()
- }
- }
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: image.currentFrame
- }
- delegate: Shape {
- x: rect.x * paper.pageScale
- y: rect.y * paper.pageScale
- width: rect.width * paper.pageScale
- height: rect.height * paper.pageScale
- visible: image.status === Image.Ready
- ShapePath {
- strokeWidth: style.linkUnderscoreStrokeWidth
- strokeColor: style.linkUnderscoreColor
- strokeStyle: style.linkUnderscoreStrokeStyle
- dashPattern: style.linkUnderscoreDashPattern
- startX: 0; startY: height
- PathLine { x: width; y: height }
- }
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- id: linkMA
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- hoverEnabled: true
- onClicked: {
- if (page >= 0)
- root.goToLocation(page, location, zoom)
- else
- Qt.openUrlExternally(url)
- }
- }
- ToolTip {
- visible: linkMA.containsMouse
- delay: 1000
- text: page >= 0 ?
- ("page " + (page + 1) +
- " location " + location.x.toFixed(1) + ", " + location.y.toFixed(1) +
- " zoom " + zoom) : url
- }
- }
- }
- PdfSelection {
- id: selection
- anchors.fill: parent
- document: root.document
- page: image.currentFrame
- renderScale: image.renderScale
- fromPoint: textSelectionDrag.centroid.pressPosition
- toPoint: textSelectionDrag.centroid.position
- hold: !textSelectionDrag.active && !mouseClickHandler.pressed
- onTextChanged: root.selectedText = text
- focus: true
- }
- }
- }
- ScrollBar.vertical: ScrollBar {
- id: vscroll
- property bool moved: false
- onPositionChanged: moved = true
- onActiveChanged: {
- var cell = tableHelper.cellAtPos(root.width / 2, root.height / 2)
- var currentItem = tableHelper.itemAtCell(cell)
- var currentLocation = Qt.point(0, 0)
- if (currentItem) { // maybe the delegate wasn't loaded yet
- currentLocation = Qt.point((tableView.contentX - currentItem.x + jumpLocationMargin.x) / root.renderScale,
- (tableView.contentY - currentItem.y + jumpLocationMargin.y) / root.renderScale)
- }
- if (active) {
- moved = false
- // emitJumped false to avoid interrupting a pinch if TableView thinks it should scroll at the same time
- navigationStack.push(cell.y, currentLocation, root.renderScale, false)
- } else if (moved) {
- navigationStack.update(cell.y, currentLocation, root.renderScale)
- }
- }
- }
- ScrollBar.horizontal: ScrollBar { }
- }
- onRenderScaleChanged: {
- // if navigationStack.jumped changes the scale, don't turn around and update the stack again;
- // and don't force layout either, because positionViewAtCell() will do that
- if (navigationStack.jumping)
- return
- // make TableView rebuild from scratch, because otherwise it doesn't know the delegates are changing size
- tableView.rebuild()
- var cell = tableHelper.cellAtPos(root.width / 2, root.height / 2)
- var currentItem = tableHelper.itemAtCell(cell)
- if (currentItem) {
- var currentLocation = Qt.point((tableView.contentX - currentItem.x + jumpLocationMargin.x) / root.renderScale,
- (tableView.contentY - currentItem.y + jumpLocationMargin.y) / root.renderScale)
- navigationStack.update(cell.y, currentLocation, renderScale)
- }
- }
- PdfNavigationStack {
- id: navigationStack
- property bool jumping: false
- property int previousPage: 0
- onJumped: {
- jumping = true
- root.renderScale = zoom
- if (location.y < 0) {
- // invalid to indicate that a specific location was not needed,
- // so attempt to position the new page just as the current page is
- var currentYOffset = 0
- var previousPageDelegate = tableHelper.itemAtCell(0, previousPage)
- if (previousPageDelegate)
- currentYOffset = tableView.contentY - previousPageDelegate.y
- tableHelper.positionViewAtRow(page, Qt.AlignTop, currentYOffset)
- if (root.debug) {
- console.log("going from page", previousPage, "to", page, "offset", currentYOffset,
- "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
- }
- } else {
- // jump to a page and position the given location relative to the top-left corner of the viewport
- var pageSize = root.document.pagePointSize(page)
- pageSize.width *= root.renderScale
- pageSize.height *= root.renderScale
- var xOffsetLimit = Math.max(0, pageSize.width - root.width) / 2
- var offset = Qt.point(Math.max(-xOffsetLimit, Math.min(xOffsetLimit,
- location.x * root.renderScale - jumpLocationMargin.x)),
- Math.max(0, location.y * root.renderScale - jumpLocationMargin.y))
- tableHelper.positionViewAtCell(0, page, Qt.AlignLeft | Qt.AlignTop, offset)
- if (root.debug) {
- console.log("going to zoom", zoom, "loc", location, "on page", page,
- "ended up @", tableView.contentX.toFixed(1) + ", " + tableView.contentY.toFixed(1))
- }
- }
- jumping = false
- previousPage = page
- }
- onCurrentPageChanged: searchModel.currentPage = currentPage
- }
- PdfSearchModel {
- id: searchModel
- document: root.document === undefined ? null : root.document
- // TODO maybe avoid jumping if the result is already fully visible in the viewport
- onCurrentResultBoundingRectChanged: root.goToLocation(currentPage,
- Qt.point(currentResultBoundingRect.x, currentResultBoundingRect.y), 0)
- }
-}
diff --git a/src/pdfquick/qml/PdfPageView.qml b/src/pdfquick/qml/PdfPageView.qml
deleted file mode 100644
index b90ad2d7f..000000000
--- a/src/pdfquick/qml/PdfPageView.qml
+++ /dev/null
@@ -1,276 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import Qt.labs.animation 1.0
-
-Rectangle {
- // public API
- // TODO 5.15: required property
- property var document: undefined
- property alias status: image.status
-
- property alias selectedText: selection.text
- function selectAll() {
- selection.selectAll()
- }
- function copySelectionToClipboard() {
- selection.copyToClipboard()
- }
-
- // page navigation
- property alias currentPage: navigationStack.currentPage
- property alias backEnabled: navigationStack.backAvailable
- property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- function goToPage(page) { goToLocation(page, Qt.point(0, 0), 0) }
- function goToLocation(page, location, zoom) {
- if (zoom > 0)
- root.renderScale = zoom
- navigationStack.push(page, location, zoom)
- }
-
- // page scaling
- property real renderScale: 1
- property alias sourceSize: image.sourceSize
- function resetScale() {
- image.sourceSize.width = 0
- image.sourceSize.height = 0
- root.x = 0
- root.y = 0
- root.scale = 1
- }
- function scaleToWidth(width, height) {
- var halfRotation = Math.abs(root.rotation % 180)
- image.sourceSize = Qt.size((halfRotation > 45 && halfRotation < 135) ? height : width, 0)
- root.x = 0
- root.y = 0
- image.centerInSize = Qt.size(width, height)
- image.centerOnLoad = true
- image.vCenterOnLoad = (halfRotation > 45 && halfRotation < 135)
- root.scale = 1
- }
- function scaleToPage(width, height) {
- var windowAspect = width / height
- var halfRotation = Math.abs(root.rotation % 180)
- var pagePointSize = document.pagePointSize(navigationStack.currentPage)
- if (halfRotation > 45 && halfRotation < 135) {
- // rotated 90 or 270º
- var pageAspect = pagePointSize.height / pagePointSize.width
- if (windowAspect > pageAspect) {
- image.sourceSize = Qt.size(height, 0)
- } else {
- image.sourceSize = Qt.size(0, width)
- }
- } else {
- var pageAspect = pagePointSize.width / pagePointSize.height
- if (windowAspect > pageAspect) {
- image.sourceSize = Qt.size(0, height)
- } else {
- image.sourceSize = Qt.size(width, 0)
- }
- }
- image.centerInSize = Qt.size(width, height)
- image.centerOnLoad = true
- image.vCenterOnLoad = true
- root.scale = 1
- }
-
- // text search
- property alias searchModel: searchModel
- property alias searchString: searchModel.searchString
- function searchBack() { --searchModel.currentResult }
- function searchForward() { ++searchModel.currentResult }
-
- // implementation
- id: root
- width: image.width
- height: image.height
-
- PdfSelection {
- id: selection
- document: root.document
- page: navigationStack.currentPage
- fromPoint: Qt.point(textSelectionDrag.centroid.pressPosition.x / image.pageScale, textSelectionDrag.centroid.pressPosition.y / image.pageScale)
- toPoint: Qt.point(textSelectionDrag.centroid.position.x / image.pageScale, textSelectionDrag.centroid.position.y / image.pageScale)
- hold: !textSelectionDrag.active && !tapHandler.pressed
- }
-
- PdfSearchModel {
- id: searchModel
- document: root.document === undefined ? null : root.document
- onCurrentPageChanged: root.goToPage(currentPage)
- }
-
- PdfNavigationStack {
- id: navigationStack
- onCurrentPageChanged: searchModel.currentPage = currentPage
- // TODO onCurrentLocationChanged: position currentLocation.x and .y in middle // currentPageChanged() MUST occur first!
- onCurrentZoomChanged: root.renderScale = currentZoom
- // TODO deal with horizontal location (need WheelHandler or Flickable probably)
- }
-
- Image {
- id: image
- currentFrame: navigationStack.currentPage
- source: document.status === PdfDocument.Ready ? document.source : ""
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- property bool centerOnLoad: false
- property bool vCenterOnLoad: false
- property size centerInSize
- property real pageScale: image.paintedWidth / document.pagePointSize(navigationStack.currentPage).width
- function reRenderIfNecessary() {
- var newSourceWidth = image.sourceSize.width * root.scale
- var ratio = newSourceWidth / image.sourceSize.width
- if (ratio > 1.1 || ratio < 0.9) {
- image.sourceSize.width = newSourceWidth
- image.sourceSize.height = 0
- root.scale = 1
- }
- }
- onStatusChanged:
- if (status == Image.Ready && centerOnLoad) {
- root.x = (centerInSize.width - image.implicitWidth) / 2
- root.y = vCenterOnLoad ? (centerInSize.height - image.implicitHeight) / 2 : 0
- centerOnLoad = false
- vCenterOnLoad = false
- }
- }
- onRenderScaleChanged: {
- image.sourceSize.width = document.pagePointSize(navigationStack.currentPage).width * renderScale
- image.sourceSize.height = 0
- root.scale = 1
- }
-
- Shape {
- anchors.fill: parent
- opacity: 0.25
- visible: image.status === Image.Ready
- ShapePath {
- strokeWidth: 1
- strokeColor: "cyan"
- fillColor: "steelblue"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentPageBoundingPolygons
- }
- }
- ShapePath {
- strokeWidth: 1
- strokeColor: "orange"
- fillColor: "cyan"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- ShapePath {
- fillColor: "orange"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
-
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: navigationStack.currentPage
- }
- delegate: Rectangle {
- color: "transparent"
- border.color: "lightgrey"
- x: rect.x * image.pageScale
- y: rect.y * image.pageScale
- width: rect.width * image.pageScale
- height: rect.height * image.pageScale
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (page >= 0)
- navigationStack.push(page, Qt.point(0, 0), root.renderScale)
- else
- Qt.openUrlExternally(url)
- }
- }
- }
- }
-
- PinchHandler {
- id: pinch
- minimumScale: 0.1
- maximumScale: 10
- minimumRotation: 0
- maximumRotation: 0
- onActiveChanged: if (!active) image.reRenderIfNecessary()
- grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started
- }
- DragHandler {
- id: pageMovingTouchDrag
- acceptedDevices: PointerDevice.TouchScreen
- }
- DragHandler {
- id: pageMovingMiddleMouseDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- acceptedButtons: Qt.MiddleButton
- snapMode: DragHandler.NoSnap
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- TapHandler {
- id: tapHandler
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- }
- // prevent it from being scrolled out of view
- BoundaryRule on x {
- minimum: 100 - root.width
- maximum: root.parent.width - 100
- }
- BoundaryRule on y {
- minimum: 100 - root.height
- maximum: root.parent.height - 100
- }
-}
diff --git a/src/pdfquick/qml/PdfScrollablePageView.qml b/src/pdfquick/qml/PdfScrollablePageView.qml
deleted file mode 100644
index 51d9e530d..000000000
--- a/src/pdfquick/qml/PdfScrollablePageView.qml
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import Qt.labs.animation 1.0
-
-Flickable {
- // public API
- // TODO 5.15: required property
- property var document: undefined
- property bool debug: false
- property alias status: image.status
-
- property alias selectedText: selection.text
- function selectAll() {
- selection.selectAll()
- }
- function copySelectionToClipboard() {
- selection.copyToClipboard()
- }
-
- // page navigation
- property alias currentPage: navigationStack.currentPage
- property alias backEnabled: navigationStack.backAvailable
- property alias forwardEnabled: navigationStack.forwardAvailable
- function back() { navigationStack.back() }
- function forward() { navigationStack.forward() }
- function goToPage(page) {
- if (page === navigationStack.currentPage)
- return
- goToLocation(page, Qt.point(0, 0), 0)
- }
- function goToLocation(page, location, zoom) {
- if (zoom > 0)
- root.renderScale = zoom
- navigationStack.push(page, location, zoom)
- }
-
- // page scaling
- property real renderScale: 1
- property real pageRotation: 0
- property alias sourceSize: image.sourceSize
- function resetScale() {
- paper.scale = 1
- root.renderScale = 1
- }
- function scaleToWidth(width, height) {
- var pagePointSize = document.pagePointSize(navigationStack.currentPage)
- root.renderScale = root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width)
- if (debug)
- console.log("scaling", pagePointSize, "to fit", root.width, "rotated?", paper.rot90, "scale", root.renderScale)
- root.contentX = 0
- root.contentY = 0
- }
- function scaleToPage(width, height) {
- var pagePointSize = document.pagePointSize(navigationStack.currentPage)
- root.renderScale = Math.min(
- root.width / (paper.rot90 ? pagePointSize.height : pagePointSize.width),
- root.height / (paper.rot90 ? pagePointSize.width : pagePointSize.height) )
- root.contentX = 0
- root.contentY = 0
- }
-
- // text search
- property alias searchModel: searchModel
- property alias searchString: searchModel.searchString
- function searchBack() { --searchModel.currentResult }
- function searchForward() { ++searchModel.currentResult }
-
- // implementation
- id: root
- PdfStyle { id: style }
- contentWidth: paper.width
- contentHeight: paper.height
- ScrollBar.vertical: ScrollBar {
- onActiveChanged:
- if (!active ) {
- var currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
- (root.contentY + root.height / 2) / root.renderScale)
- navigationStack.update(navigationStack.currentPage, currentLocation, root.renderScale)
- }
- }
- ScrollBar.horizontal: ScrollBar {
- onActiveChanged:
- if (!active ) {
- var currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
- (root.contentY + root.height / 2) / root.renderScale)
- navigationStack.update(navigationStack.currentPage, currentLocation, root.renderScale)
- }
- }
-
- onRenderScaleChanged: {
- image.sourceSize.width = document.pagePointSize(navigationStack.currentPage).width * renderScale
- image.sourceSize.height = 0
- paper.scale = 1
- var currentLocation = Qt.point((root.contentX + root.width / 2) / root.renderScale,
- (root.contentY + root.height / 2) / root.renderScale)
- navigationStack.update(navigationStack.currentPage, currentLocation, root.renderScale)
- }
-
- PdfSearchModel {
- id: searchModel
- document: root.document === undefined ? null : root.document
- // TODO maybe avoid jumping if the result is already fully visible in the viewport
- onCurrentResultBoundingRectChanged: root.goToLocation(currentPage,
- Qt.point(currentResultBoundingRect.x, currentResultBoundingRect.y), 0)
- }
-
- PdfNavigationStack {
- id: navigationStack
- onJumped: {
- root.renderScale = zoom
- var dx = Math.max(0, location.x * root.renderScale - root.width / 2) - root.contentX
- var dy = Math.max(0, location.y * root.renderScale - root.height / 2) - root.contentY
- // don't jump if location is in the viewport already, i.e. if the "error" between desired and actual contentX/Y is small
- if (Math.abs(dx) > root.width / 3)
- root.contentX += dx
- if (Math.abs(dy) > root.height / 3)
- root.contentY += dy
- if (root.debug) {
- console.log("going to zoom", zoom, "loc", location,
- "on page", page, "ended up @", root.contentX + ", " + root.contentY)
- }
- }
- onCurrentPageChanged: searchModel.currentPage = currentPage
- }
-
- Rectangle {
- id: paper
- width: rot90 ? image.height : image.width
- height: rot90 ? image.width : image.height
- property real rotationModulus: Math.abs(root.pageRotation % 180)
- property bool rot90: rotationModulus > 45 && rotationModulus < 135
-
- Image {
- id: image
- currentFrame: navigationStack.currentPage
- source: document.status === PdfDocument.Ready ? document.source : ""
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- rotation: root.pageRotation
- anchors.centerIn: parent
- property real pageScale: image.paintedWidth / document.pagePointSize(navigationStack.currentPage).width
-
- Shape {
- anchors.fill: parent
- visible: image.status === Image.Ready
- ShapePath {
- strokeWidth: -1
- fillColor: style.pageSearchResultsColor
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentPageBoundingPolygons
- }
- }
- ShapePath {
- strokeWidth: style.currentSearchResultStrokeWidth
- strokeColor: style.currentSearchResultStrokeColor
- fillColor: "transparent"
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: searchModel.currentResultBoundingPolygons
- }
- }
- ShapePath {
- fillColor: style.selectionColor
- scale: Qt.size(image.pageScale, image.pageScale)
- PathMultiline {
- paths: selection.geometry
- }
- }
- }
-
- Repeater {
- model: PdfLinkModel {
- id: linkModel
- document: root.document
- page: navigationStack.currentPage
- }
- delegate: Shape {
- x: rect.x * image.pageScale
- y: rect.y * image.pageScale
- width: rect.width * image.pageScale
- height: rect.height * image.pageScale
- ShapePath {
- strokeWidth: style.linkUnderscoreStrokeWidth
- strokeColor: style.linkUnderscoreColor
- strokeStyle: style.linkUnderscoreStrokeStyle
- dashPattern: style.linkUnderscoreDashPattern
- startX: 0; startY: height
- PathLine { x: width; y: height }
- }
- MouseArea { // TODO switch to TapHandler / HoverHandler in 5.15
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- if (page >= 0)
- navigationStack.push(page, Qt.point(0, 0), root.renderScale)
- else
- Qt.openUrlExternally(url)
- }
- }
- }
- }
- DragHandler {
- id: textSelectionDrag
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- target: null
- }
- TapHandler {
- id: mouseClickHandler
- acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
- }
- TapHandler {
- id: touchTapHandler
- acceptedDevices: PointerDevice.TouchScreen
- onTapped: {
- selection.clear()
- selection.focus = true
- }
- }
- }
-
- PdfSelection {
- id: selection
- anchors.fill: parent
- document: root.document
- page: navigationStack.currentPage
- renderScale: image.pageScale
- fromPoint: textSelectionDrag.centroid.pressPosition
- toPoint: textSelectionDrag.centroid.position
- hold: !textSelectionDrag.active && !mouseClickHandler.pressed
- focus: true
- }
-
- PinchHandler {
- id: pinch
- minimumScale: 0.1
- maximumScale: root.renderScale < 4 ? 2 : 1
- minimumRotation: 0
- maximumRotation: 0
- enabled: image.sourceSize.width < 5000
- onActiveChanged:
- if (!active) {
- var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
- pinch.centroid.position.y / root.renderScale)
- var centroidInFlickable = root.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
- var newSourceWidth = image.sourceSize.width * paper.scale
- var ratio = newSourceWidth / image.sourceSize.width
- if (root.debug)
- console.log("pinch ended with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
- "page at", paper.x.toFixed(2), paper.y.toFixed(2),
- "contentX/Y were", root.contentX.toFixed(2), root.contentY.toFixed(2))
- if (ratio > 1.1 || ratio < 0.9) {
- var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
- paper.scale = 1
- paper.x = 0
- paper.y = 0
- root.contentX = centroidOnPage.x - centroidInFlickable.x
- root.contentY = centroidOnPage.y - centroidInFlickable.y
- root.renderScale *= ratio // onRenderScaleChanged calls navigationStack.update() so we don't need to here
- if (root.debug)
- console.log("contentX/Y adjusted to", root.contentX.toFixed(2), root.contentY.toFixed(2))
- } else {
- paper.x = 0
- paper.y = 0
- }
- }
- grabPermissions: PointerHandler.CanTakeOverFromAnything
- }
- }
-}
diff --git a/src/pdfquick/qml/PdfStyle.qml b/src/pdfquick/qml/PdfStyle.qml
deleted file mode 100644
index 090465ce6..000000000
--- a/src/pdfquick/qml/PdfStyle.qml
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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$
-**
-****************************************************************************/
-import QtQml 2.14
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Shapes 1.14
-
-QtObject {
- property Control prototypeControl: Control { }
- function withAlpha(color, alpha) {
- return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
- }
- property color selectionColor: withAlpha(prototypeControl.palette.highlight, 0.5)
- property color pageSearchResultsColor: "#80B0C4DE"
- property color currentSearchResultStrokeColor: "cyan"
- property real currentSearchResultStrokeWidth: 2
- property color linkUnderscoreColor: prototypeControl.palette.link
- property real linkUnderscoreStrokeWidth: 1
- property var linkUnderscoreStrokeStyle: ShapePath.DashLine
- property var linkUnderscoreDashPattern: [ 1, 4 ]
-}
diff --git a/src/pdfquick/qquickpdfbookmarkmodel.cpp b/src/pdfquick/qquickpdfbookmarkmodel.cpp
new file mode 100644
index 000000000..81f8547ae
--- /dev/null
+++ b/src/pdfquick/qquickpdfbookmarkmodel.cpp
@@ -0,0 +1,55 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickpdfbookmarkmodel_p.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype PdfBookmarkModel
+//! \instantiates QQuickPdfBookmarkModel
+ \inqmlmodule QtQuick.Pdf
+ \ingroup pdf
+ \brief A tree of links (anchors) within a PDF document, such as the table of contents.
+ \since 6.4
+
+ A PDF document can contain a hierarchy of link destinations, usually
+ representing the table of contents, to be shown in a sidebar in a PDF
+ viewer, so that the user can quickly jump to those locations in the
+ document. This QAbstractItemModel holds the information in a form
+ suitable for display with TreeView, ListView, QTreeView or QListView.
+*/
+
+QQuickPdfBookmarkModel::QQuickPdfBookmarkModel(QObject *parent)
+ : QPdfBookmarkModel(parent)
+{
+}
+
+/*!
+ \internal
+*/
+QQuickPdfBookmarkModel::~QQuickPdfBookmarkModel() = default;
+
+/*!
+ \qmlproperty PdfDocument PdfBookmarkModel::document
+
+ This property holds the PDF document in which bookmarks are to be found.
+*/
+QQuickPdfDocument *QQuickPdfBookmarkModel::document() const
+{
+ return m_quickDocument;
+}
+
+void QQuickPdfBookmarkModel::setDocument(QQuickPdfDocument *document)
+{
+ if (document == m_quickDocument)
+ return;
+ m_quickDocument = document;
+ QPdfBookmarkModel::setDocument(document->document());
+ emit documentChanged();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickpdfbookmarkmodel_p.cpp"
diff --git a/src/pdfquick/qquickpdfbookmarkmodel_p.h b/src/pdfquick/qquickpdfbookmarkmodel_p.h
new file mode 100644
index 000000000..1276be058
--- /dev/null
+++ b/src/pdfquick/qquickpdfbookmarkmodel_p.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKPDFBOOKMARKMODEL_P_H
+#define QQUICKPDFBOOKMARKMODEL_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 <QtPdfQuick/private/qtpdfquickglobal_p.h>
+#include <QtPdfQuick/private/qquickpdfdocument_p.h>
+#include <QtPdf/qpdfbookmarkmodel.h>
+
+#include <QQmlEngine>
+
+QT_BEGIN_NAMESPACE
+
+class Q_PDFQUICK_EXPORT QQuickPdfBookmarkModel : public QPdfBookmarkModel
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
+ QML_NAMED_ELEMENT(PdfBookmarkModel)
+ QML_ADDED_IN_VERSION(6, 4)
+
+public:
+ explicit QQuickPdfBookmarkModel(QObject *parent = nullptr);
+ ~QQuickPdfBookmarkModel() override;
+
+ QQuickPdfDocument *document() const;
+ void setDocument(QQuickPdfDocument *document);
+
+Q_SIGNALS:
+ void documentChanged();
+
+private:
+ QQuickPdfDocument *m_quickDocument;
+
+ Q_DISABLE_COPY(QQuickPdfBookmarkModel)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPdfBookmarkModel)
+
+#endif // QQUICKPDFBOOKMARKMODEL_P_H
diff --git a/src/pdfquick/qquickpdfdocument.cpp b/src/pdfquick/qquickpdfdocument.cpp
index 2f5360f37..9770900db 100644
--- a/src/pdfquick/qquickpdfdocument.cpp
+++ b/src/pdfquick/qquickpdfdocument.cpp
@@ -1,43 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickpdfdocument_p.h"
-#include <QQuickItem>
-#include <QQmlEngine>
-#include <QStandardPaths>
+#include <private/qpdffile_p.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQml/qqmlfile.h>
QT_BEGIN_NAMESPACE
@@ -60,20 +31,31 @@ QT_BEGIN_NAMESPACE
QQuickPdfDocument::QQuickPdfDocument(QObject *parent)
: QObject(parent)
{
- connect(&m_doc, &QPdfDocument::passwordChanged, this, &QQuickPdfDocument::passwordChanged);
- connect(&m_doc, &QPdfDocument::passwordRequired, this, &QQuickPdfDocument::passwordRequired);
- connect(&m_doc, &QPdfDocument::statusChanged, [this] (QPdfDocument::Status status) {
- emit statusChanged();
- if (status == QPdfDocument::Ready)
- emit metaDataChanged();
- });
- connect(&m_doc, &QPdfDocument::pageCountChanged, this, &QQuickPdfDocument::pageCountChanged);
}
-void QQuickPdfDocument::componentComplete()
+/*!
+ \internal
+*/
+QQuickPdfDocument::~QQuickPdfDocument()
{
- if (m_doc.error() == QPdfDocument::IncorrectPasswordError)
- emit passwordRequired();
+ delete m_carrierFile;
+};
+
+void QQuickPdfDocument::classBegin()
+{
+ m_doc = static_cast<QPdfDocument *>(qmlExtendedObject(this));
+ Q_ASSERT(m_doc);
+ connect(m_doc, &QPdfDocument::passwordChanged, this, [this]() -> void {
+ if (resolvedSource().isValid())
+ m_doc->load(QQmlFile::urlToLocalFileOrQrc(resolvedSource()));
+ });
+ connect(m_doc, &QPdfDocument::statusChanged, this, [this] (QPdfDocument::Status status) {
+ emit errorChanged();
+ if (status == QPdfDocument::Status::Ready)
+ emit metaDataChanged();
+ });
+ if (m_doc->error() == QPdfDocument::Error::IncorrectPassword)
+ emit m_doc->passwordRequired();
}
/*!
@@ -90,11 +72,14 @@ void QQuickPdfDocument::setSource(QUrl source)
m_source = source;
m_maxPageWidthHeight = QSizeF();
+ if (m_carrierFile)
+ m_carrierFile->deleteLater();
+ m_carrierFile = nullptr;
emit sourceChanged();
- if (source.scheme() == QLatin1String("qrc"))
- m_doc.load(QLatin1Char(':') + source.path());
- else
- m_doc.load(source.toLocalFile());
+ const QQmlContext *context = qmlContext(this);
+ m_resolvedSource = context ? context->resolvedUrl(source) : source;
+ if (m_resolvedSource.isValid())
+ m_doc->load(QQmlFile::urlToLocalFileOrQrc(m_resolvedSource));
}
/*!
@@ -107,25 +92,25 @@ void QQuickPdfDocument::setSource(QUrl source)
*/
QString QQuickPdfDocument::error() const
{
- switch (m_doc.error()) {
- case QPdfDocument::NoError:
+ switch (m_doc->error()) {
+ case QPdfDocument::Error::None:
return tr("no error");
break;
- case QPdfDocument::UnknownError:
+ case QPdfDocument::Error::Unknown:
break;
- case QPdfDocument::DataNotYetAvailableError:
+ case QPdfDocument::Error::DataNotYetAvailable:
return tr("data not yet available");
break;
- case QPdfDocument::FileNotFoundError:
+ case QPdfDocument::Error::FileNotFound:
return tr("file not found");
break;
- case QPdfDocument::InvalidFileFormatError:
+ case QPdfDocument::Error::InvalidFileFormat:
return tr("invalid file format");
break;
- case QPdfDocument::IncorrectPasswordError:
+ case QPdfDocument::Error::IncorrectPassword:
return tr("incorrect password");
break;
- case QPdfDocument::UnsupportedSecuritySchemeError:
+ case QPdfDocument::Error::UnsupportedSecurityScheme:
return tr("unsupported security scheme");
break;
}
@@ -133,20 +118,12 @@ QString QQuickPdfDocument::error() const
}
/*!
- \qmlproperty bool PdfDocument::password
+ \qmlproperty string PdfDocument::password
This property holds the document password. If the passwordRequired()
signal is emitted, the UI should prompt the user and then set this
property so that document opening can continue.
*/
-void QQuickPdfDocument::setPassword(const QString &password)
-{
- if (m_doc.password() == password)
- return;
- m_doc.setPassword(password);
- if (source().isValid() && source().isLocalFile())
- m_doc.load(source().path());
-}
/*!
\qmlproperty int PdfDocument::pageCount
@@ -167,58 +144,45 @@ void QQuickPdfDocument::setPassword(const QString &password)
Returns the size of the given \a page in points.
*/
-QSizeF QQuickPdfDocument::pagePointSize(int page) const
-{
- return m_doc.pageSize(page);
-}
qreal QQuickPdfDocument::maxPageWidth() const
{
- const_cast<QQuickPdfDocument *>(this)->updateMaxPageSize();
+ updateMaxPageSize();
return m_maxPageWidthHeight.width();
}
qreal QQuickPdfDocument::maxPageHeight() const
{
- const_cast<QQuickPdfDocument *>(this)->updateMaxPageSize();
+ updateMaxPageSize();
return m_maxPageWidthHeight.height();
}
+QPdfDocument *QQuickPdfDocument::document() const
+{
+ return m_doc;
+}
+
/*!
\internal
- \qmlmethod size PdfDocument::heightSumBeforePage(int page)
-
- Returns the sum of the heights, in points, of all sets of \a facingPages
- pages from 0 to the given \a page, exclusive.
-
- That is, if the pages were laid out end-to-end in adjacent sets of
- \a facingPages, what would be the distance in points from the top of the
- first page to the top of the given page.
+ Returns a QPdfFile instance that can carry this document down into
+ QPdfIOHandler::load(QIODevice *). It should not be used for other purposes.
*/
-// Workaround for lack of something analogous to ListView.positionViewAtIndex() in TableView
-qreal QQuickPdfDocument::heightSumBeforePage(int page, qreal spacing, int facingPages) const
+QPdfFile *QQuickPdfDocument::carrierFile()
{
- qreal ret = 0;
- for (int i = 0; i < page; i+= facingPages) {
- if (i + facingPages > page)
- break;
- qreal facingPagesHeight = 0;
- for (int j = i; j < i + facingPages; ++j)
- facingPagesHeight = qMax(facingPagesHeight, pagePointSize(j).height());
- ret += facingPagesHeight + spacing;
- }
- return ret;
+ if (!m_carrierFile)
+ m_carrierFile = new QPdfFile(m_doc);
+ return m_carrierFile;
}
-void QQuickPdfDocument::updateMaxPageSize()
+void QQuickPdfDocument::updateMaxPageSize() const
{
if (m_maxPageWidthHeight.isValid())
return;
qreal w = 0;
qreal h = 0;
- const int count = pageCount();
+ const int count = m_doc->pageCount();
for (int i = 0; i < count; ++i) {
- auto size = pagePointSize(i);
+ auto size = m_doc->pagePointSize(i);
w = qMax(w, size.width());
h = qMax(w, size.height());
}
@@ -277,13 +241,13 @@ void QQuickPdfDocument::updateMaxPageSize()
*/
/*!
- \qmlproperty string PdfDocument::creationDate
+ \qmlproperty date PdfDocument::creationDate
This property holds the date and time the document was created.
*/
/*!
- \qmlproperty string PdfDocument::modificationDate
+ \qmlproperty date PdfDocument::modificationDate
This property holds the date and time the document was most recently
modified.
@@ -303,3 +267,5 @@ void QQuickPdfDocument::updateMaxPageSize()
*/
QT_END_NAMESPACE
+
+#include "moc_qquickpdfdocument_p.cpp"
diff --git a/src/pdfquick/qquickpdfdocument_p.h b/src/pdfquick/qquickpdfdocument_p.h
index cfeeb7b98..95ded7f8b 100644
--- a/src/pdfquick/qquickpdfdocument_p.h
+++ b/src/pdfquick/qquickpdfdocument_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKPDFDOCUMENT_P_H
#define QQUICKPDFDOCUMENT_P_H
@@ -50,83 +17,83 @@
#include <QtPdfQuick/private/qtpdfquickglobal_p.h>
#include <QtPdf/QPdfDocument>
-#include <QDateTime>
-#include <QJSValue>
-#include <QQmlParserStatus>
-#include <QUrl>
-#include <QVariant>
+
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlParserStatus>
+#include <QtCore/QDateTime>
+#include <QtCore/QUrl>
QT_BEGIN_NAMESPACE
+class QPdfFile;
+
class Q_PDFQUICK_EXPORT QQuickPdfDocument : public QObject, public QQmlParserStatus
{
Q_OBJECT
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged FINAL)
- Q_PROPERTY(qreal maxPageWidth READ maxPageWidth NOTIFY metaDataChanged)
- Q_PROPERTY(qreal maxPageHeight READ maxPageHeight NOTIFY metaDataChanged)
- Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged FINAL)
- Q_PROPERTY(QPdfDocument::Status status READ status NOTIFY statusChanged FINAL)
- Q_PROPERTY(QString error READ error NOTIFY statusChanged FINAL)
-
- Q_PROPERTY(QString title READ title NOTIFY metaDataChanged)
- Q_PROPERTY(QString subject READ subject NOTIFY metaDataChanged)
- Q_PROPERTY(QString author READ author NOTIFY metaDataChanged)
- Q_PROPERTY(QString keywords READ keywords NOTIFY metaDataChanged)
- Q_PROPERTY(QString producer READ producer NOTIFY metaDataChanged)
- Q_PROPERTY(QString creator READ creator NOTIFY metaDataChanged)
- Q_PROPERTY(QDateTime creationDate READ creationDate NOTIFY metaDataChanged)
- Q_PROPERTY(QDateTime modificationDate READ modificationDate NOTIFY metaDataChanged)
+ Q_INTERFACES(QQmlParserStatus)
+
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged FINAL)
+ Q_PROPERTY(qreal maxPageWidth READ maxPageWidth NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(qreal maxPageHeight READ maxPageHeight NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QString error READ error NOTIFY errorChanged FINAL)
+
+ Q_PROPERTY(QString title READ title NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QString subject READ subject NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QString author READ author NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QString keywords READ keywords NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QString producer READ producer NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QString creator READ creator NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QDateTime creationDate READ creationDate NOTIFY metaDataChanged FINAL)
+ Q_PROPERTY(QDateTime modificationDate READ modificationDate NOTIFY metaDataChanged FINAL)
+ QML_NAMED_ELEMENT(PdfDocument)
+ QML_EXTENDED(QPdfDocument)
+ QML_ADDED_IN_VERSION(5, 15)
public:
explicit QQuickPdfDocument(QObject *parent = nullptr);
+ ~QQuickPdfDocument() override;
- void classBegin() override {}
- void componentComplete() override;
+ void classBegin() override;
+ void componentComplete() override {}
QUrl source() const { return m_source; }
void setSource(QUrl source);
-
- int pageCount() const { return m_doc.pageCount(); }
- QPdfDocument::Status status() const { return m_doc.status(); }
+ QUrl resolvedSource() const { return m_resolvedSource; }
QString error() const;
- QString password() const { return m_doc.password(); }
- void setPassword(const QString &password);
-
- QString title() { return m_doc.metaData(QPdfDocument::Title).toString(); }
- QString author() { return m_doc.metaData(QPdfDocument::Author).toString(); }
- QString subject() { return m_doc.metaData(QPdfDocument::Subject).toString(); }
- QString keywords() { return m_doc.metaData(QPdfDocument::Keywords).toString(); }
- QString producer() { return m_doc.metaData(QPdfDocument::Producer).toString(); }
- QString creator() { return m_doc.metaData(QPdfDocument::Creator).toString(); }
- QDateTime creationDate() { return m_doc.metaData(QPdfDocument::CreationDate).toDateTime(); }
- QDateTime modificationDate() { return m_doc.metaData(QPdfDocument::ModificationDate).toDateTime(); }
+ QString title() { return m_doc->metaData(QPdfDocument::MetaDataField::Title).toString(); }
+ QString author() { return m_doc->metaData(QPdfDocument::MetaDataField::Author).toString(); }
+ QString subject() { return m_doc->metaData(QPdfDocument::MetaDataField::Subject).toString(); }
+ QString keywords() { return m_doc->metaData(QPdfDocument::MetaDataField::Keywords).toString(); }
+ QString producer() { return m_doc->metaData(QPdfDocument::MetaDataField::Producer).toString(); }
+ QString creator() { return m_doc->metaData(QPdfDocument::MetaDataField::Creator).toString(); }
+ QDateTime creationDate() { return m_doc->metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(); }
+ QDateTime modificationDate() { return m_doc->metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(); }
- Q_INVOKABLE QSizeF pagePointSize(int page) const;
qreal maxPageWidth() const;
qreal maxPageHeight() const;
- Q_INVOKABLE qreal heightSumBeforePage(int page, qreal spacing = 0, int facingPages = 1) const;
Q_SIGNALS:
void sourceChanged();
- void passwordChanged();
- void passwordRequired();
- void statusChanged();
- void pageCountChanged();
+ void errorChanged();
void metaDataChanged();
private:
- QPdfDocument &document() { return m_doc; }
- void updateMaxPageSize();
+ QPdfDocument *document() const;
+ QPdfFile *carrierFile();
+ void updateMaxPageSize() const;
private:
QUrl m_source;
- QPdfDocument m_doc;
- QSizeF m_maxPageWidthHeight;
+ QUrl m_resolvedSource;
+ QPdfDocument *m_doc = nullptr;
+ QPdfFile *m_carrierFile = nullptr;
+ mutable QSizeF m_maxPageWidthHeight;
+ friend class QQuickPdfBookmarkModel;
friend class QQuickPdfLinkModel;
+ friend class QQuickPdfPageImage;
friend class QQuickPdfSearchModel;
friend class QQuickPdfSelection;
diff --git a/src/pdfquick/qquickpdflinkmodel.cpp b/src/pdfquick/qquickpdflinkmodel.cpp
index 68a05663d..469d13faf 100644
--- a/src/pdfquick/qquickpdflinkmodel.cpp
+++ b/src/pdfquick/qquickpdflinkmodel.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickpdflinkmodel_p.h"
#include <QQuickItem>
@@ -54,7 +21,7 @@ QT_BEGIN_NAMESPACE
The available model roles are:
- \value rect
+ \value rectangle
Bounding rectangle around the link.
\value url
If the link is a web link, the URL for that; otherwise an empty URL.
@@ -75,12 +42,15 @@ QT_BEGIN_NAMESPACE
page: image.currentFrame
}
delegate: Rectangle {
+ required property rect rectangle
+ required property url url
+ required property int page
color: "transparent"
border.color: "lightgrey"
- x: rect.x
- y: rect.y
- width: rect.width
- height: rect.height
+ x: rectangle.x
+ y: rectangle.y
+ width: rectangle.width
+ height: rectangle.height
HoverHandler { cursorShape: Qt.PointingHandCursor }
TapHandler {
onTapped: {
@@ -105,6 +75,11 @@ QQuickPdfLinkModel::QQuickPdfLinkModel(QObject *parent)
}
/*!
+ \internal
+*/
+QQuickPdfLinkModel::~QQuickPdfLinkModel() = default;
+
+/*!
\qmlproperty PdfDocument PdfLinkModel::document
This property holds the PDF document in which links are to be found.
@@ -119,7 +94,8 @@ void QQuickPdfLinkModel::setDocument(QQuickPdfDocument *document)
if (document == m_quickDocument)
return;
m_quickDocument = document;
- QPdfLinkModel::setDocument(&document->m_doc);
+ if (document)
+ QPdfLinkModel::setDocument(document->document());
}
/*!
@@ -129,3 +105,5 @@ void QQuickPdfLinkModel::setDocument(QQuickPdfDocument *document)
*/
QT_END_NAMESPACE
+
+#include "moc_qquickpdflinkmodel_p.cpp"
diff --git a/src/pdfquick/qquickpdflinkmodel_p.h b/src/pdfquick/qquickpdflinkmodel_p.h
index d777643ef..44314b2b1 100644
--- a/src/pdfquick/qquickpdflinkmodel_p.h
+++ b/src/pdfquick/qquickpdflinkmodel_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKPDFLINKMODEL_P_H
#define QQUICKPDFLINKMODEL_P_H
@@ -52,8 +19,7 @@
#include <QtPdfQuick/private/qquickpdfdocument_p.h>
#include <QtPdf/private/qpdflinkmodel_p.h>
-#include <QVariant>
-#include <QtQml/qqml.h>
+#include <QtQml/QQmlEngine>
QT_BEGIN_NAMESPACE
@@ -61,23 +27,18 @@ class Q_PDFQUICK_EXPORT QQuickPdfLinkModel : public QPdfLinkModel
{
Q_OBJECT
Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
+ QML_NAMED_ELEMENT(PdfLinkModel)
+ QML_ADDED_IN_VERSION(5, 15)
public:
explicit QQuickPdfLinkModel(QObject *parent = nullptr);
+ ~QQuickPdfLinkModel() override;
QQuickPdfDocument *document() const;
void setDocument(QQuickPdfDocument *document);
-signals:
- void documentChanged();
-
-private:
- void updateResults();
-
private:
QQuickPdfDocument *m_quickDocument;
- QList<QPolygonF> m_linksGeometry;
-
Q_DISABLE_COPY(QQuickPdfLinkModel)
};
diff --git a/src/pdfquick/qquickpdfnavigationstack.cpp b/src/pdfquick/qquickpdfnavigationstack.cpp
deleted file mode 100644
index b1554b989..000000000
--- a/src/pdfquick/qquickpdfnavigationstack.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "qquickpdfnavigationstack_p.h"
-#include <QLoggingCategory>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.navigationstack")
-
-/*!
- \qmltype PdfNavigationStack
-//! \instantiates QQuickPdfNavigationStack
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief History of the destinations visited within a PDF Document.
- \since 5.15
-
- PdfNavigationStack remembers which destinations the user has visited in a PDF
- document, and provides the ability to traverse backward and forward.
-*/
-
-QQuickPdfNavigationStack::QQuickPdfNavigationStack(QObject *parent)
- : QObject(parent)
-{
- push(0, QPointF(), 1);
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::forward()
-
- Goes back to the page, location and zoom level that was being viewed before
- back() was called, and then emits the \l jumped() signal.
-
- If a new destination was pushed since the last time \l back() was called,
- the forward() function does nothing, because there is a branch in the
- timeline which causes the "future" to be lost.
-*/
-void QQuickPdfNavigationStack::forward()
-{
- if (m_currentHistoryIndex >= m_pageHistory.count() - 1)
- return;
- bool backAvailableWas = backAvailable();
- bool forwardAvailableWas = forwardAvailable();
- QPointF currentLocationWas = currentLocation();
- qreal currentZoomWas = currentZoom();
- ++m_currentHistoryIndex;
- m_changing = true;
- emit jumped(currentPage(), currentLocation(), currentZoom());
- if (currentZoomWas != currentZoom())
- emit currentZoomChanged();
- emit currentPageChanged();
- if (currentLocationWas != currentLocation())
- emit currentLocationChanged();
- if (!backAvailableWas)
- emit backAvailableChanged();
- if (forwardAvailableWas != forwardAvailable())
- emit forwardAvailableChanged();
- m_changing = false;
- qCDebug(qLcNav) << "forward: index" << m_currentHistoryIndex << "page" << currentPage()
- << "@" << currentLocation() << "zoom" << currentZoom();
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::back()
-
- Pops the stack, updates the \l currentPage, \l currentLocation and
- \l currentZoom properties to the most-recently-viewed destination, and then
- emits the \l jumped() signal.
-*/
-void QQuickPdfNavigationStack::back()
-{
- if (m_currentHistoryIndex <= 0)
- return;
- bool backAvailableWas = backAvailable();
- bool forwardAvailableWas = forwardAvailable();
- QPointF currentLocationWas = currentLocation();
- qreal currentZoomWas = currentZoom();
- --m_currentHistoryIndex;
- m_changing = true;
- emit jumped(currentPage(), currentLocation(), currentZoom());
- if (currentZoomWas != currentZoom())
- emit currentZoomChanged();
- emit currentPageChanged();
- if (currentLocationWas != currentLocation())
- emit currentLocationChanged();
- if (backAvailableWas != backAvailable())
- emit backAvailableChanged();
- if (!forwardAvailableWas)
- emit forwardAvailableChanged();
- m_changing = false;
- qCDebug(qLcNav) << "back: index" << m_currentHistoryIndex << "page" << currentPage()
- << "@" << currentLocation() << "zoom" << currentZoom();
-}
-
-/*!
- \qmlproperty int PdfNavigationStack::currentPage
-
- This property holds the current page that is being viewed.
- If there is no current page, it holds \c -1.
-*/
-int QQuickPdfNavigationStack::currentPage() const
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return -1;
- return m_pageHistory.at(m_currentHistoryIndex)->page;
-}
-
-/*!
- \qmlproperty point PdfNavigationStack::currentLocation
-
- This property holds the current location on the page that is being viewed.
-*/
-QPointF QQuickPdfNavigationStack::currentLocation() const
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return QPointF();
- return m_pageHistory.at(m_currentHistoryIndex)->location;
-}
-
-/*!
- \qmlproperty real PdfNavigationStack::currentZoom
-
- This property holds the magnification scale on the page that is being viewed.
-*/
-qreal QQuickPdfNavigationStack::currentZoom() const
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return 1;
- return m_pageHistory.at(m_currentHistoryIndex)->zoom;
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::push(int page, point location, qreal zoom, bool emitJumped)
-
- Adds the given destination, consisting of \a page, \a location, and \a zoom,
- to the history of visited locations. If \a emitJumped is \c false, the
- \l jumped() signal will not be emitted.
-
- If forwardAvailable() is \c true, calling this function represents a branch
- in the timeline which causes the "future" to be lost, and therefore
- forwardAvailable will change to \c false.
-*/
-void QQuickPdfNavigationStack::push(int page, QPointF location, qreal zoom, bool emitJumped)
-{
- if (page == currentPage() && location == currentLocation() && zoom == currentZoom())
- return;
- if (qFuzzyIsNull(zoom))
- zoom = currentZoom();
- bool backAvailableWas = backAvailable();
- bool forwardAvailableWas = forwardAvailable();
- if (!m_changing) {
- if (m_currentHistoryIndex >= 0 && forwardAvailableWas)
- m_pageHistory.remove(m_currentHistoryIndex + 1, m_pageHistory.count() - m_currentHistoryIndex - 1);
- m_pageHistory.append(QExplicitlySharedDataPointer<QPdfDestinationPrivate>(new QPdfDestinationPrivate(page, location, zoom)));
- m_currentHistoryIndex = m_pageHistory.count() - 1;
- }
- emit currentZoomChanged();
- emit currentPageChanged();
- emit currentLocationChanged();
- if (m_changing)
- return;
- if (!backAvailableWas)
- emit backAvailableChanged();
- if (forwardAvailableWas)
- emit forwardAvailableChanged();
- if (emitJumped)
- emit jumped(page, location, zoom);
- qCDebug(qLcNav) << "push: index" << m_currentHistoryIndex << "page" << page
- << "@" << location << "zoom" << zoom << "-> history" <<
- [this]() {
- QStringList ret;
- for (auto d : m_pageHistory)
- ret << QString::number(d->page);
- return ret.join(QLatin1Char(','));
- }();
-}
-
-/*!
- \qmlmethod void PdfNavigationStack::update(int page, point location, qreal zoom)
-
- Modifies the current destination, consisting of \a page, \a location and \a zoom.
-
- This can be called periodically while the user is manually moving around
- the document, so that after back() is called, forward() will jump back to
- the most-recently-viewed destination rather than the destination that was
- last specified by push().
-
- The \c currentZoomChanged, \c currentPageChanged and \c currentLocationChanged
- signals will be emitted if the respective properties are actually changed.
- The \l jumped signal is not emitted, because this operation
- represents smooth movement rather than a navigational jump.
-*/
-void QQuickPdfNavigationStack::update(int page, QPointF location, qreal zoom)
-{
- if (m_currentHistoryIndex < 0 || m_currentHistoryIndex >= m_pageHistory.count())
- return;
- int currentPageWas = currentPage();
- QPointF currentLocationWas = currentLocation();
- qreal currentZoomWas = currentZoom();
- if (page == currentPageWas && location == currentLocationWas && zoom == currentZoomWas)
- return;
- m_pageHistory[m_currentHistoryIndex]->page = page;
- m_pageHistory[m_currentHistoryIndex]->location = location;
- m_pageHistory[m_currentHistoryIndex]->zoom = zoom;
- if (currentZoomWas != zoom)
- emit currentZoomChanged();
- if (currentPageWas != page)
- emit currentPageChanged();
- if (currentLocationWas != location)
- emit currentLocationChanged();
- qCDebug(qLcNav) << "update: index" << m_currentHistoryIndex << "page" << page
- << "@" << location << "zoom" << zoom << "-> history" <<
- [this]() {
- QStringList ret;
- for (auto d : m_pageHistory)
- ret << QString::number(d->page);
- return ret.join(QLatin1Char(','));
- }();
-}
-
-/*!
- \qmlproperty bool PdfNavigationStack::backAvailable
- \readonly
-
- Holds \c true if a \e back destination is available in the history.
-*/
-
-bool QQuickPdfNavigationStack::backAvailable() const
-{
- return m_currentHistoryIndex > 0;
-}
-
-/*!
- \qmlproperty bool PdfNavigationStack::forwardAvailable
- \readonly
-
- Holds \c true if a \e forward destination is available in the history.
-*/
-
-bool QQuickPdfNavigationStack::forwardAvailable() const
-{
- return m_currentHistoryIndex < m_pageHistory.count() - 1;
-}
-
-/*!
- \qmlsignal PdfNavigationStack::jumped(int page, point location, qreal zoom)
-
- This signal is emitted for the given \a page, \a location, and \a zoom,
- It is emitted on calling forward(), back(), or push() only.
-
- \note The signal is emitted on calling update().
-*/
-
-QT_END_NAMESPACE
diff --git a/src/pdfquick/qquickpdfnavigationstack_p.h b/src/pdfquick/qquickpdfnavigationstack_p.h
deleted file mode 100644
index 1d37a4a85..000000000
--- a/src/pdfquick/qquickpdfnavigationstack_p.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QQUICKPDFNAVIGATIONSTACK_P_H
-#define QQUICKPDFNAVIGATIONSTACK_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 <QtPdfQuick/private/qtpdfquickglobal_p.h>
-#include <QtPdfQuick/private/qquickpdfdocument_p.h>
-#include <QtPdf/private/qpdfdestination_p.h>
-
-#include <QtQml/qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_PDFQUICK_EXPORT QQuickPdfNavigationStack : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int currentPage READ currentPage NOTIFY currentPageChanged)
- Q_PROPERTY(QPointF currentLocation READ currentLocation NOTIFY currentLocationChanged)
- Q_PROPERTY(qreal currentZoom READ currentZoom NOTIFY currentZoomChanged)
- Q_PROPERTY(bool backAvailable READ backAvailable NOTIFY backAvailableChanged)
- Q_PROPERTY(bool forwardAvailable READ forwardAvailable NOTIFY forwardAvailableChanged)
-
-public:
- explicit QQuickPdfNavigationStack(QObject *parent = nullptr);
-
- Q_INVOKABLE void push(int page, QPointF location, qreal zoom, bool emitJumped = true);
- Q_INVOKABLE void update(int page, QPointF location, qreal zoom);
- Q_INVOKABLE void forward();
- Q_INVOKABLE void back();
-
- int currentPage() const;
- QPointF currentLocation() const;
- qreal currentZoom() const;
-
- bool backAvailable() const;
- bool forwardAvailable() const;
-
-Q_SIGNALS:
- void currentPageChanged();
- void currentLocationChanged();
- void currentZoomChanged();
- void backAvailableChanged();
- void forwardAvailableChanged();
- void jumped(int page, QPointF location, qreal zoom);
-
-private:
- QList<QExplicitlySharedDataPointer<QPdfDestinationPrivate>> m_pageHistory;
- int m_currentHistoryIndex = 0;
- bool m_changing = false;
-
- Q_DISABLE_COPY(QQuickPdfNavigationStack)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPdfNavigationStack)
-
-#endif // QQUICKPDFNAVIGATIONSTACK_P_H
diff --git a/src/pdfquick/qquickpdfpageimage.cpp b/src/pdfquick/qquickpdfpageimage.cpp
new file mode 100644
index 000000000..f2da067f1
--- /dev/null
+++ b/src/pdfquick/qquickpdfpageimage.cpp
@@ -0,0 +1,141 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickpdfpageimage_p.h"
+#include "qquickpdfdocument_p.h"
+#include <private/qpdffile_p.h>
+#include <QtQuick/private/qquickimage_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(qLcImg, "qt.pdf.image")
+
+/*!
+ \qmltype PdfPageImage
+//! \instantiates QQuickPdfPageImage
+ \inqmlmodule QtQuick.Pdf
+ \ingroup pdf
+ \inherits Image
+ \brief Displays one page from a PDF document.
+ \since 6.4
+
+ The PdfPageImage type is an Image specialized to render a page from a PDF document.
+*/
+
+class QQuickPdfPageImagePrivate: public QQuickImagePrivate
+{
+public:
+ QQuickPdfPageImagePrivate() : QQuickImagePrivate() {}
+
+ QQuickPdfDocument *doc = nullptr;
+};
+
+QQuickPdfPageImage::QQuickPdfPageImage(QQuickItem *parent)
+ : QQuickImage(*(new QQuickPdfPageImagePrivate), parent)
+{
+}
+
+/*!
+ \internal
+*/
+QQuickPdfPageImage::~QQuickPdfPageImage()
+{
+ Q_D(QQuickPdfPageImage);
+ // cancel any async rendering job that is running on my behalf
+ d->pix.clear();
+}
+
+/*!
+ \qmlproperty PdfDocument PdfPageImage::document
+
+ This property holds the PDF document from which to render an image.
+*/
+void QQuickPdfPageImage::setDocument(QQuickPdfDocument *document)
+{
+ Q_D(QQuickPdfPageImage);
+ if (d->doc == document)
+ return;
+
+ if (d->doc)
+ disconnect(d->doc->document(), &QPdfDocument::statusChanged, this, &QQuickPdfPageImage::documentStatusChanged);
+ d->doc = document;
+ if (document) {
+ connect(document->document(), &QPdfDocument::statusChanged, this, &QQuickPdfPageImage::documentStatusChanged);
+ if (document->document()->status() == QPdfDocument::Status::Ready)
+ setSource(document->resolvedSource()); // calls load()
+ }
+ emit documentChanged();
+}
+
+QQuickPdfDocument *QQuickPdfPageImage::document() const
+{
+ Q_D(const QQuickPdfPageImage);
+ return d->doc;
+}
+
+void QQuickPdfPageImage::load()
+{
+ Q_D(QQuickPdfPageImage);
+ QUrl url = source();
+ if (!d->doc || !d->doc->carrierFile()) {
+ if (!url.isEmpty()) {
+ qmlWarning(this) << "document property not set: falling back to inefficient loading of " << url;
+ QQuickImageBase::load();
+ }
+ return;
+ }
+ if (url != d->doc->resolvedSource()) {
+ url = d->doc->resolvedSource();
+ qmlWarning(this) << "document and source properties in conflict: preferring document source " << url;
+ }
+ auto carrierFile = d->doc->carrierFile();
+ static int thisRequestProgress = -1;
+ static int thisRequestFinished = -1;
+ if (thisRequestProgress == -1) {
+ thisRequestProgress =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
+ thisRequestFinished =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
+ }
+
+ d->pix.loadImageFromDevice(qmlEngine(this), carrierFile, url,
+ d->sourceClipRect.toRect(), d->sourcesize * d->devicePixelRatio,
+ QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
+
+ qCDebug(qLcImg) << "loading page" << d->currentFrame << "of" << d->frameCount
+ << "from" << carrierFile->fileName() << "status" << d->pix.status();
+
+ switch (d->pix.status()) {
+ case QQuickPixmap::Ready:
+ pixmapChange();
+ break;
+ case QQuickPixmap::Loading:
+ d->pix.connectFinished(this, thisRequestFinished);
+ d->pix.connectDownloadProgress(this, thisRequestProgress);
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (d->status != Loading) {
+ d->status = Loading;
+ emit statusChanged(d->status);
+ }
+ break;
+ default:
+ qCDebug(qLcImg) << "unexpected status" << d->pix.status();
+ break;
+ }
+}
+
+void QQuickPdfPageImage::documentStatusChanged()
+{
+ Q_D(QQuickPdfPageImage);
+ const auto status = d->doc->document()->status();
+ qCDebug(qLcImg) << "document status" << status;
+ if (status == QPdfDocument::Status::Ready)
+ setSource(d->doc->resolvedSource()); // calls load()
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickpdfpageimage_p.cpp"
diff --git a/src/pdfquick/qquickpdfpageimage_p.h b/src/pdfquick/qquickpdfpageimage_p.h
new file mode 100644
index 000000000..daff052ac
--- /dev/null
+++ b/src/pdfquick/qquickpdfpageimage_p.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKPDFPAGEIMAGE_P_H
+#define QQUICKPDFPAGEIMAGE_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 <QtPdfQuick/private/qtpdfquickglobal_p.h>
+#include <QtQuick/private/qquickimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPdfDocument;
+class QQuickPdfPageImagePrivate;
+class Q_PDFQUICK_EXPORT QQuickPdfPageImage : public QQuickImage
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged FINAL)
+ QML_NAMED_ELEMENT(PdfPageImage)
+ QML_ADDED_IN_VERSION(6, 4)
+
+public:
+ QQuickPdfPageImage(QQuickItem *parent = nullptr);
+ ~QQuickPdfPageImage() override;
+
+ void setDocument(QQuickPdfDocument *document);
+ QQuickPdfDocument *document() const;
+
+signals:
+ void documentChanged();
+
+protected:
+ void load() override;
+ void documentStatusChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QQuickPdfPageImage)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPDFPAGEIMAGE_P_H
diff --git a/src/pdfquick/qquickpdfpagenavigator.cpp b/src/pdfquick/qquickpdfpagenavigator.cpp
new file mode 100644
index 000000000..939d928e9
--- /dev/null
+++ b/src/pdfquick/qquickpdfpagenavigator.cpp
@@ -0,0 +1,130 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickpdfpagenavigator_p.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype PdfPageNavigator
+//! \instantiates QQuickPdfPageNavigator
+ \inqmlmodule QtQuick.Pdf
+ \ingroup pdf
+ \brief History of the destinations visited within a PDF Document.
+ \since 5.15
+
+ PdfPageNavigator remembers which destinations the user has visited in a PDF
+ document, and provides the ability to traverse backward and forward.
+*/
+
+QQuickPdfPageNavigator::QQuickPdfPageNavigator(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ \internal
+*/
+QQuickPdfPageNavigator::~QQuickPdfPageNavigator() = default;
+
+/*!
+ \internal
+*/
+QPdfPageNavigator *QQuickPdfPageNavigator::navStack()
+{
+ return static_cast<QPdfPageNavigator *>(qmlExtendedObject(this));
+}
+
+/*!
+ \qmlmethod void PdfPageNavigator::forward()
+
+ Goes back to the page, location and zoom level that was being viewed before
+ back() was called, and then emits the \l jumped() signal.
+
+ If a new destination was pushed since the last time \l back() was called,
+ the forward() function does nothing, because there is a branch in the
+ timeline which causes the "future" to be lost.
+*/
+
+/*!
+ \qmlmethod void PdfPageNavigator::back()
+
+ Pops the stack, updates the \l currentPage, \l currentLocation and
+ \l currentZoom properties to the most-recently-viewed destination, and then
+ emits the \l jumped() signal.
+*/
+
+/*!
+ \qmlproperty int PdfPageNavigator::currentPage
+
+ This property holds the current page that is being viewed.
+ If there is no current page, it holds \c -1.
+*/
+
+/*!
+ \qmlproperty point PdfPageNavigator::currentLocation
+
+ This property holds the current location on the page that is being viewed.
+*/
+
+/*!
+ \qmlproperty real PdfPageNavigator::currentZoom
+
+ This property holds the magnification scale on the page that is being viewed.
+*/
+
+/*!
+ \qmlmethod void PdfPageNavigator::jump(int page, point location, qreal zoom, bool emitJumped)
+
+ Adds the given destination, consisting of \a page, \a location, and \a zoom,
+ to the history of visited locations. If \a emitJumped is \c false, the
+ \l jumped() signal will not be emitted.
+
+ If forwardAvailable is \c true, calling this function represents a branch
+ in the timeline which causes the "future" to be lost, and therefore
+ forwardAvailable will change to \c false.
+*/
+
+/*!
+ \qmlmethod void PdfPageNavigator::update(int page, point location, qreal zoom)
+
+ Modifies the current destination, consisting of \a page, \a location and \a zoom.
+
+ This can be called periodically while the user is manually moving around
+ the document, so that after back() is called, forward() will jump back to
+ the most-recently-viewed destination rather than the destination that was
+ last specified by jump().
+
+ The \c currentZoomChanged, \c currentPageChanged and \c currentLocationChanged
+ signals will be emitted if the respective properties are actually changed.
+ The \l jumped signal is not emitted, because this operation
+ represents smooth movement rather than a navigational jump.
+*/
+
+/*!
+ \qmlproperty bool PdfPageNavigator::backAvailable
+ \readonly
+
+ Holds \c true if a \e back destination is available in the history.
+*/
+
+/*!
+ \qmlproperty bool PdfPageNavigator::forwardAvailable
+ \readonly
+
+ Holds \c true if a \e forward destination is available in the history.
+*/
+
+/*!
+ \qmlsignal PdfPageNavigator::jumped(int page, point location, qreal zoom)
+
+ This signal is emitted when an abrupt jump occurs, to the specified \a page
+ index, \a location on the page, and \a zoom level; but \e not when simply
+ scrolling through the document one page at a time. That is, forward(),
+ back() and jump() always emit this signal; update() does not.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qquickpdfpagenavigator_p.cpp"
diff --git a/src/pdfquick/qquickpdfpagenavigator_p.h b/src/pdfquick/qquickpdfpagenavigator_p.h
new file mode 100644
index 000000000..2a2d92d6b
--- /dev/null
+++ b/src/pdfquick/qquickpdfpagenavigator_p.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKPDFPAGENAVIGATOR_P_H
+#define QQUICKPDFPAGENAVIGATOR_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 <QtPdfQuick/private/qtpdfquickglobal_p.h>
+#include <QtPdf/qpdfpagenavigator.h>
+#include <QtPdf/private/qpdflink_p.h>
+
+#include <QQmlEngine>
+
+QT_BEGIN_NAMESPACE
+
+struct Q_PDFQUICK_EXPORT QPdfLinkForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QPdfLink)
+ QML_VALUE_TYPE(pdfLink)
+ QML_ADDED_IN_VERSION(6, 4)
+};
+
+class Q_PDFQUICK_EXPORT QQuickPdfPageNavigator : public QObject
+{
+ Q_OBJECT
+ QML_EXTENDED(QPdfPageNavigator)
+ QML_NAMED_ELEMENT(PdfPageNavigator)
+ QML_ADDED_IN_VERSION(5, 15)
+
+public:
+ explicit QQuickPdfPageNavigator(QObject *parent = nullptr);
+ ~QQuickPdfPageNavigator() override;
+
+private:
+ QPdfPageNavigator *navStack();
+
+ Q_DISABLE_COPY(QQuickPdfPageNavigator)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPdfPageNavigator)
+
+#endif // QQUICKPDFPAGENAVIGATOR_P_H
diff --git a/src/pdfquick/qquickpdfsearchmodel.cpp b/src/pdfquick/qquickpdfsearchmodel.cpp
index 85003cd0d..896584ad7 100644
--- a/src/pdfquick/qquickpdfsearchmodel.cpp
+++ b/src/pdfquick/qquickpdfsearchmodel.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickpdfsearchmodel_p.h"
#include <QtCore/qloggingcategory.h>
@@ -60,6 +27,11 @@ QQuickPdfSearchModel::QQuickPdfSearchModel(QObject *parent)
this, &QQuickPdfSearchModel::onResultsChanged);
}
+/*!
+ \internal
+*/
+QQuickPdfSearchModel::~QQuickPdfSearchModel() = default;
+
QQuickPdfDocument *QQuickPdfSearchModel::document() const
{
return m_quickDocument;
@@ -71,7 +43,7 @@ void QQuickPdfSearchModel::setDocument(QQuickPdfDocument *document)
return;
m_quickDocument = document;
- QPdfSearchModel::setDocument(&document->m_doc);
+ QPdfSearchModel::setDocument(document->document());
}
/*!
@@ -102,15 +74,16 @@ void QQuickPdfSearchModel::setDocument(QQuickPdfDocument *document)
}
\endqml
+ It becomes empty whenever \c {currentPage != currentResultLink.page}.
+
\sa PathMultiline
*/
QList<QPolygonF> QQuickPdfSearchModel::currentResultBoundingPolygons() const
{
QList<QPolygonF> ret;
- const auto &results = const_cast<QQuickPdfSearchModel *>(this)->resultsOnPage(m_currentPage);
- if (m_currentResult < 0 || m_currentResult >= results.count())
+ const auto result = currentResultLink();
+ if (result.page() != m_currentPage)
return ret;
- const auto result = results[m_currentResult];
for (auto rect : result.rectangles())
ret << QPolygonF(rect);
return ret;
@@ -119,23 +92,21 @@ QList<QPolygonF> QQuickPdfSearchModel::currentResultBoundingPolygons() const
/*!
\qmlproperty point PdfSearchModel::currentResultBoundingRect
- The bounding box containing all \l currentResultBoundingPolygons.
-
- When this property changes, a scrollable view should automatically scroll
- itself in such a way as to ensure that this region is visible; for example,
- it could try to position the upper-left corner near the upper-left of its
- own viewport, subject to the constraints of the scrollable area.
+ The bounding box containing all \l currentResultBoundingPolygons,
+ if \c {currentPage == currentResultLink.page}; otherwise, an invalid rectangle.
*/
QRectF QQuickPdfSearchModel::currentResultBoundingRect() const
{
QRectF ret;
- const auto &results = const_cast<QQuickPdfSearchModel *>(this)->resultsOnPage(m_currentPage);
- if (m_currentResult < 0 || m_currentResult >= results.count())
+ const auto result = currentResultLink();
+ if (result.page() != m_currentPage)
return ret;
- auto rects = results[m_currentResult].rectangles();
- ret = rects.takeFirst();
- for (auto rect : rects)
- ret = ret.united(rect);
+ auto rects = result.rectangles();
+ if (!rects.isEmpty()) {
+ ret = rects.takeFirst();
+ for (auto rect : rects)
+ ret = ret.united(rect);
+ }
return ret;
}
@@ -205,15 +176,15 @@ QList<QPolygonF> QQuickPdfSearchModel::currentPageBoundingPolygons() const
*/
QList<QPolygonF> QQuickPdfSearchModel::boundingPolygonsOnPage(int page)
{
- if (!document() || searchString().isEmpty() || page < 0 || page > document()->pageCount())
+ if (!document() || searchString().isEmpty() || page < 0 || page > document()->document()->pageCount())
return {};
updatePage(page);
QList<QPolygonF> ret;
- auto m = QPdfSearchModel::resultsOnPage(page);
- for (auto result : m) {
- for (auto rect : result.rectangles())
+ const auto m = QPdfSearchModel::resultsOnPage(page);
+ for (const auto &result : m) {
+ for (const auto &rect : result.rectangles())
ret << QPolygonF(rect);
}
@@ -228,12 +199,13 @@ QList<QPolygonF> QQuickPdfSearchModel::boundingPolygonsOnPage(int page)
*/
void QQuickPdfSearchModel::setCurrentPage(int currentPage)
{
- if (m_currentPage == currentPage)
+ if (m_currentPage == currentPage || !document())
return;
+ const auto pageCount = document()->document()->pageCount();
if (currentPage < 0)
- currentPage = document()->pageCount() - 1;
- else if (currentPage >= document()->pageCount())
+ currentPage = pageCount - 1;
+ else if (currentPage >= pageCount)
currentPage = 0;
m_currentPage = currentPage;
@@ -246,51 +218,50 @@ void QQuickPdfSearchModel::setCurrentPage(int currentPage)
/*!
\qmlproperty int PdfSearchModel::currentResult
- The result index on \l currentPage for which \l currentResultBoundingPolygons
- should provide the regions to highlight.
+ The result index within the whole set of search results, for which
+ \l currentResultBoundingPolygons should provide the regions to highlight
+ if currentPage matches \c currentResultLink.page.
*/
void QQuickPdfSearchModel::setCurrentResult(int currentResult)
{
if (m_currentResult == currentResult)
return;
- int currentResultWas = currentResult;
- int currentPageWas = m_currentPage;
- if (currentResult < 0) {
- setCurrentPage(m_currentPage - 1);
- while (resultsOnPage(m_currentPage).count() == 0 && m_currentPage != currentPageWas) {
- m_suspendSignals = true;
- setCurrentPage(m_currentPage - 1);
- }
- if (m_suspendSignals) {
- emit currentPageChanged();
- m_suspendSignals = false;
- }
- const auto results = resultsOnPage(m_currentPage);
- currentResult = results.count() - 1;
+ const int currentResultWas = m_currentResult;
+ const int currentPageWas = m_currentPage;
+ const int resultCount = rowCount({});
+
+ // wrap around at the ends
+ if (currentResult >= resultCount) {
+ currentResult = 0;
+ } else if (currentResult < 0) {
+ currentResult = resultCount - 1;
+ }
+
+ const QPdfLink link = resultAtIndex(currentResult);
+ if (link.isValid()) {
+ setCurrentPage(link.page());
+ m_currentResult = currentResult;
+ emit currentResultChanged();
+ emit currentResultLinkChanged();
+ emit currentResultBoundingPolygonsChanged();
+ emit currentResultBoundingRectChanged();
+ qCDebug(qLcSearch) << "currentResult was" << currentResultWas
+ << "requested" << currentResult << "on page" << currentPageWas
+ << "->" << m_currentResult << "on page" << m_currentPage;
} else {
- const auto results = resultsOnPage(m_currentPage);
- if (currentResult >= results.count()) {
- setCurrentPage(m_currentPage + 1);
- while (resultsOnPage(m_currentPage).count() == 0 && m_currentPage != currentPageWas) {
- m_suspendSignals = true;
- setCurrentPage(m_currentPage + 1);
- }
- if (m_suspendSignals) {
- emit currentPageChanged();
- m_suspendSignals = false;
- }
- currentResult = 0;
- }
+ qWarning() << "failed to find result" << currentResult << "in range 0 ->" << resultCount;
}
- qCDebug(qLcSearch) << "currentResult was" << m_currentResult
- << "requested" << currentResultWas << "on page" << currentPageWas
- << "->" << currentResult << "on page" << m_currentPage;
+}
- m_currentResult = currentResult;
- emit currentResultChanged();
- emit currentResultBoundingPolygonsChanged();
- emit currentResultBoundingRectChanged();
+/*!
+ \qmlproperty QPdfLink PdfSearchModel::currentResultLink
+
+ The result at index \l currentResult.
+*/
+QPdfLink QQuickPdfSearchModel::currentResultLink() const
+{
+ return resultAtIndex(m_currentResult);
}
/*!
@@ -299,4 +270,13 @@ void QQuickPdfSearchModel::setCurrentResult(int currentResult)
The string to search for.
*/
+/*!
+ \since 6.8
+ \qmlproperty int PdfSearchModel::count
+
+ The number of search results found.
+*/
+
QT_END_NAMESPACE
+
+#include "moc_qquickpdfsearchmodel_p.cpp"
diff --git a/src/pdfquick/qquickpdfsearchmodel_p.h b/src/pdfquick/qquickpdfsearchmodel_p.h
index ad92d4222..699cd719f 100644
--- a/src/pdfquick/qquickpdfsearchmodel_p.h
+++ b/src/pdfquick/qquickpdfsearchmodel_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKPDFSEARCHMODEL_P_H
#define QQUICKPDFSEARCHMODEL_P_H
@@ -50,10 +17,9 @@
#include <QtPdfQuick/private/qtpdfquickglobal_p.h>
#include <QtPdfQuick/private/qquickpdfdocument_p.h>
-#include <QtPdf/qpdfsearchmodel.h>
-#include <QtCore/qvariant.h>
-#include <QtQml/qqml.h>
+#include <QtPdf/qpdfsearchmodel.h>
+#include <QtQml/QQmlEngine>
QT_BEGIN_NAMESPACE
@@ -63,12 +29,16 @@ class Q_PDFQUICK_EXPORT QQuickPdfSearchModel : public QPdfSearchModel
Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged)
Q_PROPERTY(int currentResult READ currentResult WRITE setCurrentResult NOTIFY currentResultChanged)
+ Q_PROPERTY(QPdfLink currentResultLink READ currentResultLink NOTIFY currentResultLinkChanged)
Q_PROPERTY(QList<QPolygonF> currentPageBoundingPolygons READ currentPageBoundingPolygons NOTIFY currentPageBoundingPolygonsChanged)
Q_PROPERTY(QList<QPolygonF> currentResultBoundingPolygons READ currentResultBoundingPolygons NOTIFY currentResultBoundingPolygonsChanged)
Q_PROPERTY(QRectF currentResultBoundingRect READ currentResultBoundingRect NOTIFY currentResultBoundingRectChanged)
+ QML_NAMED_ELEMENT(PdfSearchModel)
+ QML_ADDED_IN_VERSION(5, 15)
public:
explicit QQuickPdfSearchModel(QObject *parent = nullptr);
+ ~QQuickPdfSearchModel() override;
QQuickPdfDocument *document() const;
void setDocument(QQuickPdfDocument * document);
@@ -81,14 +51,15 @@ public:
int currentResult() const { return m_currentResult; }
void setCurrentResult(int currentResult);
+ QPdfLink currentResultLink() const;
QList<QPolygonF> currentPageBoundingPolygons() const;
QList<QPolygonF> currentResultBoundingPolygons() const;
QRectF currentResultBoundingRect() const;
signals:
- void documentChanged();
void currentPageChanged();
void currentResultChanged();
+ void currentResultLinkChanged();
void currentPageBoundingPolygonsChanged();
void currentResultBoundingPolygonsChanged();
void currentResultBoundingRectChanged();
diff --git a/src/pdfquick/qquickpdfselection.cpp b/src/pdfquick/qquickpdfselection.cpp
index 48ff0d8bd..4776cb8b4 100644
--- a/src/pdfquick/qquickpdfselection.cpp
+++ b/src/pdfquick/qquickpdfselection.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickpdfselection_p.h"
#include "qquickpdfdocument_p.h"
@@ -56,13 +23,14 @@ static const QRegularExpression WordDelimiter(QStringLiteral("\\s"));
//! \instantiates QQuickPdfSelection
\inqmlmodule QtQuick.Pdf
\ingroup pdf
+ \inherits Item
\brief A representation of a text selection within a PDF Document.
\since 5.15
PdfSelection provides the text string and its geometry within a bounding box
from one point to another.
- To modify the selection using the mouse, bind \l fromPoint and \l toPoint
+ To modify the selection using the mouse, bind \l from and \l to
to the suitable properties of an input handler so that they will be set to
the positions where the drag gesture begins and ends, respectively; and
bind the \l hold property so that it will be set to \c true during the drag
@@ -78,11 +46,19 @@ QQuickPdfSelection::QQuickPdfSelection(QQuickItem *parent)
{
#if QT_CONFIG(im)
setFlags(ItemIsFocusScope | ItemAcceptsInputMethod);
- // workaround to get Copy instead of Paste on the popover menu (QTBUG-83811)
- setProperty("qt_im_readonly", QVariant(true));
#endif
}
+/*!
+ \internal
+*/
+QQuickPdfSelection::~QQuickPdfSelection() = default;
+
+/*!
+ \qmlproperty PdfDocument PdfSelection::document
+
+ This property holds the PDF document in which to select text.
+*/
QQuickPdfDocument *QQuickPdfSelection::document() const
{
return m_document;
@@ -118,8 +94,8 @@ void QQuickPdfSelection::setDocument(QQuickPdfDocument *document)
PdfSelection {
id: selection
document: doc
- fromPoint: textSelectionDrag.centroid.pressPosition
- toPoint: textSelectionDrag.centroid.position
+ from: textSelectionDrag.centroid.pressPosition
+ to: textSelectionDrag.centroid.position
hold: !textSelectionDrag.active
}
Shape {
@@ -143,27 +119,39 @@ QList<QPolygonF> QQuickPdfSelection::geometry() const
return m_geometry;
}
+/*!
+ \qmlmethod void PdfSelection::clear()
+
+ Clears the current selection.
+*/
void QQuickPdfSelection::clear()
{
m_hitPoint = QPointF();
- m_fromPoint = QPointF();
- m_toPoint = QPointF();
+ m_from = QPointF();
+ m_to = QPointF();
m_heightAtAnchor = 0;
m_heightAtCursor = 0;
m_fromCharIndex = -1;
m_toCharIndex = -1;
m_text.clear();
m_geometry.clear();
- emit fromPointChanged();
- emit toPointChanged();
+ emit fromChanged();
+ emit toChanged();
emit textChanged();
emit selectedAreaChanged();
QGuiApplication::inputMethod()->update(Qt::ImQueryInput);
}
+/*!
+ \qmlmethod void PdfSelection::selectAll()
+
+ Selects all text on the current \l page.
+*/
void QQuickPdfSelection::selectAll()
{
- QPdfSelection sel = m_document->m_doc.getAllText(m_page);
+ if (!m_document)
+ return;
+ QPdfSelection sel = m_document->document()->getAllText(m_page);
if (sel.text() != m_text) {
m_text = sel.text();
if (QGuiApplication::clipboard()->supportsSelection())
@@ -179,11 +167,11 @@ void QQuickPdfSelection::selectAll()
m_fromCharIndex = sel.startIndex();
m_toCharIndex = sel.endIndex();
if (sel.bounds().isEmpty()) {
- m_fromPoint = QPointF();
- m_toPoint = QPointF();
+ m_from = QPointF();
+ m_to = QPointF();
} else {
- m_fromPoint = sel.bounds().first().boundingRect().topLeft() * m_renderScale;
- m_toPoint = sel.bounds().last().boundingRect().bottomRight() * m_renderScale - QPointF(0, m_heightAtCursor);
+ m_from = sel.bounds().first().boundingRect().topLeft() * m_renderScale;
+ m_to = sel.bounds().last().boundingRect().bottomRight() * m_renderScale - QPointF(0, m_heightAtCursor);
}
QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
@@ -196,21 +184,25 @@ void QQuickPdfSelection::keyReleaseEvent(QKeyEvent *ev)
qCDebug(qLcIm) << "release" << ev;
const auto &allText = pageText();
if (ev == QKeySequence::MoveToPreviousWord) {
+ if (!m_document)
+ return;
// iOS sends MoveToPreviousWord first to get to the beginning of the word,
// and then SelectNextWord to select the whole word.
- int i = allText.lastIndexOf(WordDelimiter, m_fromCharIndex - allText.length());
+ int i = allText.lastIndexOf(WordDelimiter, m_fromCharIndex - allText.size());
if (i < 0)
i = 0;
else
i += 1; // don't select the space before the word
- auto sel = m_document->m_doc.getSelectionAtIndex(m_page, i, m_text.length() + m_fromCharIndex - i);
+ auto sel = m_document->document()->getSelectionAtIndex(m_page, i, m_text.size() + m_fromCharIndex - i);
update(sel);
QGuiApplication::inputMethod()->update(Qt::ImAnchorRectangle);
} else if (ev == QKeySequence::SelectNextWord) {
+ if (!m_document)
+ return;
int i = allText.indexOf(WordDelimiter, m_toCharIndex);
if (i < 0)
- i = allText.length(); // go to the end of m_textAfter
- auto sel = m_document->m_doc.getSelectionAtIndex(m_page, m_fromCharIndex, m_text.length() + i - m_toCharIndex);
+ i = allText.size(); // go to the end of m_textAfter
+ auto sel = m_document->document()->getSelectionAtIndex(m_page, m_fromCharIndex, m_text.size() + i - m_toCharIndex);
update(sel);
QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle);
} else if (ev == QKeySequence::Copy) {
@@ -226,7 +218,9 @@ void QQuickPdfSelection::inputMethodEvent(QInputMethodEvent *event)
qCDebug(qLcIm) << "QInputMethodEvent::Cursor: moved to" << attr.start << "len" << attr.length;
break;
case QInputMethodEvent::Selection: {
- auto sel = m_document->m_doc.getSelectionAtIndex(m_page, attr.start, attr.length);
+ if (!m_document)
+ return;
+ auto sel = m_document->document()->getSelectionAtIndex(m_page, attr.start, attr.length);
update(sel);
qCDebug(qLcIm) << "QInputMethodEvent::Selection: from" << attr.start << "len" << attr.length
<< "result:" << m_fromCharIndex << "->" << m_toCharIndex << sel.boundingRectangle();
@@ -247,16 +241,18 @@ QVariant QQuickPdfSelection::inputMethodQuery(Qt::InputMethodQuery query, const
if (!argument.isNull()) {
qCDebug(qLcIm) << "IM query" << query << "with arg" << argument;
if (query == Qt::ImCursorPosition) {
+ if (!m_document)
+ return {};
// If it didn't move since last time, return the same result.
if (m_hitPoint == argument.toPointF())
return inputMethodQuery(query);
m_hitPoint = argument.toPointF();
- auto tp = m_document->m_doc.d->hitTest(m_page, m_hitPoint / m_renderScale);
+ auto tp = m_document->document()->d->hitTest(m_page, m_hitPoint / m_renderScale);
qCDebug(qLcIm) << "ImCursorPosition hit testing in px" << m_hitPoint << "pt" << (m_hitPoint / m_renderScale)
<< "got char index" << tp.charIndex << "@" << tp.position << "pt," << tp.position * m_renderScale << "px";
if (tp.charIndex >= 0) {
m_toCharIndex = tp.charIndex;
- m_toPoint = tp.position * m_renderScale - QPointF(0, m_heightAtCursor);
+ m_to = tp.position * m_renderScale - QPointF(0, m_heightAtCursor);
m_heightAtCursor = tp.height * m_renderScale;
if (qFuzzyIsNull(m_heightAtAnchor))
m_heightAtAnchor = m_heightAtCursor;
@@ -289,10 +285,10 @@ QVariant QQuickPdfSelection::inputMethodQuery(Qt::InputMethodQuery query) const
ret = m_toCharIndex;
break;
case Qt::ImAnchorRectangle:
- ret = QRectF(m_fromPoint, QSizeF(1, m_heightAtAnchor));
+ ret = QRectF(m_from, QSizeF(1, m_heightAtAnchor));
break;
case Qt::ImCursorRectangle:
- ret = QRectF(m_toPoint, QSizeF(1, m_heightAtCursor));
+ ret = QRectF(m_to, QSizeF(1, m_heightAtCursor));
break;
case Qt::ImSurroundingText:
ret = QVariant(pageText());
@@ -321,6 +317,7 @@ QVariant QQuickPdfSelection::inputMethodQuery(Qt::InputMethodQuery query) const
case Qt::ImPlatformData:
break;
case Qt::ImReadOnly:
+ ret = true;
break;
case Qt::ImQueryInput:
case Qt::ImQueryAll:
@@ -335,7 +332,9 @@ QVariant QQuickPdfSelection::inputMethodQuery(Qt::InputMethodQuery query) const
const QString &QQuickPdfSelection::pageText() const
{
if (m_pageTextDirty) {
- m_pageText = m_document->m_doc.getAllText(m_page).text();
+ if (!m_document)
+ return m_pageText;
+ m_pageText = m_document->document()->getAllText(m_page).text();
m_pageTextDirty = false;
}
return m_pageText;
@@ -345,8 +344,8 @@ void QQuickPdfSelection::resetPoints()
{
bool wasHolding = m_hold;
m_hold = false;
- setFromPoint(QPointF());
- setToPoint(QPointF());
+ setFrom(QPointF());
+ setTo(QPointF());
m_hold = wasHolding;
}
@@ -377,7 +376,7 @@ void QQuickPdfSelection::setPage(int page)
\qmlproperty real PdfSelection::renderScale
\brief The ratio from points to pixels at which the page is rendered.
- This is used to scale \l fromPoint and \l toPoint to find ranges of
+ This is used to scale \l from and \l to to find ranges of
selected characters in the document, because positions within the document
are always given in points.
*/
@@ -388,6 +387,11 @@ qreal QQuickPdfSelection::renderScale() const
void QQuickPdfSelection::setRenderScale(qreal scale)
{
+ if (qFuzzyIsNull(scale)) {
+ qWarning() << "PdfSelection.renderScale cannot be set to 0.";
+ return;
+ }
+
if (qFuzzyCompare(scale, m_renderScale))
return;
@@ -397,7 +401,7 @@ void QQuickPdfSelection::setRenderScale(qreal scale)
}
/*!
- \qmlproperty point PdfSelection::fromPoint
+ \qmlproperty point PdfSelection::from
The beginning location, in pixels from the upper-left corner of the page,
from which to find selected text. This can be bound to the
@@ -405,41 +409,41 @@ void QQuickPdfSelection::setRenderScale(qreal scale)
the position where the user presses the mouse button and begins dragging,
for example.
*/
-QPointF QQuickPdfSelection::fromPoint() const
+QPointF QQuickPdfSelection::from() const
{
- return m_fromPoint;
+ return m_from;
}
-void QQuickPdfSelection::setFromPoint(QPointF fromPoint)
+void QQuickPdfSelection::setFrom(QPointF from)
{
- if (m_hold || m_fromPoint == fromPoint)
+ if (m_hold || m_from == from)
return;
- m_fromPoint = fromPoint;
- emit fromPointChanged();
+ m_from = from;
+ emit fromChanged();
updateResults();
}
/*!
- \qmlproperty point PdfSelection::toPoint
+ \qmlproperty point PdfSelection::to
The ending location, in pixels from the upper-left corner of the page,
from which to find selected text. This can be bound to the
\c centroid.position of a \l DragHandler to end selection of text at the
position where the user is currently dragging the mouse, for example.
*/
-QPointF QQuickPdfSelection::toPoint() const
+QPointF QQuickPdfSelection::to() const
{
- return m_toPoint;
+ return m_to;
}
-void QQuickPdfSelection::setToPoint(QPointF toPoint)
+void QQuickPdfSelection::setTo(QPointF to)
{
- if (m_hold || m_toPoint == toPoint)
+ if (m_hold || m_to == to)
return;
- m_toPoint = toPoint;
- emit toPointChanged();
+ m_to = to;
+ emit toChanged();
updateResults();
}
@@ -447,7 +451,7 @@ void QQuickPdfSelection::setToPoint(QPointF toPoint)
\qmlproperty bool PdfSelection::hold
Controls whether to hold the existing selection regardless of changes to
- \l fromPoint and \l toPoint. This property can be set to \c true when the mouse
+ \l from and \l to. This property can be set to \c true when the mouse
or touchpoint is released, so that the selection is not lost due to the
point bindings changing.
*/
@@ -491,8 +495,8 @@ void QQuickPdfSelection::updateResults()
{
if (!m_document)
return;
- QPdfSelection sel = m_document->document().getSelection(m_page,
- m_fromPoint / m_renderScale, m_toPoint / m_renderScale);
+ QPdfSelection sel = m_document->document()->getSelection(m_page,
+ m_from / m_renderScale, m_to / m_renderScale);
update(sel, true);
}
@@ -516,12 +520,12 @@ void QQuickPdfSelection::update(const QPdfSelection &sel, bool textAndGeometryOn
m_fromCharIndex = sel.startIndex();
m_toCharIndex = sel.endIndex();
if (sel.bounds().isEmpty()) {
- m_fromPoint = sel.boundingRectangle().topLeft() * m_renderScale;
- m_toPoint = m_fromPoint;
+ m_from = sel.boundingRectangle().topLeft() * m_renderScale;
+ m_to = m_from;
} else {
Qt::InputMethodQueries toUpdate = {};
QRectF firstLineBounds = sel.bounds().first().boundingRect();
- m_fromPoint = firstLineBounds.topLeft() * m_renderScale;
+ m_from = firstLineBounds.topLeft() * m_renderScale;
if (!qFuzzyCompare(m_heightAtAnchor, firstLineBounds.height())) {
m_heightAtAnchor = firstLineBounds.height() * m_renderScale;
toUpdate.setFlag(Qt::ImAnchorRectangle);
@@ -531,10 +535,12 @@ void QQuickPdfSelection::update(const QPdfSelection &sel, bool textAndGeometryOn
m_heightAtCursor = lastLineBounds.height() * m_renderScale;
toUpdate.setFlag(Qt::ImCursorRectangle);
}
- m_toPoint = lastLineBounds.topRight() * m_renderScale;
+ m_to = lastLineBounds.topRight() * m_renderScale;
if (toUpdate)
QGuiApplication::inputMethod()->update(toUpdate);
}
}
QT_END_NAMESPACE
+
+#include "moc_qquickpdfselection_p.cpp"
diff --git a/src/pdfquick/qquickpdfselection_p.h b/src/pdfquick/qquickpdfselection_p.h
index b364a6c03..4f633a467 100644
--- a/src/pdfquick/qquickpdfselection_p.h
+++ b/src/pdfquick/qquickpdfselection_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKPDFSELECTION_P_H
#define QQUICKPDFSELECTION_P_H
@@ -50,11 +17,12 @@
#include <QtPdfQuick/private/qtpdfquickglobal_p.h>
#include <QtPdfQuick/private/qquickpdfdocument_p.h>
-#include <QPointF>
-#include <QPolygonF>
-#include <QVariant>
-#include <QtQml/qqml.h>
-#include <QtQuick/qquickitem.h>
+
+#include <QtCore/QPointF>
+#include <QtCore/QVariant>
+#include <QtGui/QPolygonF>
+#include <QtQml/QQmlEngine>
+#include <QtQuick/QQuickItem>
QT_BEGIN_NAMESPACE
class QPdfSelection;
@@ -65,15 +33,18 @@ class Q_PDFQUICK_EXPORT QQuickPdfSelection : public QQuickItem
Q_PROPERTY(QQuickPdfDocument *document READ document WRITE setDocument NOTIFY documentChanged)
Q_PROPERTY(int page READ page WRITE setPage NOTIFY pageChanged)
Q_PROPERTY(qreal renderScale READ renderScale WRITE setRenderScale NOTIFY renderScaleChanged)
- Q_PROPERTY(QPointF fromPoint READ fromPoint WRITE setFromPoint NOTIFY fromPointChanged)
- Q_PROPERTY(QPointF toPoint READ toPoint WRITE setToPoint NOTIFY toPointChanged)
+ Q_PROPERTY(QPointF from READ from WRITE setFrom NOTIFY fromChanged)
+ Q_PROPERTY(QPointF to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(bool hold READ hold WRITE setHold NOTIFY holdChanged)
Q_PROPERTY(QString text READ text NOTIFY textChanged)
Q_PROPERTY(QList<QPolygonF> geometry READ geometry NOTIFY selectedAreaChanged)
+ QML_NAMED_ELEMENT(PdfSelection)
+ QML_ADDED_IN_VERSION(5, 15)
public:
explicit QQuickPdfSelection(QQuickItem *parent = nullptr);
+ ~QQuickPdfSelection() override;
QQuickPdfDocument *document() const;
void setDocument(QQuickPdfDocument * document);
@@ -81,10 +52,10 @@ public:
void setPage(int page);
qreal renderScale() const;
void setRenderScale(qreal scale);
- QPointF fromPoint() const;
- void setFromPoint(QPointF fromPoint);
- QPointF toPoint() const;
- void setToPoint(QPointF toPoint);
+ QPointF from() const;
+ void setFrom(QPointF from);
+ QPointF to() const;
+ void setTo(QPointF to);
bool hold() const;
void setHold(bool hold);
@@ -101,8 +72,8 @@ signals:
void documentChanged();
void pageChanged();
void renderScaleChanged();
- void fromPointChanged();
- void toPointChanged();
+ void fromChanged();
+ void toChanged();
void holdChanged();
void textChanged();
void selectedAreaChanged();
@@ -124,8 +95,8 @@ private:
private:
QQuickPdfDocument *m_document = nullptr;
mutable QPointF m_hitPoint;
- QPointF m_fromPoint;
- mutable QPointF m_toPoint;
+ QPointF m_from;
+ mutable QPointF m_to;
qreal m_renderScale = 1;
mutable qreal m_heightAtAnchor = 0;
mutable qreal m_heightAtCursor = 0;
diff --git a/src/pdfquick/qquicktableviewextra.cpp b/src/pdfquick/qquicktableviewextra.cpp
deleted file mode 100644
index 6ce45967f..000000000
--- a/src/pdfquick/qquicktableviewextra.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 "qquicktableviewextra_p.h"
-#include <QtQml>
-#include <QQmlContext>
-
-Q_LOGGING_CATEGORY(qLcTVE, "qt.pdf.tableextra")
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- \qmltype TableViewExtra
-//! \instantiates QQuickTableViewExtra
- \inqmlmodule QtQuick.Pdf
- \ingroup pdf
- \brief A helper class with missing TableView functions
- \since 5.15
-
- TableViewExtra provides equivalents for some functions that will be added
- to TableView in Qt 6.
-*/
-
-QQuickTableViewExtra::QQuickTableViewExtra(QObject *parent) : QObject(parent)
-{
-}
-
-QPoint QQuickTableViewExtra::cellAtPos(qreal x, qreal y) const
-{
- QPointF position(x, y);
- return m_tableView->cellAtPos(position);
-}
-
-QQuickItem *QQuickTableViewExtra::itemAtCell(const QPoint &cell) const
-{
- return m_tableView->itemAtCell(cell);
-}
-
-void QQuickTableViewExtra::positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset)
-{
- m_tableView->positionViewAtCell(cell, alignment, offset);
-}
-
-QT_END_NAMESPACE
diff --git a/src/pdfquick/qquicktableviewextra_p.h b/src/pdfquick/qquicktableviewextra_p.h
deleted file mode 100644
index 30eed696d..000000000
--- a/src/pdfquick/qquicktableviewextra_p.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 QQUICKTABLEVIEWEXTRA_P_H
-#define QQUICKTABLEVIEWEXTRA_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 <QtPdfQuick/private/qtpdfquickglobal_p.h>
-#include <QtQuick/private/qquicktableview_p.h>
-#include <QPointF>
-#include <QPolygonF>
-#include <QVariant>
-#include <QtQml/qqml.h>
-#include <QtQuick/qquickitem.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_PDFQUICK_EXPORT QQuickTableViewExtra : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QQuickTableView *tableView READ tableView WRITE setTableView)
-
-public:
- QQuickTableViewExtra(QObject *parent = nullptr);
-
- QQuickTableView * tableView() const { return m_tableView; }
- void setTableView(QQuickTableView * tableView) { m_tableView = tableView; }
-
- Q_INVOKABLE QPoint cellAtPos(qreal x, qreal y) const;
- Q_INVOKABLE QQuickItem *itemAtCell(int column, int row) const {
- return itemAtCell(QPoint(column, row));
- }
- Q_INVOKABLE QQuickItem *itemAtCell(const QPoint &cell) const;
- Q_INVOKABLE void positionViewAtCell(int column, int row, Qt::Alignment alignment, const QPointF &offset = QPointF()) {
- positionViewAtCell(QPoint(column, row), alignment, offset);
- }
- Q_INVOKABLE void positionViewAtCell(const QPoint &cell, Qt::Alignment alignment, const QPointF &offset);
- Q_INVOKABLE void positionViewAtRow(int row, Qt::Alignment alignment, qreal offset = 0) {
- positionViewAtCell(QPoint(0, row), alignment & Qt::AlignVertical_Mask, QPointF(0, offset));
- }
-
-private:
- QQuickTableView *m_tableView = nullptr;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickTableViewExtra)
-
-#endif // QQUICKTABLEVIEWEXTRA_P_H
diff --git a/src/pdfquick/qtpdfquickglobal_p.h b/src/pdfquick/qtpdfquickglobal_p.h
index 567b10094..7b5d629ed 100644
--- a/src/pdfquick/qtpdfquickglobal_p.h
+++ b/src/pdfquick/qtpdfquickglobal_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTPDFQUICKGLOBAL_H
#define QTPDFQUICKGLOBAL_H
diff --git a/src/pdfwidgets/CMakeLists.txt b/src/pdfwidgets/CMakeLists.txt
index 2d2616556..41af017c0 100644
--- a/src/pdfwidgets/CMakeLists.txt
+++ b/src/pdfwidgets/CMakeLists.txt
@@ -1,7 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Widgets)
qt_internal_add_module(PdfWidgets
SOURCES
+ qpdfpageselector.cpp qpdfpageselector.h qpdfpageselector_p.h
qpdfview.cpp qpdfview.h qpdfview_p.h
qtpdfwidgetsglobal.h
LIBRARIES
@@ -11,4 +15,5 @@ qt_internal_add_module(PdfWidgets
Qt::Gui
Qt::Widgets
Qt::Pdf
+ NO_GENERATE_CPP_EXPORTS
)
diff --git a/src/pdfwidgets/qpdfpageselector.cpp b/src/pdfwidgets/qpdfpageselector.cpp
new file mode 100644
index 000000000..66b781ed3
--- /dev/null
+++ b/src/pdfwidgets/qpdfpageselector.cpp
@@ -0,0 +1,171 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpdfpageselector.h"
+#include "qpdfpageselector_p.h"
+
+#include <QPdfDocument>
+
+#include <QtWidgets/qboxlayout.h>
+
+using namespace Qt::StringLiterals;
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPdfPageSelector
+ \inmodule QtPdf
+ \since 6.6
+ \brief A widget for selecting a PDF page.
+
+ QPdfPageSelector is a widget for selecting a page label from a
+ QPdfDocument.
+
+ \sa QPdfDocument::pageLabel()
+*/
+
+/*!
+ Constructs a PDF page selector with parent widget \a parent.
+*/
+QPdfPageSelector::QPdfPageSelector(QWidget *parent)
+ : QWidget(parent), d_ptr(new QPdfPageSelectorPrivate)
+{
+ Q_D(QPdfPageSelector);
+ d->spinBox = new QPdfPageSelectorSpinBox(this);
+ d->spinBox->setObjectName(u"_q_spinBox"_s);
+ auto vlay = new QVBoxLayout(this);
+ vlay->setContentsMargins({});
+ vlay->addWidget(d->spinBox);
+
+ connect(d->spinBox, &QPdfPageSelectorSpinBox::_q_documentChanged,
+ this, &QPdfPageSelector::documentChanged);
+ connect(d->spinBox, &QSpinBox::valueChanged, this, &QPdfPageSelector::currentPageChanged);
+ connect(d->spinBox, &QSpinBox::textChanged, this, &QPdfPageSelector::currentPageLabelChanged);
+}
+
+/*!
+ Destroys the page selector.
+*/
+QPdfPageSelector::~QPdfPageSelector()
+ = default;
+
+/*!
+ \property QPdfPageSelector::document
+
+ This property holds the document to be viewed.
+*/
+
+void QPdfPageSelector::setDocument(QPdfDocument *doc)
+{
+ Q_D(QPdfPageSelector);
+ d->spinBox->setDocument(doc);
+}
+
+QPdfDocument *QPdfPageSelector::document() const
+{
+ Q_D(const QPdfPageSelector);
+ return d->spinBox->document();
+}
+
+/*!
+ \property QPdfPageSelector::currentPage
+
+ This property holds the index (\c{0}-based) of the current page in the
+ document.
+*/
+
+int QPdfPageSelector::currentPage() const
+{
+ Q_D(const QPdfPageSelector);
+ return d->spinBox->value();
+}
+
+void QPdfPageSelector::setCurrentPage(int index)
+{
+ Q_D(QPdfPageSelector);
+ d->spinBox->setValue(index);
+}
+
+/*!
+ \property QPdfPageSelector::currentPageLabel
+
+ This property holds the page label corresponding to the current page
+ in the document.
+
+ This is the text presented to the user.
+
+ \sa QPdfDocument::pageLabel()
+*/
+
+QString QPdfPageSelector::currentPageLabel() const
+{
+ Q_D(const QPdfPageSelector);
+ return d->spinBox->text();
+}
+
+//
+// QPdfPageSelectorSpinBox:
+//
+
+void QPdfPageSelectorSpinBox::documentStatusChanged()
+{
+ if (m_document && m_document->status() == QPdfDocument::Status::Ready) {
+ setMaximum(m_document->pageCount());
+ setValue(0);
+ }
+}
+
+void QPdfPageSelectorSpinBox::setDocument(QPdfDocument *document)
+{
+ if (m_document == document)
+ return;
+
+ if (m_document)
+ disconnect(m_documentStatusChangedConnection);
+
+ m_document = document;
+ emit _q_documentChanged(document);
+
+ if (m_document) {
+ m_documentStatusChangedConnection =
+ connect(m_document.get(), &QPdfDocument::statusChanged,
+ this, &QPdfPageSelectorSpinBox::documentStatusChanged);
+ }
+
+ documentStatusChanged();
+}
+
+QPdfPageSelectorSpinBox::QPdfPageSelectorSpinBox(QWidget *parent)
+ : QSpinBox(parent)
+{
+}
+
+QPdfPageSelectorSpinBox::~QPdfPageSelectorSpinBox()
+ = default;
+
+int QPdfPageSelectorSpinBox::valueFromText(const QString &text) const
+{
+ if (!m_document)
+ return 0;
+
+ return m_document->pageIndexForLabel(text.trimmed());
+}
+
+QString QPdfPageSelectorSpinBox::textFromValue(int value) const
+{
+ if (!m_document)
+ return {};
+
+ return m_document->pageLabel(value);
+}
+
+QValidator::State QPdfPageSelectorSpinBox::validate(QString &text, int &pos) const
+{
+ Q_UNUSED(pos);
+ return valueFromText(text) >= 0 ? QValidator::Acceptable : QValidator::Intermediate;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qpdfpageselector_p.cpp"
+#include "moc_qpdfpageselector.cpp"
diff --git a/src/pdfwidgets/qpdfpageselector.h b/src/pdfwidgets/qpdfpageselector.h
new file mode 100644
index 000000000..d779f54cd
--- /dev/null
+++ b/src/pdfwidgets/qpdfpageselector.h
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFPAGESELECTOR_H
+#define QPDFPAGESELECTOR_H
+
+#include <QtPdfWidgets/qtpdfwidgetsglobal.h>
+
+#include <QtWidgets/qwidget.h>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfDocument;
+class QPdfPageSelectorPrivate;
+
+class Q_PDF_WIDGETS_EXPORT QPdfPageSelector : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPdfDocument* document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged USER true)
+ Q_PROPERTY(QString currentPageLabel READ currentPageLabel NOTIFY currentPageLabelChanged)
+public:
+ QPdfPageSelector() : QPdfPageSelector(nullptr) {}
+ explicit QPdfPageSelector(QWidget *parent);
+ ~QPdfPageSelector() override;
+
+ void setDocument(QPdfDocument *document);
+ QPdfDocument *document() const;
+
+ int currentPage() const;
+ QString currentPageLabel() const;
+
+public Q_SLOTS:
+ void setCurrentPage(int index);
+
+Q_SIGNALS:
+ void documentChanged(QPdfDocument *document);
+ void currentPageChanged(int index);
+ void currentPageLabelChanged(const QString &label);
+
+private:
+ Q_DECLARE_PRIVATE(QPdfPageSelector)
+ const std::unique_ptr<QPdfPageSelectorPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFPAGESELECTOR_H
diff --git a/src/pdfwidgets/qpdfpageselector_p.h b/src/pdfwidgets/qpdfpageselector_p.h
new file mode 100644
index 000000000..8e961f1d2
--- /dev/null
+++ b/src/pdfwidgets/qpdfpageselector_p.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPDFPAGESELECTOR_P_H
+#define QPDFPAGESELECTOR_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 "qpdfpageselector.h"
+
+#include <QtWidgets/qspinbox.h>
+
+#include <QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QPdfPageSelectorSpinBox : public QSpinBox
+{
+ Q_OBJECT
+public:
+ QPdfPageSelectorSpinBox() : QPdfPageSelectorSpinBox(nullptr) {}
+ explicit QPdfPageSelectorSpinBox(QWidget *parent);
+ ~QPdfPageSelectorSpinBox();
+
+ void setDocument(QPdfDocument *document);
+ QPdfDocument *document() const { return m_document.get(); }
+
+Q_SIGNALS:
+ void _q_documentChanged(QPdfDocument *document);
+
+protected:
+ int valueFromText(const QString &text) const override;
+ QString textFromValue(int value) const override;
+ QValidator::State validate(QString &text, int &pos) const override;
+
+private:
+ void documentStatusChanged();
+private:
+ QPointer<QPdfDocument> m_document;
+ QMetaObject::Connection m_documentStatusChangedConnection;
+};
+
+class QPdfPageSelectorPrivate
+{
+public:
+ QPdfPageSelectorSpinBox *spinBox;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPDFPAGESELECTOR_P_H
diff --git a/src/pdfwidgets/qpdfview.cpp b/src/pdfwidgets/qpdfview.cpp
index cd2a8ef82..a67667fed 100644
--- a/src/pdfwidgets/qpdfview.cpp
+++ b/src/pdfwidgets/qpdfview.cpp
@@ -1,38 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qpdfview.h"
#include "qpdfview_p.h"
@@ -40,23 +8,31 @@
#include "qpdfpagerenderer.h"
#include <QGuiApplication>
+#include <QLoggingCategory>
#include <QPainter>
#include <QPaintEvent>
#include <QPdfDocument>
-#include <QPdfPageNavigation>
+#include <QPdfPageNavigator>
+#include <QPdfSearchModel>
#include <QScreen>
#include <QScrollBar>
-#include <QScroller>
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(qLcLink, "qt.pdf.links")
+//#define DEBUG_LINKS
+
+static const QColor SearchResultHighlight("#80B0C4DE");
+static const QColor CurrentSearchResultHighlight(Qt::cyan);
+static const int CurrentSearchResultWidth(2);
+
QPdfViewPrivate::QPdfViewPrivate(QPdfView *q)
: q_ptr(q)
, m_document(nullptr)
- , m_pageNavigation(nullptr)
+ , m_pageNavigator(nullptr)
, m_pageRenderer(nullptr)
- , m_pageMode(QPdfView::SinglePage)
- , m_zoomMode(QPdfView::CustomZoom)
+ , m_pageMode(QPdfView::PageMode::SinglePage)
+ , m_zoomMode(QPdfView::ZoomMode::Custom)
, m_zoomFactor(1.0)
, m_pageSpacing(3)
, m_documentMargins(6, 6, 6, 6)
@@ -70,7 +46,7 @@ void QPdfViewPrivate::init()
{
Q_Q(QPdfView);
- m_pageNavigation = new QPdfPageNavigation(q);
+ m_pageNavigator = new QPdfPageNavigator(q);
m_pageRenderer = new QPdfPageRenderer(q);
m_pageRenderer->setRenderMode(QPdfPageRenderer::RenderMode::MultiThreaded);
}
@@ -90,7 +66,7 @@ void QPdfViewPrivate::currentPageChanged(int currentPage)
q->verticalScrollBar()->setValue(yPositionForPage(currentPage));
- if (m_pageMode == QPdfView::SinglePage)
+ if (m_pageMode == QPdfView::PageMode::SinglePage)
invalidateDocumentLayout();
}
@@ -118,29 +94,31 @@ void QPdfViewPrivate::setViewport(QRect viewport)
if (oldSize != m_viewport.size()) {
updateDocumentLayout();
- if (m_zoomMode != QPdfView::CustomZoom) {
+ if (m_zoomMode != QPdfView::ZoomMode::Custom) {
invalidatePageCache();
}
}
- if (m_pageMode == QPdfView::MultiPage) {
+ if (m_pageMode == QPdfView::PageMode::MultiPage) {
// An imaginary, 2px height line at the upper half of the viewport, which is used to
// determine which page is currently located there -> we propagate that as 'current' page
- // to the QPdfPageNavigation object
+ // to the QPdfPageNavigator object
const QRect currentPageLine(m_viewport.x(), m_viewport.y() + m_viewport.height() * 0.4, m_viewport.width(), 2);
int currentPage = 0;
- for (auto it = m_documentLayout.pageGeometries.cbegin(); it != m_documentLayout.pageGeometries.cend(); ++it) {
- const QRect pageGeometry = it.value();
+ for (auto it = m_documentLayout.pageGeometryAndScale.cbegin();
+ it != m_documentLayout.pageGeometryAndScale.cend(); ++it) {
+ const QRect pageGeometry = it.value().first;
if (pageGeometry.intersects(currentPageLine)) {
currentPage = it.key();
break;
}
}
- if (currentPage != m_pageNavigation->currentPage()) {
+ if (currentPage != m_pageNavigator->currentPage()) {
m_blockPageScrolling = true;
- m_pageNavigation->setCurrentPage(currentPage);
+ // ΤODO give location on the page
+ m_pageNavigator->jump(currentPage, {}, m_zoomFactor);
m_blockPageScrolling = false;
}
}
@@ -167,7 +145,7 @@ void QPdfViewPrivate::pageRendered(int pageNumber, QSize imageSize, const QImage
Q_UNUSED(requestId);
if (!m_cachedPagesLRU.contains(pageNumber)) {
- if (m_cachedPagesLRU.length() > m_pageCacheLimit)
+ if (m_cachedPagesLRU.size() > m_pageCacheLimit)
m_pageCache.remove(m_cachedPagesLRU.takeFirst());
m_cachedPagesLRU.append(pageNumber);
@@ -202,37 +180,43 @@ QPdfViewPrivate::DocumentLayout QPdfViewPrivate::calculateDocumentLayout() const
DocumentLayout documentLayout;
- if (!m_document || m_document->status() != QPdfDocument::Ready)
+ if (!m_document || m_document->status() != QPdfDocument::Status::Ready)
return documentLayout;
- QHash<int, QRect> pageGeometries;
+ QHash<int, QPair<QRect, qreal>> pageGeometryAndScale;
const int pageCount = m_document->pageCount();
int totalWidth = 0;
- const int startPage = (m_pageMode == QPdfView::SinglePage ? m_pageNavigation->currentPage() : 0);
- const int endPage = (m_pageMode == QPdfView::SinglePage ? m_pageNavigation->currentPage() + 1 : pageCount);
+ const int startPage = (m_pageMode == QPdfView::PageMode::SinglePage ? m_pageNavigator->currentPage() : 0);
+ const int endPage = (m_pageMode == QPdfView::PageMode::SinglePage ? m_pageNavigator->currentPage() + 1 : pageCount);
// calculate page sizes
for (int page = startPage; page < endPage; ++page) {
QSize pageSize;
- if (m_zoomMode == QPdfView::CustomZoom) {
- pageSize = QSizeF(m_document->pageSize(page) * m_screenResolution * m_zoomFactor).toSize();
- } else if (m_zoomMode == QPdfView::FitToWidth) {
- pageSize = QSizeF(m_document->pageSize(page) * m_screenResolution).toSize();
- const qreal factor = (qreal(m_viewport.width() - m_documentMargins.left() - m_documentMargins.right()) / qreal(pageSize.width()));
- pageSize *= factor;
- } else if (m_zoomMode == QPdfView::FitInView) {
- const QSize viewportSize(m_viewport.size() + QSize(-m_documentMargins.left() - m_documentMargins.right(), -m_pageSpacing));
-
- pageSize = QSizeF(m_document->pageSize(page) * m_screenResolution).toSize();
- pageSize = pageSize.scaled(viewportSize, Qt::KeepAspectRatio);
+ qreal pageScale = m_zoomFactor;
+ if (m_zoomMode == QPdfView::ZoomMode::Custom) {
+ pageSize = QSizeF(m_document->pagePointSize(page) * m_screenResolution * m_zoomFactor).toSize();
+ } else if (m_zoomMode == QPdfView::ZoomMode::FitToWidth) {
+ pageSize = QSizeF(m_document->pagePointSize(page) * m_screenResolution).toSize();
+ pageScale = (qreal(m_viewport.width() - m_documentMargins.left() - m_documentMargins.right()) /
+ qreal(pageSize.width()));
+ pageSize *= pageScale;
+ } else if (m_zoomMode == QPdfView::ZoomMode::FitInView) {
+ const QSize viewportSize(m_viewport.size() +
+ QSize(-m_documentMargins.left() - m_documentMargins.right(), -m_pageSpacing));
+
+ pageSize = QSizeF(m_document->pagePointSize(page) * m_screenResolution).toSize();
+ QSize scaledSize = pageSize.scaled(viewportSize, Qt::KeepAspectRatio);
+ // because of KeepAspectRatio, the ratio of widths should be the same as the ratio of heights
+ pageScale = qreal(scaledSize.width()) / qreal(pageSize.width());
+ pageSize = scaledSize;
}
totalWidth = qMax(totalWidth, pageSize.width());
- pageGeometries[page] = QRect(QPoint(0, 0), pageSize);
+ pageGeometryAndScale[page] = {QRect(QPoint(0, 0), pageSize), pageScale};
}
totalWidth += m_documentMargins.left() + m_documentMargins.right();
@@ -241,19 +225,19 @@ QPdfViewPrivate::DocumentLayout QPdfViewPrivate::calculateDocumentLayout() const
// calculate page positions
for (int page = startPage; page < endPage; ++page) {
- const QSize pageSize = pageGeometries[page].size();
+ const QSize pageSize = pageGeometryAndScale[page].first.size();
// center horizontal inside the viewport
const int pageX = (qMax(totalWidth, m_viewport.width()) - pageSize.width()) / 2;
- pageGeometries[page].moveTopLeft(QPoint(pageX, pageY));
+ pageGeometryAndScale[page].first.moveTopLeft(QPoint(pageX, pageY));
pageY += pageSize.height() + m_pageSpacing;
}
pageY += m_documentMargins.bottom();
- documentLayout.pageGeometries = pageGeometries;
+ documentLayout.pageGeometryAndScale = pageGeometryAndScale;
// calculate overall document size
documentLayout.documentSize = QSize(totalWidth, pageY);
@@ -263,11 +247,26 @@ QPdfViewPrivate::DocumentLayout QPdfViewPrivate::calculateDocumentLayout() const
qreal QPdfViewPrivate::yPositionForPage(int pageNumber) const
{
- const auto it = m_documentLayout.pageGeometries.constFind(pageNumber);
- if (it == m_documentLayout.pageGeometries.cend())
+ const auto it = m_documentLayout.pageGeometryAndScale.constFind(pageNumber);
+ if (it == m_documentLayout.pageGeometryAndScale.cend())
return 0.0;
- return (*it).y();
+ return (*it).first.y();
+}
+
+QTransform QPdfViewPrivate::screenScaleTransform(int page) const
+{
+ qreal scale = m_screenResolution * m_zoomFactor;
+ switch (m_zoomMode) {
+ case QPdfView::ZoomMode::FitToWidth:
+ case QPdfView::ZoomMode::FitInView:
+ scale = m_screenResolution * m_documentLayout.pageGeometryAndScale[page].second;
+ break;
+ default:
+ break;
+ }
+
+ return QTransform::fromScale(scale, scale);
}
void QPdfViewPrivate::updateDocumentLayout()
@@ -277,7 +276,21 @@ void QPdfViewPrivate::updateDocumentLayout()
updateScrollBars();
}
-
+/*!
+ \class QPdfView
+ \inmodule QtPdf
+ \brief A PDF viewer widget.
+
+ QPdfView is a PDF viewer widget that offers a user experience similar to
+ many common PDF viewer applications, with two \l {pageMode}{modes}.
+ In the \c MultiPage mode, it supports flicking through the pages in the
+ entire document, with narrow gaps between the page images.
+ In the \c SinglePage mode, it shows one page at a time.
+*/
+
+/*!
+ Constructs a PDF viewer with parent widget \a parent.
+*/
QPdfView::QPdfView(QWidget *parent)
: QAbstractScrollArea(parent)
, d_ptr(new QPdfViewPrivate(this))
@@ -286,23 +299,32 @@ QPdfView::QPdfView(QWidget *parent)
d->init();
- connect(d->m_pageNavigation, &QPdfPageNavigation::currentPageChanged, this, [d](int page){ d->currentPageChanged(page); });
+ connect(d->m_pageNavigator, &QPdfPageNavigator::currentPageChanged, this,
+ [d](int page){ d->currentPageChanged(page); });
- connect(d->m_pageRenderer, &QPdfPageRenderer::pageRendered,
- this, [d](int pageNumber, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions, quint64 requestId){ d->pageRendered(pageNumber, imageSize, image, requestId); });
+ connect(d->m_pageRenderer, &QPdfPageRenderer::pageRendered, this,
+ [d](int pageNumber, QSize imageSize, const QImage &image, QPdfDocumentRenderOptions, quint64 requestId) {
+ d->pageRendered(pageNumber, imageSize, image, requestId); });
verticalScrollBar()->setSingleStep(20);
horizontalScrollBar()->setSingleStep(20);
- QScroller::grabGesture(this);
-
+ setMouseTracking(true);
d->calculateViewport();
}
+/*!
+ Destroys the PDF viewer.
+*/
QPdfView::~QPdfView()
{
}
+/*!
+ \property QPdfView::document
+
+ This property holds the document to be viewed.
+*/
void QPdfView::setDocument(QPdfDocument *document)
{
Q_D(QPdfView);
@@ -317,10 +339,12 @@ void QPdfView::setDocument(QPdfDocument *document)
emit documentChanged(d->m_document);
if (d->m_document)
- d->m_documentStatusChangedConnection = connect(d->m_document.data(), &QPdfDocument::statusChanged, this, [d](){ d->documentStatusChanged(); });
+ d->m_documentStatusChangedConnection =
+ connect(d->m_document.data(), &QPdfDocument::statusChanged, this,
+ [d](){ d->documentStatusChanged(); });
- d->m_pageNavigation->setDocument(d->m_document);
d->m_pageRenderer->setDocument(d->m_document);
+ d->m_linkModel.setDocument(d->m_document);
d->documentStatusChanged();
}
@@ -332,13 +356,94 @@ QPdfDocument *QPdfView::document() const
return d->m_document;
}
-QPdfPageNavigation *QPdfView::pageNavigation() const
+/*!
+ \since 6.6
+ \property QPdfView::searchModel
+
+ If this property is set, QPdfView draws highlight rectangles over the
+ search results provided by \l QPdfSearchModel::resultsOnPage(). By default
+ it is \c nullptr.
+*/
+void QPdfView::setSearchModel(QPdfSearchModel *searchModel)
+{
+ Q_D(QPdfView);
+ if (d->m_searchModel == searchModel)
+ return;
+
+ if (d->m_searchModel)
+ d->m_searchModel->disconnect(this);
+
+ d->m_searchModel = searchModel;
+ emit searchModelChanged(searchModel);
+
+ if (searchModel) {
+ connect(searchModel, &QPdfSearchModel::dataChanged, this,
+ [this](const QModelIndex &, const QModelIndex &, const QList<int> &) { update(); });
+ }
+ setCurrentSearchResultIndex(-1);
+}
+
+QPdfSearchModel *QPdfView::searchModel() const
+{
+ Q_D(const QPdfView);
+ return d->m_searchModel;
+}
+
+/*!
+ \since 6.6
+ \property QPdfView::currentSearchResultIndex
+
+ If this property is set to a positive number, and \l searchModel is set,
+ QPdfView draws a frame around the search result provided by
+ \l QPdfSearchModel at the given index. For example, if QPdfSearchModel is
+ used as the model for a QListView, you can keep this property updated by
+ connecting QItemSelectionModel::currentChanged() from
+ QListView::selectionModel() to a function that will in turn call this function.
+
+ By default it is \c -1, so that no search results are framed.
+*/
+void QPdfView::setCurrentSearchResultIndex(int currentResult)
+{
+ Q_D(QPdfView);
+ if (d->m_currentSearchResultIndex == currentResult)
+ return;
+
+ d->m_currentSearchResultIndex = currentResult;
+ emit currentSearchResultIndexChanged(currentResult);
+ viewport()->update(); //update();
+}
+
+int QPdfView::currentSearchResultIndex() const
+{
+ Q_D(const QPdfView);
+ return d->m_currentSearchResultIndex;
+}
+
+/*!
+ This accessor returns the navigation stack that will handle back/forward navigation.
+*/
+QPdfPageNavigator *QPdfView::pageNavigator() const
{
Q_D(const QPdfView);
- return d->m_pageNavigation;
+ return d->m_pageNavigator;
}
+/*!
+ \enum QPdfView::PageMode
+
+ This enum describes the overall behavior of the PDF viewer:
+
+ \value SinglePage Show one page at a time.
+ \value MultiPage Allow scrolling through all pages in the document.
+*/
+
+/*!
+ \property QPdfView::pageMode
+
+ This property holds whether to show one page at a time, or all pages in the
+ document. The default is \c SinglePage.
+*/
QPdfView::PageMode QPdfView::pageMode() const
{
Q_D(const QPdfView);
@@ -359,6 +464,24 @@ void QPdfView::setPageMode(PageMode mode)
emit pageModeChanged(d->m_pageMode);
}
+/*!
+ \enum QPdfView::ZoomMode
+
+ This enum describes the magnification behavior of the PDF viewer:
+
+ \value Custom Use \l zoomFactor only.
+ \value FitToWidth Automatically choose a zoom factor so that
+ the width of the page fits in the view.
+ \value FitInView Automatically choose a zoom factor so that
+ the entire page fits in the view.
+*/
+
+/*!
+ \property QPdfView::zoomMode
+
+ This property indicates whether to use a custom size for the page(s),
+ or zoom them to fit to the view. The default is \c CustomZoom.
+*/
QPdfView::ZoomMode QPdfView::zoomMode() const
{
Q_D(const QPdfView);
@@ -379,6 +502,12 @@ void QPdfView::setZoomMode(ZoomMode mode)
emit zoomModeChanged(d->m_zoomMode);
}
+/*!
+ \property QPdfView::zoomFactor
+
+ This property holds the ratio of pixels to points. The default is \c 1,
+ meaning one point (1/72 of an inch) equals 1 logical pixel.
+*/
qreal QPdfView::zoomFactor() const
{
Q_D(const QPdfView);
@@ -399,6 +528,12 @@ void QPdfView::setZoomFactor(qreal factor)
emit zoomFactorChanged(d->m_zoomFactor);
}
+/*!
+ \property QPdfView::pageSpacing
+
+ This property holds the size of the padding between pages in the \l MultiPage
+ \l {pageMode}{mode}.
+*/
int QPdfView::pageSpacing() const
{
Q_D(const QPdfView);
@@ -419,6 +554,11 @@ void QPdfView::setPageSpacing(int spacing)
emit pageSpacingChanged(d->m_pageSpacing);
}
+/*!
+ \property QPdfView::documentMargins
+
+ This property holds the margins around the page view.
+*/
QMargins QPdfView::documentMargins() const
{
Q_D(const QPdfView);
@@ -447,8 +587,9 @@ void QPdfView::paintEvent(QPaintEvent *event)
painter.fillRect(event->rect(), palette().brush(QPalette::Dark));
painter.translate(-d->m_viewport.x(), -d->m_viewport.y());
- for (auto it = d->m_documentLayout.pageGeometries.cbegin(); it != d->m_documentLayout.pageGeometries.cend(); ++it) {
- const QRect pageGeometry = it.value();
+ for (auto it = d->m_documentLayout.pageGeometryAndScale.cbegin();
+ it != d->m_documentLayout.pageGeometryAndScale.cend(); ++it) {
+ const QRect pageGeometry = it.value().first;
if (pageGeometry.intersects(d->m_viewport)) { // page needs to be painted
painter.fillRect(pageGeometry, Qt::white);
@@ -456,9 +597,47 @@ void QPdfView::paintEvent(QPaintEvent *event)
const auto pageIt = d->m_pageCache.constFind(page);
if (pageIt != d->m_pageCache.cend()) {
const QImage &img = pageIt.value();
- painter.drawImage(pageGeometry.topLeft(), img);
+ painter.drawImage(pageGeometry, img);
} else {
- d->m_pageRenderer->requestPage(page, pageGeometry.size());
+ d->m_pageRenderer->requestPage(page, pageGeometry.size() * devicePixelRatioF());
+ }
+
+ const QTransform scaleTransform = d->screenScaleTransform(page);
+#ifdef DEBUG_LINKS
+ const QString fmt = u"page %1 @ %2, %3"_s;
+ d->m_linkModel.setPage(page);
+ const int linkCount = d->m_linkModel.rowCount({});
+ for (int i = 0; i < linkCount; ++i) {
+ const QRectF linkBounds = scaleTransform.mapRect(
+ d->m_linkModel.data(d->m_linkModel.index(i),
+ int(QPdfLinkModel::Role::Rect)).toRectF())
+ .translated(pageGeometry.topLeft());
+ painter.setPen(Qt::blue);
+ painter.drawRect(linkBounds);
+ painter.setPen(Qt::red);
+ const QPoint loc = d->m_linkModel.data(d->m_linkModel.index(i),
+ int(QPdfLinkModel::Role::Location)).toPoint();
+ // TODO maybe draw destination URL if that's what it is
+ painter.drawText(linkBounds.bottomLeft() + QPoint(2, -2),
+ fmt.arg(d->m_linkModel.data(d->m_linkModel.index(i),
+ int(QPdfLinkModel::Role::Page)).toInt())
+ .arg(loc.x()).arg(loc.y()));
+ }
+#endif
+ if (d->m_searchModel) {
+ for (const QPdfLink &result : d->m_searchModel->resultsOnPage(page)) {
+ for (const QRectF &rect : result.rectangles())
+ painter.fillRect(scaleTransform.mapRect(rect).translated(pageGeometry.topLeft()), SearchResultHighlight);
+ }
+
+ if (d->m_currentSearchResultIndex >= 0 && d->m_currentSearchResultIndex < d->m_searchModel->rowCount({})) {
+ const QPdfLink &cur = d->m_searchModel->resultAtIndex(d->m_currentSearchResultIndex);
+ if (cur.page() == page) {
+ painter.setPen({CurrentSearchResultHighlight, CurrentSearchResultWidth});
+ for (const auto &rect : cur.rectangles())
+ painter.drawRect(scaleTransform.mapRect(rect).translated(pageGeometry.topLeft()));
+ }
+ }
}
}
}
@@ -483,6 +662,52 @@ void QPdfView::scrollContentsBy(int dx, int dy)
d->calculateViewport();
}
+void QPdfView::mousePressEvent(QMouseEvent *event)
+{
+ Q_ASSERT(event->isAccepted());
+}
+
+void QPdfView::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QPdfView);
+ for (auto it = d->m_documentLayout.pageGeometryAndScale.cbegin();
+ it != d->m_documentLayout.pageGeometryAndScale.cend(); ++it) {
+ const int page = it.key();
+ const QTransform screenInvTransform = d->screenScaleTransform(page).inverted();
+ const QRect pageGeometry = it.value().first;
+ if (pageGeometry.contains(event->position().toPoint())) {
+ const QPointF posInPoints = screenInvTransform.map(event->position() - pageGeometry.topLeft());
+ d->m_linkModel.setPage(page);
+ auto dest = d->m_linkModel.linkAt(posInPoints);
+ setCursor(dest.isValid() ? Qt::PointingHandCursor : Qt::ArrowCursor);
+ if (dest.isValid())
+ qCDebug(qLcLink) << event->position() << ":" << posInPoints << "pt ->" << dest;
+ }
+ }
+}
+
+void QPdfView::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QPdfView);
+ for (auto it = d->m_documentLayout.pageGeometryAndScale.cbegin();
+ it != d->m_documentLayout.pageGeometryAndScale.cend(); ++it) {
+ const int page = it.key();
+ const QTransform screenInvTransform = d->screenScaleTransform(page).inverted();
+ const QRect pageGeometry = it.value().first;
+ if (pageGeometry.contains(event->position().toPoint())) {
+ const QPointF posInPoints = screenInvTransform.map(event->position() - pageGeometry.topLeft());
+ d->m_linkModel.setPage(page);
+ auto dest = d->m_linkModel.linkAt(posInPoints);
+ if (dest.isValid()) {
+ qCDebug(qLcLink) << event << ": jumping to" << dest;
+ d->m_pageNavigator->jump(dest.page(), dest.location(), dest.zoom());
+ // TODO scroll and zoom to where the link tells us to
+ }
+ return;
+ }
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qpdfview.cpp"
diff --git a/src/pdfwidgets/qpdfview.h b/src/pdfwidgets/qpdfview.h
index 25c0e7f69..7f1d014de 100644
--- a/src/pdfwidgets/qpdfview.h
+++ b/src/pdfwidgets/qpdfview.h
@@ -1,38 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFVIEW_H
#define QPDFVIEW_H
@@ -43,7 +11,8 @@
QT_BEGIN_NAMESPACE
class QPdfDocument;
-class QPdfPageNavigation;
+class QPdfPageNavigator;
+class QPdfSearchModel;
class QPdfViewPrivate;
class Q_PDF_WIDGETS_EXPORT QPdfView : public QAbstractScrollArea
@@ -59,29 +28,38 @@ class Q_PDF_WIDGETS_EXPORT QPdfView : public QAbstractScrollArea
Q_PROPERTY(int pageSpacing READ pageSpacing WRITE setPageSpacing NOTIFY pageSpacingChanged)
Q_PROPERTY(QMargins documentMargins READ documentMargins WRITE setDocumentMargins NOTIFY documentMarginsChanged)
+ Q_PROPERTY(QPdfSearchModel* searchModel READ searchModel WRITE setSearchModel NOTIFY searchModelChanged)
+ Q_PROPERTY(int currentSearchResultIndex READ currentSearchResultIndex WRITE setCurrentSearchResultIndex NOTIFY currentSearchResultIndexChanged)
+
public:
- enum PageMode
+ enum class PageMode
{
SinglePage,
MultiPage
};
Q_ENUM(PageMode)
- enum ZoomMode
+ enum class ZoomMode
{
- CustomZoom,
+ Custom,
FitToWidth,
FitInView
};
Q_ENUM(ZoomMode)
- explicit QPdfView(QWidget *parent = nullptr);
+ QPdfView() : QPdfView(nullptr) {}
+ explicit QPdfView(QWidget *parent);
~QPdfView();
void setDocument(QPdfDocument *document);
QPdfDocument *document() const;
- QPdfPageNavigation *pageNavigation() const;
+ QPdfSearchModel *searchModel() const;
+ void setSearchModel(QPdfSearchModel *searchModel);
+
+ int currentSearchResultIndex() const;
+
+ QPdfPageNavigator *pageNavigator() const;
PageMode pageMode() const;
ZoomMode zoomMode() const;
@@ -94,22 +72,28 @@ public:
void setDocumentMargins(QMargins margins);
public Q_SLOTS:
- void setPageMode(PageMode mode);
- void setZoomMode(ZoomMode mode);
+ void setPageMode(QPdfView::PageMode mode);
+ void setZoomMode(QPdfView::ZoomMode mode);
void setZoomFactor(qreal factor);
+ void setCurrentSearchResultIndex(int currentResult);
Q_SIGNALS:
void documentChanged(QPdfDocument *document);
- void pageModeChanged(PageMode pageMode);
- void zoomModeChanged(ZoomMode zoomMode);
+ void pageModeChanged(QPdfView::PageMode pageMode);
+ void zoomModeChanged(QPdfView::ZoomMode zoomMode);
void zoomFactorChanged(qreal zoomFactor);
void pageSpacingChanged(int pageSpacing);
void documentMarginsChanged(QMargins documentMargins);
+ void searchModelChanged(QPdfSearchModel *searchModel);
+ void currentSearchResultIndexChanged(int currentResult);
protected:
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void scrollContentsBy(int dx, int dy) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
private:
Q_DECLARE_PRIVATE(QPdfView)
diff --git a/src/pdfwidgets/qpdfview_p.h b/src/pdfwidgets/qpdfview_p.h
index 60f67ec4e..d349cc2ee 100644
--- a/src/pdfwidgets/qpdfview_p.h
+++ b/src/pdfwidgets/qpdfview_p.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPDFVIEW_P_H
#define QPDFVIEW_P_H
@@ -49,6 +16,8 @@
//
#include "qpdfview.h"
+#include "qpdfdocument.h"
+#include "qpdflinkmodel.h"
#include <QHash>
#include <QPointer>
@@ -77,10 +46,12 @@ public:
qreal yPositionForPage(int page) const;
+ QTransform screenScaleTransform(int page) const; // points to pixels
+
struct DocumentLayout
{
QSize documentSize;
- QHash<int, QRect> pageGeometries;
+ QHash<int, QPair<QRect, qreal>> pageGeometryAndScale;
};
DocumentLayout calculateDocumentLayout() const;
@@ -88,13 +59,17 @@ public:
QPdfView *q_ptr;
QPointer<QPdfDocument> m_document;
- QPdfPageNavigation* m_pageNavigation;
+ QPointer<QPdfSearchModel> m_searchModel;
+ QPdfPageNavigator* m_pageNavigator;
QPdfPageRenderer *m_pageRenderer;
+ QPdfLinkModel m_linkModel;
QPdfView::PageMode m_pageMode;
QPdfView::ZoomMode m_zoomMode;
qreal m_zoomFactor;
+ int m_currentSearchResultIndex = -1;
+
int m_pageSpacing;
QMargins m_documentMargins;
diff --git a/src/pdfwidgets/qtpdfwidgetsglobal.h b/src/pdfwidgets/qtpdfwidgetsglobal.h
index 6c73a34f6..83133e38c 100644
--- a/src/pdfwidgets/qtpdfwidgetsglobal.h
+++ b/src/pdfwidgets/qtpdfwidgetsglobal.h
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTPDFWIDGETSGLOBAL_H
#define QTPDFWIDGETSGLOBAL_H
diff --git a/src/process/CMakeLists.txt b/src/process/CMakeLists.txt
index 8628500c0..630ba42a8 100644
--- a/src/process/CMakeLists.txt
+++ b/src/process/CMakeLists.txt
@@ -1,5 +1,10 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(NOT DEFINED WEBENGINE_ROOT_SOURCE_DIR)
- get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." REALPATH)
+ qt_internal_get_filename_path_mode(path_mode)
+
+ get_filename_component(WEBENGINE_ROOT_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ${path_mode})
endif()
include(${WEBENGINE_ROOT_SOURCE_DIR}/cmake/Functions.cmake)
@@ -20,7 +25,7 @@ if(WIN32)
set_property(TARGET ${qtWebEngineProcessName} PROPERTY WIN32_EXECUTABLE TRUE)
# get libs rsp file, since cmake is not aware of PUBLIC libs for WebEngineCore
get_target_property(libs_rsp WebEngineCore LIBS_RSP)
- target_link_options(${qtWebEngineProcessName} PRIVATE "@${libs_rsp}")
+ target_link_options(${qtWebEngineProcessName} PRIVATE "@${libs_rsp}" "/STACK:0x800000")
endif()
if(MACOS)
@@ -41,23 +46,32 @@ qt_internal_extend_target(${qtWebEngineProcessName}
target_include_directories(${qtWebEngineProcessName} PRIVATE ../core)
qt_get_cmake_configurations(configs)
+
foreach(config ${configs})
string(TOUPPER "${config}" config_upper)
+ if(isFramework)
+ set(outputPath
+ "${QT_BUILD_DIR}/${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Helpers"
+ )
+ else()
+ set(outputPath "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}")
+ endif()
set_target_properties(${qtWebEngineProcessName} PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY_${config_upper} "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}"
+ RUNTIME_OUTPUT_DIRECTORY_${config_upper} "${outputPath}"
)
-endforeach()
-if(QT_FEATURE_debug_and_release)
- set_target_properties(${qtWebEngineProcessName} PROPERTIES
- OUTPUT_NAME_DEBUG ${qtWebEngineProcessName}${CMAKE_DEBUG_POSTFIX}
- )
-endif()
+ if("${config}" STREQUAL "Debug")
+ set_target_properties(${qtWebEngineProcessName} PROPERTIES
+ OUTPUT_NAME_DEBUG ${qtWebEngineProcessName}${CMAKE_DEBUG_POSTFIX}
+ )
+ endif()
+endforeach()
if(isFramework)
set_target_properties(${qtWebEngineProcessName} PROPERTIES
MACOSX_BUNDLE TRUE
INSTALL_RPATH "@loader_path/../../../../../../../"
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info_mac.plist.in"
)
target_sources(${qtWebEngineProcessName} PRIVATE QtWebEngineProcess.entitlements)
@@ -75,13 +89,9 @@ if(isFramework)
BUNDLE DESTINATION "${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Helpers"
COMPONENT Runtime
)
- if(QT_SUPERBUILD OR NOT QT_WILL_INSTALL)
- addCopyDirCommand(${qtWebEngineProcessName} "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${qtWebEngineProcessName}.app"
- "${QT_BUILD_DIR}/${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Helpers/${qtWebEngineProcessName}.app/"
- )
- endif()
qt_enable_separate_debug_info(${qtWebEngineProcessName}
- "${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Helpers" QT_EXECUTABLE
+ "${INSTALL_LIBDIR}" QT_EXECUTABLE
+ DSYM_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${INSTALL_LIBDIR}"
)
else()
qt_apply_rpaths(TARGET ${qtWebEngineProcessName} INSTALL_PATH "${INSTALL_LIBEXECDIR}" RELATIVE_RPATH)
diff --git a/src/process/Info_mac.plist.in b/src/process/Info_mac.plist.in
new file mode 100644
index 000000000..22c8c026d
--- /dev/null
+++ b/src/process/Info_mac.plist.in
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleAllowMixedLocalizations</key>
+ <true/>
+
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>LSUIElement</key>
+ <true/>
+</dict>
+</plist>
diff --git a/src/process/QtWebEngineProcess.entitlements b/src/process/QtWebEngineProcess.entitlements
index f2fbabddb..59a4b6c15 100644
--- a/src/process/QtWebEngineProcess.entitlements
+++ b/src/process/QtWebEngineProcess.entitlements
@@ -8,5 +8,7 @@
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
+ <key>com.apple.security.cs.disable-executable-page-protection</key>
+ <true/>
</dict>
</plist>
diff --git a/src/process/main.cpp b/src/process/main.cpp
index ce0f49d23..d71ab128e 100644
--- a/src/process/main.cpp
+++ b/src/process/main.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QCoreApplication>
@@ -85,7 +49,7 @@ struct tm* localtime64_r_proxy(const time_t* timep, struct tm* result)
return sandbox::localtime64_r_override(timep, result);
}
-#endif // defined(OS_LINUX)
+#endif // defined(Q_OS_LINUX)
#if defined(Q_OS_WIN32)
namespace QtWebEngineProcess {
diff --git a/src/process/support_win.cpp b/src/process/support_win.cpp
index c2ff2d838..ab4436b47 100644
--- a/src/process/support_win.cpp
+++ b/src/process/support_win.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qlibrary.h>
#include <qoperatingsystemversion.h>
diff --git a/src/webenginequick/CMakeLists.txt b/src/webenginequick/CMakeLists.txt
index a7f7d86bd..5f8344f08 100644
--- a/src/webenginequick/CMakeLists.txt
+++ b/src/webenginequick/CMakeLists.txt
@@ -1,9 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(ui)
qt_internal_add_qml_module(WebEngineQuick
URI "QtWebEngine"
VERSION "${PROJECT_VERSION}"
CLASS_NAME QtWebEnginePlugin
+ DEPENDENCIES
+ QtQuick/auto
+ QtWebChannel/auto
PLUGIN_TARGET qtwebenginequickplugin
NO_GENERATE_PLUGIN_SOURCE
NO_PLUGIN_OPTIONAL
@@ -17,11 +23,12 @@ qt_internal_add_qml_module(WebEngineQuick
api/qquickwebenginefaviconprovider_p_p.h
api/qquickwebenginenewwindowrequest.cpp api/qquickwebenginenewwindowrequest_p.h
api/qquickwebengineprofile.cpp api/qquickwebengineprofile.h api/qquickwebengineprofile_p.h
- api/qquickwebenginescriptcollection.cpp api/qquickwebenginescriptcollection_p.h
+ api/qquickwebenginescriptcollection.cpp api/qquickwebenginescriptcollection_p.h api/qquickwebenginescriptcollection_p_p.h
api/qquickwebenginesettings.cpp api/qquickwebenginesettings_p.h
api/qquickwebenginesingleton.cpp api/qquickwebenginesingleton_p.h
api/qquickwebenginetouchhandleprovider.cpp
api/qquickwebenginetouchhandleprovider_p_p.h
+ api/qquickwebenginetouchhandle.cpp api/qquickwebenginetouchhandle_p.h
api/qquickwebenginetouchselectionmenurequest.cpp
api/qquickwebenginetouchselectionmenurequest_p.h
api/qquickwebenginetouchselectionmenurequest_p_p.h
@@ -30,7 +37,6 @@ qt_internal_add_qml_module(WebEngineQuick
api/qquickwebengineforeigntypes_p.h
api/qtwebenginequickglobal.cpp api/qtwebenginequickglobal.h
api/qtwebenginequickglobal_p.h
- render_widget_host_view_qt_delegate_quick.cpp render_widget_host_view_qt_delegate_quick.h
render_widget_host_view_qt_delegate_quickwindow.cpp render_widget_host_view_qt_delegate_quickwindow.h
ui_delegates_manager.cpp ui_delegates_manager.h
DEFINES
@@ -49,6 +55,17 @@ qt_internal_add_qml_module(WebEngineQuick
Qt::Qml
Qt::Quick
Qt::WebEngineCore
+ NO_GENERATE_CPP_EXPORTS
+)
+
+qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_webengine_webchannel
+ PUBLIC_LIBRARIES
+ Qt::WebChannelQuick
+)
+
+qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_accessibility
+ SOURCES
+ qquickwebengine_accessible.cpp qquickwebengine_accessible.h
)
qt_internal_extend_target(qtwebenginequickplugin
diff --git a/src/webenginequick/api/qquickwebengineaction.cpp b/src/webenginequick/api/qquickwebengineaction.cpp
index 77ac8d340..006715c70 100644
--- a/src/webenginequick/api/qquickwebengineaction.cpp
+++ b/src/webenginequick/api/qquickwebengineaction.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebengineaction_p.h"
@@ -56,7 +20,7 @@ QT_BEGIN_NAMESPACE
method. It provides information about the action, such as
whether it is \l enabled.
- The following code uses the \l WebEngineView::action() method to check if the
+ The following code uses the \l WebEngineView::action() method to check if
the copy action is enabled:
\code
@@ -66,6 +30,14 @@ QT_BEGIN_NAMESPACE
else
console.log("Copy is disabled.");
\endcode
+
+ A \l ToolButton can be connected to a WebEngineAction as follows:
+
+ \snippet qtwebengine_webengineaction.qml 0
+
+ A context menu could be implemented like this:
+
+ \snippet qtwebengine_webengineaction.qml 1
*/
QQuickWebEngineActionPrivate::QQuickWebEngineActionPrivate(const QVariant &data, const QString &text, const QString &iconName, bool enabled)
@@ -171,3 +143,4 @@ void QQuickWebEngineAction::trigger()
QT_END_NAMESPACE
+#include "moc_qquickwebengineaction_p.cpp"
diff --git a/src/webenginequick/api/qquickwebengineaction_p.h b/src/webenginequick/api/qquickwebengineaction_p.h
index 225803d86..fcada7773 100644
--- a/src/webenginequick/api/qquickwebengineaction_p.h
+++ b/src/webenginequick/api/qquickwebengineaction_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEACTION_P_H
#define QQUICKWEBENGINEACTION_P_H
@@ -65,7 +29,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineActionPrivate;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineAction : public QObject
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineAction : public QObject
{
Q_OBJECT
Q_PROPERTY(QString text READ text CONSTANT FINAL)
diff --git a/src/webenginequick/api/qquickwebengineaction_p_p.h b/src/webenginequick/api/qquickwebengineaction_p_p.h
index 656c0fe33..7cbd69a79 100644
--- a/src/webenginequick/api/qquickwebengineaction_p_p.h
+++ b/src/webenginequick/api/qquickwebengineaction_p_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEACTION_P_P_H
#define QQUICKWEBENGINEACTION_P_P_H
diff --git a/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp b/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp
index e06cfa4d2..46e531716 100644
--- a/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp
+++ b/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebengineclientcertificateselection_p.h"
@@ -162,7 +126,7 @@ QQmlListProperty<QQuickWebEngineClientCertificateOption> QQuickWebEngineClientCe
{
if (m_certificates.empty()) {
QList<QSslCertificate> certificates = d_ptr->certificates();
- for (int i = 0; i < certificates.count(); ++i)
+ for (int i = 0; i < certificates.size(); ++i)
m_certificates.push_back(new QQuickWebEngineClientCertificateOption(this, i));
}
@@ -221,3 +185,5 @@ QUrl QQuickWebEngineClientCertificateSelection::host() const
}
QT_END_NAMESPACE
+
+#include "moc_qquickwebengineclientcertificateselection_p.cpp"
diff --git a/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h b/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h
index c32f4077b..2e0450f8e 100644
--- a/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h
+++ b/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINECERTSELECTION_P_H
#define QQUICKWEBENGINECERTSELECTION_P_H
@@ -69,7 +33,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineClientCertificateSelection;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineClientCertificateOption : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineClientCertificateOption : public QObject {
Q_OBJECT
Q_PROPERTY(QString issuer READ issuer CONSTANT FINAL)
Q_PROPERTY(QString subject READ subject CONSTANT FINAL)
@@ -98,7 +62,7 @@ private:
int m_index;
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineClientCertificateSelection : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineClientCertificateSelection : public QObject {
Q_OBJECT
Q_PROPERTY(QUrl host READ host CONSTANT FINAL)
Q_PROPERTY(QQmlListProperty<QQuickWebEngineClientCertificateOption> certificates READ certificates CONSTANT FINAL)
diff --git a/src/webenginequick/api/qquickwebenginedialogrequests.cpp b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
index 3489eab31..d49f17397 100644
--- a/src/webenginequick/api/qquickwebenginedialogrequests.cpp
+++ b/src/webenginequick/api/qquickwebenginedialogrequests.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginedialogrequests_p.h"
#include "authentication_dialog_controller.h"
@@ -721,6 +685,35 @@ void QQuickWebEngineFileDialogRequest::dialogReject()
\since QtWebEngine 1.10
\brief A request for showing a tooltip to the user.
+
+ A TooltipRequest is a request object that is passed as a
+ parameter of the WebEngineView::tooltipRequested signal. Use the
+ \c onTooltipRequested signal handler to handle requests for
+ custom tooltip menus at specific positions.
+
+ The \l accepted property of the request indicates whether the request
+ is handled by the user code or the default tooltip should
+ be displayed.
+
+ The following code uses a custom tooltip to handle the request:
+
+ \code
+ WebEngineView {
+ // ...
+ onTooltipRequested: function(request) {
+ if (request.type == TooltipRequest.Show) {
+ tooltip.visible = true;
+ tooltip.x = request.x;
+ tooltip.y = request.y;
+ tooltip.text = request.text;
+ } else {
+ tooltip.visible = false;
+ }
+ request.accepted = true;
+ }
+ // ...
+ }
+ \endcode
*/
QQuickWebEngineTooltipRequest::QQuickWebEngineTooltipRequest(
@@ -820,3 +813,5 @@ void QQuickWebEngineTooltipRequest::setAccepted(bool accepted)
}
QT_END_NAMESPACE
+
+#include "moc_qquickwebenginedialogrequests_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginedialogrequests_p.h b/src/webenginequick/api/qquickwebenginedialogrequests_p.h
index 2e99d6fc7..d33a14df4 100644
--- a/src/webenginequick/api/qquickwebenginedialogrequests_p.h
+++ b/src/webenginequick/api/qquickwebenginedialogrequests_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINDIALOGREQUESTS_P_H
#define QQUICKWEBENGINDIALOGREQUESTS_P_H
@@ -52,6 +16,7 @@
//
#include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
+#include <QtCore/qobject.h>
#include <QtCore/qpoint.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qurl.h>
@@ -67,7 +32,7 @@ namespace QtWebEngineCore {
QT_BEGIN_NAMESPACE
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineAuthenticationDialogRequest : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineAuthenticationDialogRequest : public QObject {
Q_OBJECT
public:
@@ -114,7 +79,7 @@ private:
Q_DISABLE_COPY(QQuickWebEngineAuthenticationDialogRequest)
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineJavaScriptDialogRequest : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineJavaScriptDialogRequest : public QObject {
Q_OBJECT
public:
@@ -165,7 +130,7 @@ private:
Q_DISABLE_COPY(QQuickWebEngineJavaScriptDialogRequest)
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineColorDialogRequest : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineColorDialogRequest : public QObject {
Q_OBJECT
public:
@@ -196,7 +161,7 @@ private:
Q_DISABLE_COPY(QQuickWebEngineColorDialogRequest)
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineFileDialogRequest : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineFileDialogRequest : public QObject {
Q_OBJECT
public:
@@ -241,7 +206,7 @@ private:
Q_DISABLE_COPY(QQuickWebEngineFileDialogRequest)
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineTooltipRequest : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineTooltipRequest : public QObject {
Q_OBJECT
public:
enum RequestType {
diff --git a/src/webenginequick/api/qquickwebenginedownloadrequest.cpp b/src/webenginequick/api/qquickwebenginedownloadrequest.cpp
index bd3383004..f745ba3b3 100644
--- a/src/webenginequick/api/qquickwebenginedownloadrequest.cpp
+++ b/src/webenginequick/api/qquickwebenginedownloadrequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginedownloadrequest_p.h"
#include "QtWebEngineCore/private/qwebenginedownloadrequest_p.h"
@@ -64,3 +28,5 @@ QQuickWebEngineView *QQuickWebEngineDownloadRequest::view() const
}
QT_END_NAMESPACE
+
+#include "moc_qquickwebenginedownloadrequest_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginedownloadrequest_p.h b/src/webenginequick/api/qquickwebenginedownloadrequest_p.h
index bc0731326..42a0d88ba 100644
--- a/src/webenginequick/api/qquickwebenginedownloadrequest_p.h
+++ b/src/webenginequick/api/qquickwebenginedownloadrequest_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEDOWNLOADREQUEST_P_H
#define QQUICKWEBENGINEDOWNLOADREQUEST_P_H
@@ -60,7 +24,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineProfilePrivate;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineDownloadRequest : public QWebEngineDownloadRequest
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineDownloadRequest : public QWebEngineDownloadRequest
{
Q_OBJECT
public:
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
index ee3b9bd6a..56bbb97ac 100644
--- a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
+++ b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginefaviconprovider_p_p.h"
@@ -71,9 +35,9 @@ static QSize largestSize(const QList<QSize> &availableSizes)
static QSize fitSize(const QList<QSize> &availableSizes, const QSize &requestedSize)
{
- Q_ASSERT(availableSizes.count());
+ Q_ASSERT(availableSizes.size());
QSize result = largestSize(availableSizes);
- if (availableSizes.count() == 1 || area(requestedSize) >= area(result))
+ if (availableSizes.size() == 1 || area(requestedSize) >= area(result))
return result;
for (const QSize &size : availableSizes) {
@@ -289,3 +253,5 @@ QQuickWebEngineFaviconProvider::requestImageResponse(const QString &id, const QS
}
QT_END_NAMESPACE
+
+#include "moc_qquickwebenginefaviconprovider_p_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
index 94007bc94..89bfb6e73 100644
--- a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
+++ b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEFAVICONPROVIDER_P_P_H
#define QQUICKWEBENGINEFAVICONPROVIDER_P_P_H
@@ -103,7 +67,7 @@ private:
QImage m_image;
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineFaviconProvider : public QQuickAsyncImageProvider
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineFaviconProvider : public QQuickAsyncImageProvider
{
public:
static QString identifier();
diff --git a/src/webenginequick/api/qquickwebengineforeigntypes_p.h b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
index 0cee5f197..2d205254e 100644
--- a/src/webenginequick/api/qquickwebengineforeigntypes_p.h
+++ b/src/webenginequick/api/qquickwebengineforeigntypes_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEFOREIGNTYPES_H
@@ -66,13 +30,22 @@
#include <QtWebEngineCore/qwebenginefullscreenrequest.h>
#include <QtWebEngineCore/qwebenginecontextmenurequest.h>
#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
+#include <QtWebEngineCore/qwebenginefilesystemaccessrequest.h>
+#include <QtWebEngineCore/qwebenginewebauthuxrequest.h>
QT_BEGIN_NAMESPACE
+// To prevent the same type from being exported twice into qmltypes
+// (for value type and for the enums)
+struct QWebEngineLoadingInfoDerived : public QWebEngineLoadingInfo
+{
+ Q_GADGET
+};
+
namespace ForeignWebEngineLoadingInfoNamespace
{
Q_NAMESPACE
- QML_FOREIGN_NAMESPACE(QWebEngineLoadingInfo)
+ QML_FOREIGN_NAMESPACE(QWebEngineLoadingInfoDerived)
QML_NAMED_ELEMENT(WebEngineLoadingInfo)
QML_ADDED_IN_VERSION(1, 1)
QML_EXTRA_VERSION(2, 0)
@@ -88,10 +61,17 @@ struct ForeignWebEngineLoadingInfo
QML_UNCREATABLE("")
};
+// To prevent the same type from being exported twice into qmltypes
+// (for value type and for the enums)
+struct QWebEngineCertificateErrorDerived : public QWebEngineCertificateError
+{
+ Q_GADGET
+};
+
namespace ForeignWebEngineCertificateErrorNamespace
{
Q_NAMESPACE
- QML_FOREIGN_NAMESPACE(QWebEngineCertificateError)
+ QML_FOREIGN_NAMESPACE(QWebEngineCertificateErrorDerived)
QML_NAMED_ELEMENT(WebEngineCertificateError)
QML_ADDED_IN_VERSION(1, 1)
QML_EXTRA_VERSION(2, 0)
@@ -176,6 +156,7 @@ struct ForeignWebEngineContextMenuRequest
QML_UNCREATABLE("")
};
+#if QT_DEPRECATED_SINCE(6, 5)
struct ForeignWebEngineQuotaRequest
{
Q_GADGET
@@ -185,6 +166,7 @@ struct ForeignWebEngineQuotaRequest
QML_EXTRA_VERSION(2, 0)
QML_UNCREATABLE("")
};
+#endif
struct ForeignWebEngineRegisterProtocolHandlerRequest
{
@@ -216,6 +198,39 @@ struct ForeignWebEngineFindTextResult
QML_UNCREATABLE("")
};
+struct ForeginWebEngineFileSystemAccessRequest
+{
+ Q_GADGET
+ QML_FOREIGN(QWebEngineFileSystemAccessRequest)
+ QML_NAMED_ELEMENT(webEngineFileSystemAccessRequest)
+ QML_ADDED_IN_VERSION(6, 4)
+ QML_UNCREATABLE("")
+};
+
+// To prevent the same type from being exported twice into qmltypes
+// (for value type and for the enums)
+struct QWebEngineFileSystemAccessRequestDerived : public QWebEngineFileSystemAccessRequest
+{
+ Q_GADGET
+};
+
+namespace ForeginWebEngineFileSystemAccessRequestNamespace
+{
+ Q_NAMESPACE
+ QML_FOREIGN_NAMESPACE(QWebEngineFileSystemAccessRequestDerived)
+ QML_NAMED_ELEMENT(WebEngineFileSystemAccessRequest)
+ QML_ADDED_IN_VERSION(6, 4)
+};
+
+struct ForeignWebEngineWebAuthUxRequest
+{
+ Q_GADGET
+ QML_FOREIGN(QWebEngineWebAuthUxRequest)
+ QML_NAMED_ELEMENT(WebEngineWebAuthUxRequest)
+ QML_ADDED_IN_VERSION(6, 7)
+ QML_UNCREATABLE("")
+};
+
QT_END_NAMESPACE
#endif // QQUICKWEBENGINEFOREIGNTYPES_H
diff --git a/src/webenginequick/api/qquickwebenginenewwindowrequest.cpp b/src/webenginequick/api/qquickwebenginenewwindowrequest.cpp
index fb36babfa..ecacb1e8f 100644
--- a/src/webenginequick/api/qquickwebenginenewwindowrequest.cpp
+++ b/src/webenginequick/api/qquickwebenginenewwindowrequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginenewwindowrequest_p.h"
#include "qquickwebengineview_p.h"
@@ -75,3 +39,5 @@ void QQuickWebEngineNewWindowRequest::openIn(QQuickWebEngineView *view)
}
QT_END_NAMESPACE
+
+#include "moc_qquickwebenginenewwindowrequest_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h b/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h
index df5e7234b..f170fa0c6 100644
--- a/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h
+++ b/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINENEWVIEWREQUEST_P_H
#define QQUICKWEBENGINENEWVIEWREQUEST_P_H
@@ -59,7 +23,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineView;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineNewWindowRequest : public QWebEngineNewWindowRequest
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineNewWindowRequest : public QWebEngineNewWindowRequest
{
Q_OBJECT
public:
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 6944de95f..7c3d11fcf 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -1,47 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebengineprofile.h"
#include "qquickwebengineprofile_p.h"
#include "qquickwebenginedownloadrequest_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginescriptcollection_p.h"
+#include "qquickwebenginescriptcollection_p_p.h"
#include "qquickwebengineview_p_p.h"
#include "profile_adapter.h"
@@ -49,6 +14,7 @@
#include <QtWebEngineCore/qwebenginescriptcollection.h>
#include <QtWebEngineCore/private/qwebenginescriptcollection_p.h>
+#include <QtWebEngineCore/qwebengineclienthints.h>
#include <QtWebEngineCore/qwebenginecookiestore.h>
#include <QtWebEngineCore/qwebenginenotification.h>
#include <QtWebEngineCore/private/qwebenginedownloadrequest_p.h>
@@ -56,6 +22,7 @@
#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
+#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlengine.h>
using QtWebEngineCore::ProfileAdapter;
@@ -158,11 +125,19 @@ QT_BEGIN_NAMESPACE
\sa WebEngineProfile::presentNotification
*/
+/*!
+ \fn QQuickWebEngineProfile::clearHttpCacheCompleted()
+ \since 6.7
+
+ This signal is emitted when the clearHttpCache() operation is completed.
+
+ \sa clearHttpCache()
+*/
+
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter)
: m_settings(new QQuickWebEngineSettings())
+ , m_clientHints(new QWebEngineClientHints(profileAdapter))
, m_profileAdapter(profileAdapter)
- , m_scriptCollection(new QQuickWebEngineScriptCollection(new QWebEngineScriptCollection(
- new QWebEngineScriptCollectionPrivate(profileAdapter->userResourceController()))))
{
profileAdapter->addClient(this);
// Fullscreen API was implemented before the supported setting, so we must
@@ -181,6 +156,8 @@ QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter())
delete m_profileAdapter;
+ else if (m_profileAdapter)
+ m_profileAdapter->releaseAllWebContentsAdapterClients();
}
void QQuickWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
@@ -205,6 +182,11 @@ QQuickWebEngineSettings *QQuickWebEngineProfilePrivate::settings() const
return m_settings.data();
}
+QtWebEngineCore::WebEngineSettings *QQuickWebEngineProfilePrivate::coreSettings() const
+{
+ return QtWebEngineCore::WebEngineSettings::get(m_settings->d_ptr.data());
+}
+
void QQuickWebEngineProfilePrivate::cancelDownload(quint32 downloadId)
{
if (m_profileAdapter)
@@ -238,10 +220,13 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_Q(QQuickWebEngineProfile);
Q_ASSERT(!m_ongoingDownloads.contains(info.id));
- QWebEngineDownloadRequestPrivate *itemPrivate = new QWebEngineDownloadRequestPrivate(m_profileAdapter, info.url);
+ QWebEngineDownloadRequestPrivate *itemPrivate =
+ new QWebEngineDownloadRequestPrivate(m_profileAdapter);
itemPrivate->downloadId = info.id;
- itemPrivate->downloadState = QWebEngineDownloadRequest::DownloadRequested;
+ itemPrivate->downloadState = info.accepted ? QWebEngineDownloadRequest::DownloadInProgress
+ : QWebEngineDownloadRequest::DownloadRequested;
itemPrivate->startTime = info.startTime;
+ itemPrivate->downloadUrl = info.url;
itemPrivate->totalBytes = info.totalBytes;
itemPrivate->mimeType = info.mimeType;
itemPrivate->downloadDirectory = QFileInfo(info.path).path();
@@ -305,6 +290,27 @@ void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineC
Q_EMIT q->presentNotification(notification);
}
+void QQuickWebEngineProfilePrivate::clearHttpCacheCompleted()
+{
+ Q_Q(QQuickWebEngineProfile);
+ Q_EMIT q->clearHttpCacheCompleted();
+}
+
+QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts()
+{
+ Q_Q(QQuickWebEngineProfile);
+ if (!m_scriptCollection)
+ m_scriptCollection.reset(
+ new QQuickWebEngineScriptCollection(
+ new QQuickWebEngineScriptCollectionPrivate(
+ new QWebEngineScriptCollectionPrivate(
+ m_profileAdapter->userResourceController()))));
+
+ if (!m_scriptCollection->qmlEngine())
+ m_scriptCollection->setQmlEngine(qmlEngine(q));
+
+ return m_scriptCollection.data();
+}
/*!
\qmltype WebEngineProfile
\instantiates QQuickWebEngineProfile
@@ -336,16 +342,16 @@ void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineC
*/
/*!
- \qmlsignal WebEngineProfile::downloadRequested(WebEngineDownloadItem download)
+ \qmlsignal WebEngineProfile::downloadRequested(WebEngineDownloadRequest 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 WebEngineDownloadItem::accept() or the
+ The download has to be explicitly accepted with WebEngineDownloadRequest::accept() or the
download will be cancelled by default.
*/
/*!
- \qmlsignal WebEngineProfile::downloadFinished(WebEngineDownloadItem download)
+ \qmlsignal WebEngineProfile::downloadFinished(WebEngineDownloadRequest download)
This signal is emitted whenever downloading stops, because it finished successfully, was
cancelled, or was interrupted (for example, because connectivity was lost).
@@ -362,6 +368,15 @@ void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineC
*/
/*!
+ \qmlsignal WebEngineProfile::clearHttpCacheCompleted()
+ \since QtWebEngine 6.7
+
+ This signal is emitted when the clearHttpCache() operation is completed.
+
+ \sa clearHttpCache()
+*/
+
+/*!
Constructs a new profile with the parent \a parent.
*/
QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
@@ -432,7 +447,7 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
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.
+ to be stored only in memory. Profile is off-the-record by default.
*/
@@ -441,7 +456,7 @@ void QQuickWebEngineProfile::setStorageName(const QString &name)
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.
+ to be stored only in memory. Profile is off-the-record by default.
*/
bool QQuickWebEngineProfile::isOffTheRecord() const
@@ -472,7 +487,7 @@ void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
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
+ QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) in a directory named using
storageName.
*/
@@ -483,7 +498,7 @@ void QQuickWebEngineProfile::setOffTheRecord(bool offTheRecord)
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
+ QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) in a directory named using
storageName.
*/
@@ -576,9 +591,9 @@ void QQuickWebEngineProfile::setHttpUserAgent(const QString &userAgent)
\value WebEngineProfile.MemoryHttpCache
Uses an in-memory cache. This is the only setting possible if offTheRecord is set or
- no persistentStoragePath is available.
+ no storageName is available, which is the default.
\value WebEngineProfile.DiskHttpCache
- Uses a disk cache. This is the default value.
+ Uses a disk cache. This is the default value for non off-the-record profile with storageName.
\value WebEngineProfile.NoCache
Disables caching. (Added in 5.7)
*/
@@ -588,7 +603,7 @@ void QQuickWebEngineProfile::setHttpUserAgent(const QString &userAgent)
This enumeration describes the type of the HTTP cache.
- If the profile is off-the-record, MemoryHttpCache is returned.
+ If the profile is off-the-record or has no storageName set, MemoryHttpCache is returned.
*/
QQuickWebEngineProfile::HttpCacheType QQuickWebEngineProfile::httpCacheType() const
@@ -613,10 +628,11 @@ void QQuickWebEngineProfile::setHttpCacheType(QQuickWebEngineProfile::HttpCacheT
\value WebEngineProfile.NoPersistentCookies
Both session and persistent cookies are stored in memory. This is the only setting
- possible if offTheRecord is set or no persistentStoragePath is available.
+ possible if offTheRecord is set or no storageName is available, which is the default.
\value WebEngineProfile.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.
+ are only stored to disk for crash recovery.
+ This is the default value for non off-the-record profile with storageName.
\value WebEngineProfile.ForcePersistentCookies
Both session and persistent cookies are saved to and restored from disk.
*/
@@ -708,7 +724,7 @@ void QQuickWebEngineProfile::setHttpAcceptLanguage(const QString &httpAcceptLang
/*!
Returns the default profile.
- The default profile uses the storage name "Default".
+ The default profile is off-the-record.
\sa storageName()
*/
@@ -834,6 +850,41 @@ QString QQuickWebEngineProfile::downloadPath() const
}
/*!
+ \qmlproperty bool WebEngineProfile::isPushServiceEnabled
+ \since QtWebEngine 6.5
+
+ Whether the push messaging service is enabled.
+ \note By default the push messaging service is disabled.
+ \note \QWE uses the \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)} as a browser push service.
+ Therefore, all push messages will go through the Google push service and its respective servers.
+*/
+
+/*!
+ \property QQuickWebEngineProfile::isPushServiceEnabled
+ \since QtWebEngine 6.5
+
+ Whether the push messaging service is enabled.
+ \note By default the push messaging service is disabled.
+ \note \QWE uses the \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)} as a browser push service.
+ Therefore, all push messages will go through the Google push service and its respective servers.
+*/
+
+bool QQuickWebEngineProfile::isPushServiceEnabled() const
+{
+ const Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->pushServiceEnabled();
+}
+
+void QQuickWebEngineProfile::setPushServiceEnabled(bool enabled)
+{
+ Q_D(QQuickWebEngineProfile);
+ if (isPushServiceEnabled() == enabled)
+ return;
+ d->profileAdapter()->setPushServiceEnabled(enabled);
+ emit pushServiceEnabledChanged();
+}
+
+/*!
Returns the cookie store for this profile.
*/
@@ -849,7 +900,11 @@ QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const
Removes the profile's cache entries.
- \sa WebEngineProfile::cachePath
+ \note Make sure that you do not start new navigation or any operation on the profile while
+ the clear operation is in progress. The clearHttpCacheCompleted() signal notifies about the
+ completion.
+
+ \sa WebEngineProfile::cachePath clearHttpCacheCompleted()
*/
/*!
@@ -857,7 +912,11 @@ QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const
Removes the profile's cache entries.
- \sa WebEngineProfile::clearHttpCache
+ \note Make sure that you do not start new navigation or any operation on the profile while
+ the clear operation is in progress. The clearHttpCacheCompleted() signal notifies about the
+ completion.
+
+ \sa WebEngineProfile::clearHttpCache() clearHttpCacheCompleted()
*/
void QQuickWebEngineProfile::clearHttpCache()
{
@@ -938,7 +997,7 @@ QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
}
/*!
- \qmlproperty list<WebEngineScript> WebEngineProfile::userScripts
+ \qmlproperty WebEngineScriptCollection WebEngineProfile::userScripts
\since 1.5
Returns the collection of WebEngineScript objects that are injected into
@@ -947,8 +1006,7 @@ QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
QQuickWebEngineScriptCollection *QQuickWebEngineProfile::userScripts() const
{
- const Q_D(QQuickWebEngineProfile);
- return d->m_scriptCollection.data();
+ return d_ptr->getUserScripts();
}
/*!
@@ -966,6 +1024,26 @@ QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore
#endif
}
+/*!
+ Return the Client Hints settings associated with this browsing context.
+
+ \since 6.8
+ \sa QWebEngineClientHints
+*/
+QWebEngineClientHints *QQuickWebEngineProfile::clientHints() const
+{
+ Q_D(const QQuickWebEngineProfile);
+ return d->m_clientHints.data();
+}
+
+void QQuickWebEngineProfile::ensureQmlContext(const QObject *object)
+{
+ if (!qmlContext(this)) {
+ auto engine = qmlEngine(object);
+ QQmlEngine::setContextForObject(this, new QQmlContext(engine, engine));
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qquickwebengineprofile.cpp"
diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index e594b5982..088a971e0 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEPROFILE_H
#define QQUICKWEBENGINEPROFILE_H
@@ -51,6 +15,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineDownloadRequest;
class QQuickWebEngineSettings;
class QWebEngineClientCertificateStore;
+class QWebEngineClientHints;
class QWebEngineCookieStore;
class QWebEngineNotification;
class QWebEngineUrlRequestInterceptor;
@@ -73,6 +38,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject {
Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION(1,3))
Q_PROPERTY(QQuickWebEngineScriptCollection *userScripts READ userScripts)
Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged FINAL REVISION(1,5))
+ Q_PROPERTY(bool isPushServiceEnabled READ isPushServiceEnabled WRITE setPushServiceEnabled NOTIFY pushServiceEnabledChanged FINAL REVISION(6,5))
QML_NAMED_ELEMENT(WebEngineProfile)
QML_ADDED_IN_VERSION(1, 1)
QML_EXTRA_VERSION(2, 0)
@@ -144,7 +110,11 @@ public:
QString downloadPath() const;
void setDownloadPath(const QString &path);
+ bool isPushServiceEnabled() const;
+ void setPushServiceEnabled(bool enable);
+
QWebEngineClientCertificateStore *clientCertificateStore();
+ QWebEngineClientHints *clientHints() const;
static QQuickWebEngineProfile *defaultProfile();
@@ -161,6 +131,8 @@ Q_SIGNALS:
Q_REVISION(1,3) void spellCheckLanguagesChanged();
Q_REVISION(1,3) void spellCheckEnabledChanged();
Q_REVISION(1,5) void downloadPathChanged();
+ Q_REVISION(6,5) void pushServiceEnabledChanged();
+ Q_REVISION(6,7) void clearHttpCacheCompleted();
void downloadRequested(QQuickWebEngineDownloadRequest *download);
void downloadFinished(QQuickWebEngineDownloadRequest *download);
@@ -170,6 +142,7 @@ private:
Q_DECLARE_PRIVATE(QQuickWebEngineProfile)
QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *, QObject *parent = nullptr);
QQuickWebEngineSettings *settings() const;
+ void ensureQmlContext(const QObject *object);
friend class FaviconImageResponseRunnable;
friend class QQuickWebEngineSingleton;
diff --git a/src/webenginequick/api/qquickwebengineprofile_p.h b/src/webenginequick/api/qquickwebengineprofile_p.h
index 5ff3c6913..477936f98 100644
--- a/src/webenginequick/api/qquickwebengineprofile_p.h
+++ b/src/webenginequick/api/qquickwebengineprofile_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEPROFILE_P_H
#define QQUICKWEBENGINEPROFILE_P_H
@@ -64,6 +28,7 @@ class ProfileAdapter;
QT_BEGIN_NAMESPACE
+class QWebEngineClientHints;
class QQuickWebEngineDownloadRequest;
class QQuickWebEngineSettings;
class QQuickWebEngineScriptCollection;
@@ -78,6 +43,7 @@ public:
QtWebEngineCore::ProfileAdapter* profileAdapter() const;
QQuickWebEngineSettings *settings() const;
+ QtWebEngineCore::WebEngineSettings *coreSettings() const override;
void cancelDownload(quint32 downloadId);
void downloadDestroyed(quint32 downloadId);
@@ -88,14 +54,17 @@ public:
void downloadUpdated(const DownloadItemInfo &info) override;
void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override;
+ void clearHttpCacheCompleted() override;
private:
- friend class QQuickWebEngineView;
QQuickWebEngineProfile *q_ptr;
QScopedPointer<QQuickWebEngineSettings> m_settings;
+ QScopedPointer<QWebEngineClientHints> m_clientHints;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QMap<quint32, QPointer<QQuickWebEngineDownloadRequest> > m_ongoingDownloads;
+
QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection;
+ QQuickWebEngineScriptCollection *getUserScripts();
};
QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebenginescriptcollection.cpp b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
index cc1cfb2fa..a58d97832 100644
--- a/src/webenginequick/api/qquickwebenginescriptcollection.cpp
+++ b/src/webenginequick/api/qquickwebenginescriptcollection.cpp
@@ -1,43 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginescriptcollection_p.h"
+#include "qquickwebenginescriptcollection_p_p.h"
#include "qwebenginescriptcollection.h"
#include <QtWebEngineCore/private/qwebenginescriptcollection_p.h>
#include <QtQml/qqmlinfo.h>
@@ -45,6 +10,61 @@
#include <QtQml/private/qv4scopedvalue_p.h>
#include <QtQml/private/qv4arrayobject_p.h>
+/*!
+ \qmltype WebEngineScriptCollection
+ \brief Manages a collection of user scripts.
+ \since QtWebEngine 6.2
+
+ \inqmlmodule QtWebEngine
+
+ WebEngineScriptCollection handles a user scripts collection, which
+ is injected in the JavaScript engine during the loading of web content.
+
+ Use \l{WebEngineView::userScripts}{WebEgineView.userScripts} and
+ \l{WebEngineProfile::userScripts}{WebEngineProfile.userScripts} to access
+ the collection of scripts associated with a single page or number of pages
+ sharing the same profile.
+
+ The collection of user script objects in QML can be created for a set of
+ user script objects by simple assignment to
+ \l{WebEngineScriptCollection::collection}{WebEngineScriptCollection.collection}
+ property or by WebEngineScriptCollection methods.
+
+ \note The new user script can be instantiated with JavaScript dictionaries when using
+ \e collection property.
+
+ See the following code snippets demonstrating the usage:
+
+ \list
+ \li \e collection property with JavaScript dictionaries
+ \code
+ var scriptFoo = { name: "Foo",
+ sourceUrl: Qt.resolvedUrl("foo.js"),
+ injectionPoint: WebEngineScript.DocumentReady }
+
+ webEngineView.userScripts.collection = [ scriptFoo, scriptBar ];
+ \endcode
+ \li \e collection property with user script object as value type
+ \code
+ var script = WebEngine.script()
+ script.name = "FOO"
+ webEngineView.userScripts.collection = [ script ]
+ \endcode
+ \li user script collection \e insert method can be used only with value type
+ or list of value types
+ \code
+ var script = WebEngine.script()
+ script.name = "FOO"
+ webEngineView.userScripts.insert(script)
+
+ var list = [ script ]
+ webEngineView.userScripts.insert(list)
+ \endcode
+ \endlist
+ \sa WebEngineScript WebEngineScriptCollection
+
+*/
+
QWebEngineScript parseScript(const QJSValue &value, bool *ok)
{
QWebEngineScript s;
@@ -79,52 +99,107 @@ QWebEngineScript parseScript(const QJSValue &value, bool *ok)
return s;
}
-QQuickWebEngineScriptCollection::QQuickWebEngineScriptCollection(
- QWebEngineScriptCollection *collection)
- : d(collection)
+QQuickWebEngineScriptCollectionPrivate::QQuickWebEngineScriptCollectionPrivate(QWebEngineScriptCollectionPrivate *p)
+ : QWebEngineScriptCollection(p)
+{
+
+}
+
+QQuickWebEngineScriptCollectionPrivate::~QQuickWebEngineScriptCollectionPrivate()
+{
+}
+
+QQuickWebEngineScriptCollection::QQuickWebEngineScriptCollection(QQuickWebEngineScriptCollectionPrivate *p)
+ : d(p)
{
}
QQuickWebEngineScriptCollection::~QQuickWebEngineScriptCollection() { }
+/*!
+ \qmlmethod void WebEngineScriptCollection::contains(WebEngineScript script)
+ \since QtWebEngine 6.2
+ Checks if the specified \a script is in the collection.
+ \sa find()
+*/
+
bool QQuickWebEngineScriptCollection::contains(const QWebEngineScript &value) const
{
return d->contains(value);
}
+/*!
+ \qmlmethod list<WebEngineScript> WebEngineScriptCollection::find(string name)
+ \since QtWebEngine 6.2
+ Returns a list of all user script objects with the given \a name.
+ \sa find()
+*/
QList<QWebEngineScript> QQuickWebEngineScriptCollection::find(const QString &name) const
{
return d->find(name);
}
+/*!
+ \qmlmethod void WebEngineScriptCollection::insert(WebEngineScript script)
+ \since QtWebEngine 6.2
+ Inserts a single \a script into the collection.
+ \sa find()
+*/
void QQuickWebEngineScriptCollection::insert(const QWebEngineScript &s)
{
d->insert(s);
}
+/*!
+ \qmlmethod void WebEngineScriptCollection::insert(list<WebEngineScript> list)
+ \since QtWebEngine 6.2
+ Inserts a \a list of WebEngineScript values into the user script collection.
+ \sa find()
+*/
void QQuickWebEngineScriptCollection::insert(const QList<QWebEngineScript> &list)
{
d->insert(list);
}
+/*!
+ \qmlmethod bool WebEngineScriptCollection::remove(WebEngineScript script)
+ \since QtWebEngine 6.2
+ Returns \c true if a given \a script is removed from the collection.
+ \sa insert()
+*/
bool QQuickWebEngineScriptCollection::remove(const QWebEngineScript &script)
{
return d->remove(script);
}
+/*!
+ \qmlmethod void WebEngineScriptCollection::clear()
+ \since QtWebEngine 6.2
+ Removes all script objects from this collection.
+*/
void QQuickWebEngineScriptCollection::clear()
{
d->clear();
}
+/*!
+ \qmlproperty list<WebEngineScript> WebEngineScriptCollection::collection
+ \since QtWebEngine 6.2
+
+ This property holds a JavaScript array of user script objects. The array can
+ take WebEngineScript basic type or a JavaScript dictionary as values.
+*/
QJSValue QQuickWebEngineScriptCollection::collection() const
{
+ if (!d->m_qmlEngine) {
+ qmlWarning(this) << "Scripts collection doesn't have QML engine set! Undefined value is returned.";
+ return QJSValue();
+ }
+
const QList<QWebEngineScript> &list = d->toList();
- QQmlContext *context = QQmlEngine::contextForObject(this);
- QQmlEngine *engine = context->engine();
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine);
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(d->m_qmlEngine);
QV4::Scope scope(v4);
- QV4::Scoped<QV4::ArrayObject> scriptArray(scope, v4->newArrayObject(list.length()));
+ QV4::Scoped<QV4::ArrayObject> scriptArray(scope, v4->newArrayObject(list.size()));
int i = 0;
for (const auto &val : list) {
QV4::ScopedValue sv(scope, v4->fromVariant(QVariant::fromValue(val)));
@@ -155,3 +230,15 @@ void QQuickWebEngineScriptCollection::setCollection(const QJSValue &scripts)
Q_EMIT collectionChanged();
}
}
+
+QQmlEngine* QQuickWebEngineScriptCollection::qmlEngine()
+{
+ return d->m_qmlEngine;
+}
+
+void QQuickWebEngineScriptCollection::setQmlEngine(QQmlEngine *engine)
+{
+ Q_ASSERT(engine);
+ d->m_qmlEngine = engine;
+}
+#include "moc_qquickwebenginescriptcollection_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginescriptcollection_p.h b/src/webenginequick/api/qquickwebenginescriptcollection_p.h
index 8c5682706..fbcc8dde7 100644
--- a/src/webenginequick/api/qquickwebenginescriptcollection_p.h
+++ b/src/webenginequick/api/qquickwebenginescriptcollection_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINESCRIPTCOLLECTION_H
#define QQUICKWEBENGINESCRIPTCOLLECTION_H
@@ -59,9 +23,10 @@
#include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
QT_BEGIN_NAMESPACE
-class QWebEngineScriptCollection;
+class QQmlEngine;
+class QQuickWebEngineScriptCollectionPrivate;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineScriptCollection : public QObject
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineScriptCollection : public QObject
{
Q_OBJECT
public:
@@ -83,10 +48,12 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QQuickWebEngineScriptCollection)
- QQuickWebEngineScriptCollection(QWebEngineScriptCollection *d);
- QScopedPointer<QWebEngineScriptCollection> d;
+ QQuickWebEngineScriptCollection(QQuickWebEngineScriptCollectionPrivate *d);
+ QScopedPointer<QQuickWebEngineScriptCollectionPrivate> d;
friend class QQuickWebEngineProfilePrivate;
friend class QQuickWebEngineViewPrivate;
+ QQmlEngine* qmlEngine();
+ void setQmlEngine(QQmlEngine *engine);
};
QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebenginescriptcollection_p_p.h b/src/webenginequick/api/qquickwebenginescriptcollection_p_p.h
new file mode 100644
index 000000000..54a9bc16d
--- /dev/null
+++ b/src/webenginequick/api/qquickwebenginescriptcollection_p_p.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKWEBENGINESCRIPTCOLLECTIONPRIVATE_H
+#define QQUICKWEBENGINESCRIPTCOLLECTIONPRIVATE_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/qwebenginescriptcollection.h>
+
+#include <QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngine;
+
+class QQuickWebEngineScriptCollectionPrivate : public QWebEngineScriptCollection
+{
+public:
+ QQuickWebEngineScriptCollectionPrivate(QWebEngineScriptCollectionPrivate *d);
+ ~QQuickWebEngineScriptCollectionPrivate();
+
+ Q_DISABLE_COPY(QQuickWebEngineScriptCollectionPrivate)
+ QPointer<QQmlEngine> m_qmlEngine;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index f453fc746..31ed7a661 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebengineprofile.h"
#include "qquickwebenginesettings_p.h"
@@ -113,6 +77,10 @@ bool QQuickWebEngineSettings::javascriptCanOpenWindows() const
To enable also the pasting of clipboard content from JavaScript,
use javascriptCanPaste.
+ Since unrestricted clipboard access is a potential security concern, it is
+ recommended that applications leave this disabled and instead respond to
+ \l{WebEngineView::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
+
Disabled by default.
*/
bool QQuickWebEngineSettings::javascriptCanAccessClipboard() const
@@ -419,6 +387,10 @@ bool QQuickWebEngineSettings::webRTCPublicInterfacesOnly() const
Enables JavaScript \c{execCommand("paste")}.
This also requires enabling javascriptCanAccessClipboard.
+ Since unrestricted clipboard access is a potential security concern, it is
+ recommended that applications leave this disabled and instead respond to
+ \l{WebEngineView::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests.
+
Disabled by default.
*/
bool QQuickWebEngineSettings::javascriptCanPaste() const
@@ -455,6 +427,62 @@ bool QQuickWebEngineSettings::pdfViewerEnabled() const
}
/*!
+ \qmlproperty bool WebEngineSettings::navigateOnDropEnabled
+ \since QtWebEngine 6.4
+
+ Specifies that navigations can be triggered by dropping URLs on
+ the view.
+
+ Enabled by default.
+*/
+bool QQuickWebEngineSettings::navigateOnDropEnabled() const
+{
+ return d_ptr->testAttribute(QWebEngineSettings::NavigateOnDropEnabled);
+}
+
+/*!
+ \qmlproperty bool WebEngineSettings::readingFromCanvasEnabled
+ \since QtWebEngine 6.6
+
+ Specifies that reading from all canvas elements is enabled.
+
+ This setting will have impact on all HTML5 canvas elements irrespective of origin, and can be disabled
+ to prevent canvas fingerprinting.
+
+ Enabled by default.
+ */
+bool QQuickWebEngineSettings::readingFromCanvasEnabled() const
+{
+ return d_ptr->testAttribute(QWebEngineSettings::ReadingFromCanvasEnabled);
+}
+
+/*!
+ \qmlproperty bool WebEngineSettings::forceDarkMode
+ \since QtWebEngine 6.7
+
+ Automatically render all web contents using a dark theme.
+
+ Disabled by default.
+ */
+bool QQuickWebEngineSettings::forceDarkMode() const
+{
+ return d_ptr->testAttribute(QWebEngineSettings::ForceDarkMode);
+}
+
+/*!
+ \qmlproperty bool WebEngineSettings::scrollAnimatorEnabled
+ \since QtWebEngine 6.8
+
+ Enables animated scrolling.
+
+ Disabled by default.
+ */
+bool QQuickWebEngineSettings::scrollAnimatorEnabled() const
+{
+ return d_ptr->testAttribute(QWebEngineSettings::ScrollAnimatorEnabled);
+}
+
+/*!
\qmlproperty string WebEngineSettings::defaultTextEncoding
\since QtWebEngine 1.2
@@ -468,6 +496,33 @@ QString QQuickWebEngineSettings::defaultTextEncoding() const
return d_ptr->defaultTextEncoding();
}
+ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowImageAnimation,
+ QWebEngineSettings::AllowImageAnimation)
+ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AnimateImageOnce, QWebEngineSettings::AnimateImageOnce)
+ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::DisallowImageAnimation,
+ QWebEngineSettings::DisallowImageAnimation)
+/*!
+ \qmlproperty enumeration WebEngineSettings::imageAnimationPolicy
+ \since QtWebEngine 6.8
+
+ Specifies how an image animation should be handled when the image frames
+ are rendered for animation.
+
+ \value WebEngineSettings.AllowImageAnimation
+ Allows all image animations when the image frames are rendered.
+ \value WebEngineSettings.AnimateImageOnce
+ Animate the image once when the image frames are rendered.
+ \value WebEngineSettings.DisallowImageAnimation
+ Disallows all image animations when the image frames are rendered.
+
+ Default value is \c {WebEngineSettings.AllowImageAnimation}.
+*/
+QQuickWebEngineSettings::ImageAnimationPolicy QQuickWebEngineSettings::imageAnimationPolicy() const
+{
+ return static_cast<QQuickWebEngineSettings::ImageAnimationPolicy>(
+ d_ptr->imageAnimationPolicy());
+}
+
ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::DisallowUnknownUrlSchemes, QWebEngineSettings::DisallowUnknownUrlSchemes)
ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction, QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction)
ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowAllUnknownUrlSchemes, QWebEngineSettings::AllowAllUnknownUrlSchemes)
@@ -729,6 +784,38 @@ void QQuickWebEngineSettings::setPdfViewerEnabled(bool on)
Q_EMIT pdfViewerEnabledChanged();
}
+void QQuickWebEngineSettings::setNavigateOnDropEnabled(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(QWebEngineSettings::NavigateOnDropEnabled);
+ d_ptr->setAttribute(QWebEngineSettings::NavigateOnDropEnabled, on);
+ if (wasOn != on)
+ Q_EMIT navigateOnDropEnabledChanged();
+}
+
+void QQuickWebEngineSettings::setReadingFromCanvasEnabled(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ReadingFromCanvasEnabled);
+ d_ptr->setAttribute(QWebEngineSettings::ReadingFromCanvasEnabled, on);
+ if (wasOn != on)
+ Q_EMIT readingFromCanvasEnabledChanged();
+}
+
+void QQuickWebEngineSettings::setForceDarkMode(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ForceDarkMode);
+ d_ptr->setAttribute(QWebEngineSettings::ForceDarkMode, on);
+ if (wasOn != on)
+ Q_EMIT forceDarkModeChanged();
+}
+
+void QQuickWebEngineSettings::setScrollAnimatorEnabled(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ScrollAnimatorEnabled);
+ d_ptr->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, on);
+ if (wasOn != on)
+ Q_EMIT scrollAnimatorEnabledChanged();
+}
+
void QQuickWebEngineSettings::setUnknownUrlSchemePolicy(QQuickWebEngineSettings::UnknownUrlSchemePolicy policy)
{
QWebEngineSettings::UnknownUrlSchemePolicy oldPolicy = d_ptr->unknownUrlSchemePolicy();
@@ -751,4 +838,17 @@ void QQuickWebEngineSettings::setParentSettings(QQuickWebEngineSettings *parentS
d_ptr->setParentSettings(parentSettings->d_ptr.data());
}
+void QQuickWebEngineSettings::setImageAnimationPolicy(
+ QQuickWebEngineSettings::ImageAnimationPolicy policy)
+{
+ QWebEngineSettings::ImageAnimationPolicy oldPolicy = d_ptr->imageAnimationPolicy();
+ QWebEngineSettings::ImageAnimationPolicy newPolicy =
+ static_cast<QWebEngineSettings::ImageAnimationPolicy>(policy);
+ d_ptr->setImageAnimationPolicy(newPolicy);
+ if (oldPolicy != newPolicy)
+ Q_EMIT imageAnimationPolicyChanged();
+}
+
QT_END_NAMESPACE
+
+#include "moc_qquickwebenginesettings_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginesettings_p.h b/src/webenginequick/api/qquickwebenginesettings_p.h
index 3f540fa12..ed3c77884 100644
--- a/src/webenginequick/api/qquickwebenginesettings_p.h
+++ b/src/webenginequick/api/qquickwebenginesettings_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINESETTINGS_P_H
#define QQUICKWEBENGINESETTINGS_P_H
@@ -59,7 +23,7 @@
QT_BEGIN_NAMESPACE
class QWebEngineSettings;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineSettings : public QObject {
Q_OBJECT
Q_PROPERTY(bool autoLoadImages READ autoLoadImages WRITE setAutoLoadImages NOTIFY autoLoadImagesChanged FINAL)
Q_PROPERTY(bool javascriptEnabled READ javascriptEnabled WRITE setJavascriptEnabled NOTIFY javascriptEnabledChanged FINAL)
@@ -92,6 +56,11 @@ class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_PROPERTY(bool javascriptCanPaste READ javascriptCanPaste WRITE setJavascriptCanPaste NOTIFY javascriptCanPasteChanged REVISION(1,6) FINAL)
Q_PROPERTY(bool dnsPrefetchEnabled READ dnsPrefetchEnabled WRITE setDnsPrefetchEnabled NOTIFY dnsPrefetchEnabledChanged REVISION(1,7) FINAL)
Q_PROPERTY(bool pdfViewerEnabled READ pdfViewerEnabled WRITE setPdfViewerEnabled NOTIFY pdfViewerEnabledChanged REVISION(1,8) FINAL)
+ Q_PROPERTY(bool navigateOnDropEnabled READ navigateOnDropEnabled WRITE setNavigateOnDropEnabled NOTIFY navigateOnDropEnabledChanged REVISION(6,4) FINAL)
+ Q_PROPERTY(bool readingFromCanvasEnabled READ readingFromCanvasEnabled WRITE setReadingFromCanvasEnabled NOTIFY readingFromCanvasEnabledChanged REVISION(6,6) FINAL)
+ Q_PROPERTY(bool forceDarkMode READ forceDarkMode WRITE setForceDarkMode NOTIFY forceDarkModeChanged REVISION(6,7) FINAL)
+ Q_PROPERTY(bool scrollAnimatorEnabled READ scrollAnimatorEnabled WRITE setScrollAnimatorEnabled NOTIFY scrollAnimatorEnabledChanged REVISION(6,8) FINAL)
+ Q_PROPERTY(ImageAnimationPolicy imageAnimationPolicy READ imageAnimationPolicy WRITE setImageAnimationPolicy NOTIFY imageAnimationPolicyChanged REVISION(6,8) FINAL)
QML_NAMED_ELEMENT(WebEngineSettings)
QML_ADDED_IN_VERSION(1, 1)
QML_EXTRA_VERSION(2, 0)
@@ -105,6 +74,14 @@ public:
Q_ENUM(UnknownUrlSchemePolicy)
+ enum ImageAnimationPolicy {
+ AllowImageAnimation = 1,
+ AnimateImageOnce,
+ DisallowImageAnimation
+ };
+
+ Q_ENUM(ImageAnimationPolicy)
+
~QQuickWebEngineSettings();
bool autoLoadImages() const;
@@ -138,6 +115,11 @@ public:
bool javascriptCanPaste() const;
bool dnsPrefetchEnabled() const;
bool pdfViewerEnabled() const;
+ bool navigateOnDropEnabled() const;
+ bool readingFromCanvasEnabled() const;
+ bool forceDarkMode() const;
+ bool scrollAnimatorEnabled() const;
+ ImageAnimationPolicy imageAnimationPolicy() const;
void setAutoLoadImages(bool on);
void setJavascriptEnabled(bool on);
@@ -170,6 +152,11 @@ public:
void setJavascriptCanPaste(bool on);
void setDnsPrefetchEnabled(bool on);
void setPdfViewerEnabled(bool on);
+ void setNavigateOnDropEnabled(bool on);
+ void setReadingFromCanvasEnabled(bool on);
+ void setForceDarkMode(bool on);
+ void setScrollAnimatorEnabled(bool on);
+ void setImageAnimationPolicy(ImageAnimationPolicy policy);
signals:
void autoLoadImagesChanged();
@@ -203,6 +190,11 @@ signals:
Q_REVISION(1,6) void javascriptCanPasteChanged();
Q_REVISION(1,7) void dnsPrefetchEnabledChanged();
Q_REVISION(1,8) void pdfViewerEnabledChanged();
+ Q_REVISION(6,4) void navigateOnDropEnabledChanged();
+ Q_REVISION(6,6) void readingFromCanvasEnabledChanged();
+ Q_REVISION(6,7) void forceDarkModeChanged();
+ Q_REVISION(6,8) void scrollAnimatorEnabledChanged();
+ Q_REVISION(6,8) void imageAnimationPolicyChanged();
private:
explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = nullptr);
diff --git a/src/webenginequick/api/qquickwebenginesingleton.cpp b/src/webenginequick/api/qquickwebenginesingleton.cpp
index 40ae87a68..a51d2aca4 100644
--- a/src/webenginequick/api/qquickwebenginesingleton.cpp
+++ b/src/webenginequick/api/qquickwebenginesingleton.cpp
@@ -1,46 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebengineprofile.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginesingleton_p.h"
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -87,14 +54,34 @@ QQuickWebEngineSettings *QQuickWebEngineSingleton::settings() const
*/
QQuickWebEngineProfile *QQuickWebEngineSingleton::defaultProfile() const
{
- return QQuickWebEngineProfile::defaultProfile();
+ auto profile = QQuickWebEngineProfile::defaultProfile();
+
+ // MEMO first ever call to default profile will create one without context
+ // it needs something to get qml engine from (WebEngine singleton is created in qml land)
+ profile->ensureQmlContext(this);
+
+ return profile;
}
+/*!
+ \qmlmethod WebEngineScript WebEngine::script
+ //! \instantiates QWebEngineScript
+ \since QtWebEngine 6.2
+
+ Constructs WebEngineScript, which can be set up and inserted into user scripts' collection
+ for \l{WebEngineView::userScripts}{WebEngineView.userScripts} or
+ \l{WebEngineProfile::userScripts}{WebEngineProfile.userScripts}
+ using \l{WebEngineScriptCollection}.
+
+ \sa WebEngineScript WebEngineScriptCollection
+*/
+
QWebEngineScript QQuickWebEngineSingleton::script() const
{
return QWebEngineScript();
}
+QT_END_NAMESPACE
+
#include "moc_qquickwebenginesingleton_p.cpp"
-QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebenginesingleton_p.h b/src/webenginequick/api/qquickwebenginesingleton_p.h
index 84132ed45..b05daecd6 100644
--- a/src/webenginequick/api/qquickwebenginesingleton_p.h
+++ b/src/webenginequick/api/qquickwebenginesingleton_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINESINGLETON_P_H
#define QQUICKWEBENGINESINGLETON_P_H
@@ -61,7 +25,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineSettings;
class QQuickWebEngineProfile;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSingleton : public QObject {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineSingleton : public QObject {
Q_OBJECT
Q_PROPERTY(QQuickWebEngineSettings* settings READ settings CONSTANT FINAL)
Q_PROPERTY(QQuickWebEngineProfile* defaultProfile READ defaultProfile CONSTANT FINAL REVISION(1,1))
diff --git a/src/webenginequick/api/qquickwebenginetouchhandle.cpp b/src/webenginequick/api/qquickwebenginetouchhandle.cpp
new file mode 100644
index 000000000..473463fa3
--- /dev/null
+++ b/src/webenginequick/api/qquickwebenginetouchhandle.cpp
@@ -0,0 +1,45 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickwebenginetouchhandle_p.h"
+#include "qquickwebenginetouchhandleprovider_p_p.h"
+#include "web_contents_adapter_client.h"
+#include <QtQuick/qquickitem.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickWebEngineTouchHandle::QQuickWebEngineTouchHandle() : QObject(nullptr), m_hasImage(false) { }
+
+void QQuickWebEngineTouchHandle::setBounds(const QRect &bounds)
+{
+ m_item->setX(bounds.x());
+ m_item->setY(bounds.y());
+ m_item->setWidth(bounds.width());
+ m_item->setHeight(bounds.height());
+}
+
+void QQuickWebEngineTouchHandle::setOpacity(float opacity)
+{
+ m_item->setOpacity(opacity);
+}
+
+void QQuickWebEngineTouchHandle::setImage(int orientation)
+{
+ if (m_hasImage) {
+ QUrl url = QQuickWebEngineTouchHandleProvider::url(orientation);
+ m_item->setProperty("source", url);
+ }
+}
+
+void QQuickWebEngineTouchHandle::setVisible(bool visible)
+{
+ m_item->setVisible(visible);
+}
+
+void QQuickWebEngineTouchHandle::setItem(QQuickItem *item, bool hasImage)
+{
+ m_hasImage = hasImage;
+ m_item.reset(item);
+}
+
+QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebenginetouchhandle_p.h b/src/webenginequick/api/qquickwebenginetouchhandle_p.h
new file mode 100644
index 000000000..d1deceae3
--- /dev/null
+++ b/src/webenginequick/api/qquickwebenginetouchhandle_p.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKWEBENGINETOUCHHANDLE_P_H
+#define QQUICKWEBENGINETOUCHHANDLE_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 "touch_handle_drawable_client.h"
+#include <QtQml/qqmlregistration.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qobject.h>
+
+namespace QtWebEngineCore {
+class WebContentsAdapterClient;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QQuickItem;
+class QQuickWebEngineTouchHandle : public QtWebEngineCore::TouchHandleDrawableDelegate,
+ public QObject
+{
+public:
+ QQuickWebEngineTouchHandle();
+ void setImage(int orintation) override;
+ void setBounds(const QRect &bounds) override;
+ void setVisible(bool visible) override;
+ void setOpacity(float opacity) override;
+ void setItem(QQuickItem *item, bool hasImage);
+
+private:
+ QScopedPointer<QQuickItem> m_item;
+ bool m_hasImage;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINETOUCHHANDLE_P_H
diff --git a/src/webenginequick/api/qquickwebenginetouchhandleprovider.cpp b/src/webenginequick/api/qquickwebenginetouchhandleprovider.cpp
index d6d6116dd..099fa8876 100644
--- a/src/webenginequick/api/qquickwebenginetouchhandleprovider.cpp
+++ b/src/webenginequick/api/qquickwebenginetouchhandleprovider.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginetouchhandleprovider_p_p.h"
diff --git a/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h b/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h
index b389818fc..92a13b08e 100644
--- a/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h
+++ b/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
#define QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H
@@ -56,7 +20,7 @@
QT_BEGIN_NAMESPACE
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider {
public:
static QString identifier();
static QUrl url(int orientation);
diff --git a/src/webenginequick/api/qquickwebenginetouchselectionmenurequest.cpp b/src/webenginequick/api/qquickwebenginetouchselectionmenurequest.cpp
index f406587d3..70519525d 100644
--- a/src/webenginequick/api/qquickwebenginetouchselectionmenurequest.cpp
+++ b/src/webenginequick/api/qquickwebenginetouchselectionmenurequest.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebenginetouchselectionmenurequest_p.h"
#include "qquickwebenginetouchselectionmenurequest_p_p.h"
@@ -90,7 +54,9 @@ QQuickWebEngineTouchSelectionMenuRequestPrivate::QQuickWebEngineTouchSelectionMe
/*!
Destroys the touch selection menu request.
*/
-QQuickWebEngineTouchSelectionMenuRequest::~QQuickWebEngineTouchSelectionMenuRequest() = default;
+QQuickWebEngineTouchSelectionMenuRequest::~QQuickWebEngineTouchSelectionMenuRequest()
+{
+}
/*!
Returns the number of buttons that must be displayed, based on the available actions.
@@ -138,3 +104,5 @@ QQuickWebEngineTouchSelectionMenuRequest::TouchSelectionCommandFlags QQuickWebEn
}
QT_END_NAMESPACE
+
+#include "moc_qquickwebenginetouchselectionmenurequest_p.cpp"
diff --git a/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p.h b/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p.h
index c6a8fc8c6..c7decafe1 100644
--- a/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p.h
+++ b/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINETOUCHSELECTIONMENUREQUEST_P_H
#define QQUICKWEBENGINETOUCHSELECTIONMENUREQUEST_P_H
@@ -79,13 +43,13 @@ public:
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL)
Q_PROPERTY(QRect selectionBounds READ selectionBounds CONSTANT FINAL REVISION(1))
Q_PROPERTY(TouchSelectionCommandFlags touchSelectionCommandFlags READ touchSelectionCommandFlags CONSTANT FINAL REVISION(1))
- QML_NAMED_ELEMENT(QQuickWebEngineTouchSelectionMenuRequest)
+ QML_NAMED_ELEMENT(TouchSelectionMenuRequest)
QML_ADDED_IN_VERSION(6, 3)
QML_UNCREATABLE("")
QQuickWebEngineTouchSelectionMenuRequest(QRect bounds,
QtWebEngineCore::TouchSelectionMenuController *touchSelectionMenuController);
- virtual ~QQuickWebEngineTouchSelectionMenuRequest();
+ ~QQuickWebEngineTouchSelectionMenuRequest();
int buttonCount();
bool isAccepted() const;
diff --git a/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p_p.h b/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p_p.h
index 9d72e7fee..f8eba652e 100644
--- a/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p_p.h
+++ b/src/webenginequick/api/qquickwebenginetouchselectionmenurequest_p_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINETOUCHSELECTIONMENUREQUEST_P_P_H
#define QQUICKWEBENGINETOUCHSELECTIONMENUREQUEST_P_P_H
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 837aed7e3..31e5d572e 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickwebengineaction_p.h"
#include "qquickwebengineaction_p_p.h"
@@ -46,35 +10,43 @@
#include "qquickwebengineprofile.h"
#include "qquickwebengineprofile_p.h"
#include "qquickwebenginescriptcollection_p.h"
+#include "qquickwebenginescriptcollection_p_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginetouchhandleprovider_p_p.h"
+#include "qquickwebenginetouchhandle_p.h"
#include "qquickwebenginetouchselectionmenurequest_p.h"
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_p.h"
#include "authentication_dialog_controller.h"
+#include "autofill_popup_controller.h"
#include "profile_adapter.h"
#include "file_picker_controller.h"
#include "find_text_helper.h"
#include "javascript_dialog_controller.h"
-#include "render_widget_host_view_qt_delegate_quick.h"
+#include "render_widget_host_view_qt_delegate_item.h"
#include "render_widget_host_view_qt_delegate_quickwindow.h"
#include "touch_selection_menu_controller.h"
#include "ui_delegates_manager.h"
#include "web_contents_adapter.h"
#include <QtWebEngineCore/qwebenginecertificateerror.h>
+#include <QtWebEngineCore/qwebenginedesktopmediarequest.h>
+#include <QtWebEngineCore/qwebenginefilesystemaccessrequest.h>
#include <QtWebEngineCore/qwebenginefindtextresult.h>
#include <QtWebEngineCore/qwebenginefullscreenrequest.h>
#include <QtWebEngineCore/qwebengineloadinginfo.h>
#include <QtWebEngineCore/qwebenginenavigationrequest.h>
-#include <QtWebEngineCore/qwebenginequotarequest.h>
+#include <QtWebEngineCore/qwebenginepage.h>
#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
#include <QtWebEngineCore/qwebenginescriptcollection.h>
+#include <QtWebEngineCore/qwebenginewebauthuxrequest.h>
#include <QtWebEngineCore/private/qwebenginecontextmenurequest_p.h>
+#include <QtWebEngineCore/private/qwebenginedesktopmediarequest_p.h>
#include <QtWebEngineCore/private/qwebenginehistory_p.h>
#include <QtWebEngineCore/private/qwebenginenewwindowrequest_p.h>
#include <QtWebEngineCore/private/qwebenginescriptcollection_p.h>
+#include <QtWebEngineCore/private/qwebenginepage_p.h>
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QtCore/qloggingcategory.h>
@@ -90,6 +62,12 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlproperty.h>
+#if QT_CONFIG(accessibility)
+#include "qquickwebengine_accessible.h"
+
+#include <QtGui/qaccessible.h>
+#endif
+
#if QT_CONFIG(webengine_printing_and_pdf)
#include <QtCore/qmargins.h>
#include <QtGui/qpagelayout.h>
@@ -98,12 +76,15 @@
#endif
#if QT_CONFIG(webengine_webchannel)
-#include <QtWebChannel/qqmlwebchannel.h>
+#include <QtWebChannelQuick/qqmlwebchannel.h>
#endif
QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
+Q_STATIC_ASSERT(int(QQuickWebEngineView::WebActionCount) == int(QWebEnginePage::WebActionCount));
+using LoadStatus = QWebEngineLoadingInfo::LoadStatus;
+using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain;
#if QT_DEPRECATED_SINCE(6, 2)
QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::AcceptRequest) == static_cast<int>(QWebEngineNavigationRequest::AcceptRequest));
@@ -119,9 +100,6 @@ Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInWindow)
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInTab) == static_cast<int>(QWebEngineNewWindowRequest::InNewTab));
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInDialog) == static_cast<int>(QWebEngineNewWindowRequest::InNewDialog));
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInBackgroundTab) == static_cast<int>(QWebEngineNewWindowRequest::InNewBackgroundTab));
-
-using LoadStatus = QWebEngineLoadingInfo::LoadStatus;
-using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain;
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NoErrorDomain) == static_cast<int>(ErrorDomain::NoErrorDomain));
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::InternalErrorDomain) == static_cast<int>(ErrorDomain::InternalErrorDomain));
Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::ConnectionErrorDomain) == static_cast<int>(ErrorDomain::ConnectionErrorDomain));
@@ -136,14 +114,189 @@ Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::LoadSucceededStatus) == st
QT_WARNING_POP
#endif
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(webengine_printing_and_pdf)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Letter, QQuickWebEngineView::PrintedPageSizeId::Letter)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Legal, QQuickWebEngineView::PrintedPageSizeId::Legal)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Executive, QQuickWebEngineView::PrintedPageSizeId::Executive)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A0, QQuickWebEngineView::PrintedPageSizeId::A0)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A1, QQuickWebEngineView::PrintedPageSizeId::A1)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A2, QQuickWebEngineView::PrintedPageSizeId::A2)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A3, QQuickWebEngineView::PrintedPageSizeId::A3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4, QQuickWebEngineView::PrintedPageSizeId::A4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A5, QQuickWebEngineView::PrintedPageSizeId::A5)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A6, QQuickWebEngineView::PrintedPageSizeId::A6)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A7, QQuickWebEngineView::PrintedPageSizeId::A7)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A8, QQuickWebEngineView::PrintedPageSizeId::A8)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A9, QQuickWebEngineView::PrintedPageSizeId::A9)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A10, QQuickWebEngineView::PrintedPageSizeId::A10)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B0, QQuickWebEngineView::PrintedPageSizeId::B0)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B1, QQuickWebEngineView::PrintedPageSizeId::B1)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B2, QQuickWebEngineView::PrintedPageSizeId::B2)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B3, QQuickWebEngineView::PrintedPageSizeId::B3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B4, QQuickWebEngineView::PrintedPageSizeId::B4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B5, QQuickWebEngineView::PrintedPageSizeId::B5)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B6, QQuickWebEngineView::PrintedPageSizeId::B6)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B7, QQuickWebEngineView::PrintedPageSizeId::B7)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B8, QQuickWebEngineView::PrintedPageSizeId::B8)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B9, QQuickWebEngineView::PrintedPageSizeId::B9)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B10, QQuickWebEngineView::PrintedPageSizeId::B10)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::C5E, QQuickWebEngineView::PrintedPageSizeId::C5E)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Comm10E, QQuickWebEngineView::PrintedPageSizeId::Comm10E)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::DLE, QQuickWebEngineView::PrintedPageSizeId::DLE)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Folio, QQuickWebEngineView::PrintedPageSizeId::Folio)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Ledger, QQuickWebEngineView::PrintedPageSizeId::Ledger)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Tabloid, QQuickWebEngineView::PrintedPageSizeId::Tabloid)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Custom, QQuickWebEngineView::PrintedPageSizeId::Custom)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A3Extra, QQuickWebEngineView::PrintedPageSizeId::A3Extra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Extra, QQuickWebEngineView::PrintedPageSizeId::A4Extra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Plus, QQuickWebEngineView::PrintedPageSizeId::A4Plus)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Small, QQuickWebEngineView::PrintedPageSizeId::A4Small)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A5Extra, QQuickWebEngineView::PrintedPageSizeId::A5Extra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B5Extra, QQuickWebEngineView::PrintedPageSizeId::B5Extra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB0, QQuickWebEngineView::PrintedPageSizeId::JisB0)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB1, QQuickWebEngineView::PrintedPageSizeId::JisB1)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB2, QQuickWebEngineView::PrintedPageSizeId::JisB2)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB3, QQuickWebEngineView::PrintedPageSizeId::JisB3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB4, QQuickWebEngineView::PrintedPageSizeId::JisB4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB5, QQuickWebEngineView::PrintedPageSizeId::JisB5)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB6, QQuickWebEngineView::PrintedPageSizeId::JisB6)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB7, QQuickWebEngineView::PrintedPageSizeId::JisB7)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB8, QQuickWebEngineView::PrintedPageSizeId::JisB8)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB9, QQuickWebEngineView::PrintedPageSizeId::JisB9)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB10, QQuickWebEngineView::PrintedPageSizeId::JisB10)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiC, QQuickWebEngineView::PrintedPageSizeId::AnsiC)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiD, QQuickWebEngineView::PrintedPageSizeId::AnsiD)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiE, QQuickWebEngineView::PrintedPageSizeId::AnsiE)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LegalExtra, QQuickWebEngineView::PrintedPageSizeId::LegalExtra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterExtra, QQuickWebEngineView::PrintedPageSizeId::LetterExtra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterPlus, QQuickWebEngineView::PrintedPageSizeId::LetterPlus)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterSmall, QQuickWebEngineView::PrintedPageSizeId::LetterSmall)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::TabloidExtra, QQuickWebEngineView::PrintedPageSizeId::TabloidExtra)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchA, QQuickWebEngineView::PrintedPageSizeId::ArchA)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchB, QQuickWebEngineView::PrintedPageSizeId::ArchB)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchC, QQuickWebEngineView::PrintedPageSizeId::ArchC)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchD, QQuickWebEngineView::PrintedPageSizeId::ArchD)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchE, QQuickWebEngineView::PrintedPageSizeId::ArchE)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial7x9, QQuickWebEngineView::PrintedPageSizeId::Imperial7x9)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial8x10, QQuickWebEngineView::PrintedPageSizeId::Imperial8x10)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial9x11, QQuickWebEngineView::PrintedPageSizeId::Imperial9x11)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial9x12, QQuickWebEngineView::PrintedPageSizeId::Imperial9x12)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x11, QQuickWebEngineView::PrintedPageSizeId::Imperial10x11)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x13, QQuickWebEngineView::PrintedPageSizeId::Imperial10x13)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x14, QQuickWebEngineView::PrintedPageSizeId::Imperial10x14)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial12x11, QQuickWebEngineView::PrintedPageSizeId::Imperial12x11)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial15x11, QQuickWebEngineView::PrintedPageSizeId::Imperial15x11)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ExecutiveStandard, QQuickWebEngineView::PrintedPageSizeId::ExecutiveStandard)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Note, QQuickWebEngineView::PrintedPageSizeId::Note)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Quarto, QQuickWebEngineView::PrintedPageSizeId::Quarto)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Statement, QQuickWebEngineView::PrintedPageSizeId::Statement)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::SuperA, QQuickWebEngineView::PrintedPageSizeId::SuperA)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::SuperB, QQuickWebEngineView::PrintedPageSizeId::SuperB)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Postcard, QQuickWebEngineView::PrintedPageSizeId::Postcard)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::DoublePostcard, QQuickWebEngineView::PrintedPageSizeId::DoublePostcard)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc16K, QQuickWebEngineView::PrintedPageSizeId::Prc16K)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc32K, QQuickWebEngineView::PrintedPageSizeId::Prc32K)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc32KBig, QQuickWebEngineView::PrintedPageSizeId::Prc32KBig)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldUS, QQuickWebEngineView::PrintedPageSizeId::FanFoldUS)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldGerman, QQuickWebEngineView::PrintedPageSizeId::FanFoldGerman)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldGermanLegal, QQuickWebEngineView::PrintedPageSizeId::FanFoldGermanLegal)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB5, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB5)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB6, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB6)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC0, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC0)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC1, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC1)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC2, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC2)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC6, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC6)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC65, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC65)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC7, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC7)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope9, QQuickWebEngineView::PrintedPageSizeId::Envelope9)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope11, QQuickWebEngineView::PrintedPageSizeId::Envelope11)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope12, QQuickWebEngineView::PrintedPageSizeId::Envelope12)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope14, QQuickWebEngineView::PrintedPageSizeId::Envelope14)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeMonarch, QQuickWebEngineView::PrintedPageSizeId::EnvelopeMonarch)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePersonal, QQuickWebEngineView::PrintedPageSizeId::EnvelopePersonal)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeChou3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeChou3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeChou4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeChou4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeInvite, QQuickWebEngineView::PrintedPageSizeId::EnvelopeInvite)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeItalian, QQuickWebEngineView::PrintedPageSizeId::EnvelopeItalian)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeKaku2, QQuickWebEngineView::PrintedPageSizeId::EnvelopeKaku2)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeKaku3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeKaku3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc1, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc1)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc2, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc2)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc3, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc3)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc4, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc5, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc5)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc6, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc6)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc7, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc7)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc8, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc8)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc9, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc9)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc10, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc10)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeYou4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeYou4)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LastPageSize, QQuickWebEngineView::PrintedPageSizeId::LastPageSize)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiA, QQuickWebEngineView::PrintedPageSizeId::AnsiA)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiB, QQuickWebEngineView::PrintedPageSizeId::AnsiB)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC5, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC5)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeDL, QQuickWebEngineView::PrintedPageSizeId::EnvelopeDL)
+ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope10, QQuickWebEngineView::PrintedPageSizeId::Envelope10)
+#endif
+
+class WebEngineQuickWidgetDelegate : public QtWebEngineCore::WidgetDelegate
+{
+public:
+ WebEngineQuickWidgetDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *item, QQuickWebEngineView *parent)
+ : m_contentItem(item)
+ , m_parentView(parent)
+ {
+ }
+
+ ~WebEngineQuickWidgetDelegate() override
+ {
+ if (m_contentItem)
+ m_contentItem->setWidgetDelegate(nullptr);
+ }
+
+ void InitAsPopup(const QRect &screenRect) override
+ {
+ Q_UNUSED(screenRect);
+ Q_UNREACHABLE();
+ }
+
+ void Bind(WebContentsAdapterClient *client) override
+ {
+ QQuickWebEngineViewPrivate::bindViewAndDelegateItem(
+ static_cast<QQuickWebEngineViewPrivate *>(client), m_contentItem);
+ }
+
+ void Unbind() override
+ {
+ QQuickWebEngineViewPrivate::bindViewAndDelegateItem(nullptr, m_contentItem);
+ }
+
+ void Destroy() override
+ {
+ delete this;
+ }
+
+ bool ActiveFocusOnPress() override
+ {
+ return m_parentView->property("activeFocusOnPress").toBool() || m_parentView->hasActiveFocus();
+ }
+
+private:
+ QPointer<RenderWidgetHostViewQtDelegateItem> m_contentItem; // deleted by core
+ QPointer<QQuickWebEngineView> m_parentView;
+};
+
+#if QT_CONFIG(accessibility)
static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object)
{
if (QQuickWebEngineView *v = qobject_cast<QQuickWebEngineView*>(object))
return new QQuickWebEngineViewAccessible(v);
- return 0;
+ return nullptr;
}
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
static QLatin1String defaultMimeType("text/html;charset=UTF-8");
@@ -158,7 +311,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_fullscreenMode(false)
, isLoading(false)
, m_activeFocusOnPress(true)
- , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
, m_webChannel(nullptr)
, m_webChannelWorld(0)
, m_defaultAudioMuted(false)
@@ -167,12 +319,13 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_zoomFactor(1.0)
, m_profileInitialized(false)
, m_contextMenuRequest(nullptr)
+ , m_touchHandleDelegate(nullptr)
{
memset(actions, 0, sizeof(actions));
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::installFactory(&webAccessibleFactory);
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
}
QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
@@ -181,9 +334,7 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
m_profile->d_ptr->removeWebContentsAdapterClient(this);
if (m_faviconProvider)
m_faviconProvider->detach(q_ptr);
- // q_ptr->d_ptr might be null due to destroy()
- if (q_ptr->d_ptr)
- bindViewAndWidget(q_ptr, nullptr);
+ bindViewAndDelegateItem(this, nullptr);
}
void QQuickWebEngineViewPrivate::initializeProfile()
@@ -191,14 +342,18 @@ void QQuickWebEngineViewPrivate::initializeProfile()
if (!m_profileInitialized) {
Q_ASSERT(!adapter->isInitialized());
m_profileInitialized = true;
- if (!m_profile)
+
+ if (!m_profile) {
m_profile = QQuickWebEngineProfile::defaultProfile();
+
+ // MEMO first ever call to default profile will create one without context
+ // it needs something to get qml engine from (and view is created in qml land)
+ m_profile->ensureQmlContext(q_ptr);
+ }
+
m_profile->d_ptr->addWebContentsAdapterClient(this);
m_settings.reset(new QQuickWebEngineSettings(m_profile->settings()));
adapter->setClient(this);
- m_scriptCollection.reset(new QQuickWebEngineScriptCollection(
- new QWebEngineScriptCollection(new QWebEngineScriptCollectionPrivate(
- profileAdapter()->userResourceController(), adapter))));
}
}
@@ -212,8 +367,8 @@ void QQuickWebEngineViewPrivate::releaseProfile()
// The profile for this web contents is about to be
// garbage collected, delete WebContents first and
// let the QQuickWebEngineView be collected later by gc.
- bindViewAndWidget(q_ptr, nullptr);
- delete q_ptr->d_ptr.take();
+ bindViewAndDelegateItem(this, nullptr);
+ q_ptr->d_ptr.reset();
}
UIDelegatesManager *QQuickWebEngineViewPrivate::ui()
@@ -226,22 +381,26 @@ UIDelegatesManager *QQuickWebEngineViewPrivate::ui()
RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
- return new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ false);
+ Q_Q(QQuickWebEngineView);
+ auto *item = new RenderWidgetHostViewQtDelegateItem(client, /*isPopup = */ false);
+ item->setWidgetDelegate(new WebEngineQuickWidgetDelegate(item, q));
+ return item;
}
RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client)
{
Q_Q(QQuickWebEngineView);
const bool hasWindowCapability = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
- RenderWidgetHostViewQtDelegateQuick *quickDelegate = new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ true);
+ RenderWidgetHostViewQtDelegateItem *quickDelegate = new RenderWidgetHostViewQtDelegateItem(client, /*isPopup = */ true);
if (hasWindowCapability) {
RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow =
new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate, q->window());
+ quickDelegate->setWidgetDelegate(wrapperWindow);
wrapperWindow->setVirtualParent(q);
- quickDelegate->setParentItem(wrapperWindow->contentItem());
- return wrapperWindow;
+ return quickDelegate;
}
quickDelegate->setParentItem(q);
+ quickDelegate->setWidgetDelegate(new WebEngineQuickWidgetDelegate(quickDelegate, q));
quickDelegate->show();
return quickDelegate;
}
@@ -333,6 +492,10 @@ static QQuickWebEngineView::Feature toFeature(QtWebEngineCore::ProfileAdapter::P
return QQuickWebEngineView::Notifications;
case QtWebEngineCore::ProfileAdapter::GeolocationPermission:
return QQuickWebEngineView::Geolocation;
+ case QtWebEngineCore::ProfileAdapter::ClipboardReadWrite:
+ return QQuickWebEngineView::ClipboardReadWrite;
+ case QtWebEngineCore::ProfileAdapter::LocalFontsPermission:
+ return QQuickWebEngineView::LocalFontsAccess;
default:
break;
}
@@ -428,6 +591,12 @@ void QQuickWebEngineViewPrivate::selectionChanged()
updateEditActions();
}
+void QQuickWebEngineViewPrivate::zoomUpdateIsNeeded()
+{
+ Q_Q(QQuickWebEngineView);
+ q->setZoomFactor(m_zoomFactor);
+}
+
void QQuickWebEngineViewPrivate::recentlyAudibleChanged(bool recentlyAudible)
{
Q_Q(QQuickWebEngineView);
@@ -545,6 +714,15 @@ void QQuickWebEngineViewPrivate::windowCloseRejected()
QMetaObject::invokeMethod(q, "windowCloseRejected");
}
+void QQuickWebEngineViewPrivate::desktopMediaRequested(
+ QtWebEngineCore::DesktopMediaController *controller)
+{
+ Q_Q(QQuickWebEngineView);
+ QTimer::singleShot(0, q, [q, controller]() {
+ Q_EMIT q->desktopMediaRequested(QWebEngineDesktopMediaRequest(controller));
+ });
+}
+
void QQuickWebEngineViewPrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen)
{
Q_Q(QQuickWebEngineView);
@@ -560,7 +738,7 @@ bool QQuickWebEngineViewPrivate::isFullScreenMode() const
void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
{
Q_Q(QQuickWebEngineView);
- if (q->receivers(SIGNAL(javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) {
+ if (q->receivers(SIGNAL(javaScriptConsoleMessage(QQuickWebEngineView::JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) {
Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
return;
}
@@ -622,16 +800,17 @@ void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &secur
adapter->grantMouseLockPermission(securityOrigin, false);
}
-void QQuickWebEngineViewPrivate::runQuotaRequest(QWebEngineQuotaRequest request)
+void QQuickWebEngineViewPrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
{
Q_Q(QQuickWebEngineView);
- Q_EMIT q->quotaRequested(request);
+ Q_EMIT q->registerProtocolHandlerRequested(request);
}
-void QQuickWebEngineViewPrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
+void QQuickWebEngineViewPrivate::runFileSystemAccessRequest(
+ QWebEngineFileSystemAccessRequest request)
{
Q_Q(QQuickWebEngineView);
- Q_EMIT q->registerProtocolHandlerRequested(request);
+ Q_EMIT q->fileSystemAccessRequested(request);
}
QObject *QQuickWebEngineViewPrivate::accessibilityParentObject()
@@ -664,6 +843,19 @@ void QQuickWebEngineViewPrivate::findTextFinished(const QWebEngineFindTextResult
Q_EMIT q->findTextFinished(result);
}
+void QQuickWebEngineViewPrivate::showAutofillPopup(
+ QtWebEngineCore::AutofillPopupController *controller, const QRect &bounds,
+ bool autoselectFirstSuggestion)
+{
+ ui()->showAutofillPopup(controller, bounds.bottomLeft(), bounds.width() + 2,
+ autoselectFirstSuggestion);
+}
+
+void QQuickWebEngineViewPrivate::hideAutofillPopup()
+{
+ ui()->hideAutofillPopup();
+}
+
QWebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
return m_settings->d_ptr.data();
@@ -694,74 +886,6 @@ void QQuickWebEngineViewPrivate::visibleChanged(bool visible)
Q_UNUSED(visible);
}
-#ifndef QT_NO_ACCESSIBILITY
-QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o)
- : QAccessibleObject(o)
-{}
-
-bool QQuickWebEngineViewAccessible::isValid() const
-{
- if (!QAccessibleObject::isValid())
- return false;
-
- if (!engineView() || !engineView()->d_func())
- return false;
-
- return true;
-}
-
-QAccessibleInterface *QQuickWebEngineViewAccessible::parent() const
-{
- QQuickItem *parent = engineView()->parentItem();
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parent);
- if (!iface)
- return QAccessible::queryAccessibleInterface(engineView()->window());
- return iface;
-}
-
-QAccessibleInterface *QQuickWebEngineViewAccessible::focusChild() const
-{
- if (child(0) && child(0)->focusChild())
- return child(0)->focusChild();
- return const_cast<QQuickWebEngineViewAccessible *>(this);
-}
-
-int QQuickWebEngineViewAccessible::childCount() const
-{
- return child(0) ? 1 : 0;
-}
-
-QAccessibleInterface *QQuickWebEngineViewAccessible::child(int index) const
-{
- if (index == 0 && isValid())
- return engineView()->d_func()->adapter->browserAccessible();
- return nullptr;
-}
-
-int QQuickWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- if (child(0) && c == child(0))
- return 0;
- return -1;
-}
-
-QString QQuickWebEngineViewAccessible::text(QAccessible::Text) const
-{
- return QString();
-}
-
-QAccessible::Role QQuickWebEngineViewAccessible::role() const
-{
- return QAccessible::Client;
-}
-
-QAccessible::State QQuickWebEngineViewAccessible::state() const
-{
- QAccessible::State s;
- return s;
-}
-#endif // QT_NO_ACCESSIBILITY
-
class WebContentsAdapterOwner : public QObject
{
public:
@@ -811,6 +935,8 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
QQuickWebEngineView::~QQuickWebEngineView()
{
+ if (hasFocus())
+ setFocus(false);
}
void QQuickWebEngineViewPrivate::ensureContentsAdapter()
@@ -847,10 +973,8 @@ void QQuickWebEngineViewPrivate::initializationFinished()
emit q->backgroundColorChanged();
}
- if (!qFuzzyCompare(adapter->currentZoomFactor(), m_zoomFactor)) {
- adapter->setZoomFactor(m_zoomFactor);
- emit q->zoomFactorChanged(m_zoomFactor);
- }
+ // apply if it was set before first ever navigation already
+ q->setZoomFactor(m_zoomFactor);
#if QT_CONFIG(webengine_webchannel)
if (m_webChannel)
@@ -863,7 +987,8 @@ void QQuickWebEngineViewPrivate::initializationFinished()
if (devToolsView && devToolsView->d_ptr->adapter)
adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
- m_scriptCollection->d->d->initializationFinished(adapter);
+ if (m_scriptCollection)
+ m_scriptCollection->d->d->initializationFinished(adapter);
if (q->window())
adapter->setVisible(q->isVisible());
@@ -891,59 +1016,63 @@ void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
}
}
-void QQuickWebEngineViewPrivate::bindViewAndWidget(QQuickWebEngineView *view,
- RenderWidgetHostViewQtDelegateQuick *widget)
+// static
+void QQuickWebEngineViewPrivate::bindViewAndDelegateItem(QQuickWebEngineViewPrivate *viewPrivate,
+ RenderWidgetHostViewQtDelegateItem *delegateItem)
{
- auto oldWidget = view ? view->d_func()->widget : nullptr;
- auto oldView = widget ? widget->m_view : nullptr;
+ auto oldDelegateItem = viewPrivate ? viewPrivate->delegateItem : nullptr;
+ auto oldAdapterClient = delegateItem ? delegateItem->m_adapterClient : nullptr;
+
+ auto *oldViewPrivate = static_cast<QQuickWebEngineViewPrivate *>(oldAdapterClient);
// Change pointers first.
- if (widget && oldView != view) {
- if (oldView)
- oldView->d_func()->widget = nullptr;
- widget->m_view = view;
+ if (delegateItem && oldViewPrivate != viewPrivate) {
+ if (oldViewPrivate)
+ oldViewPrivate->delegateItem = nullptr;
+ delegateItem->m_adapterClient = viewPrivate;
}
- if (view && oldWidget != widget) {
- if (oldWidget)
- oldWidget->m_view = nullptr;
- view->d_func()->widget = widget;
+ if (viewPrivate && oldDelegateItem != delegateItem) {
+ if (oldDelegateItem)
+ oldDelegateItem->m_adapterClient = nullptr;
+ viewPrivate->delegateItem = delegateItem;
}
// Then notify.
- if (widget && oldView != view && oldView)
- oldView->d_func()->widgetChanged(widget, nullptr);
+ if (oldViewPrivate && oldViewPrivate != viewPrivate)
+ oldViewPrivate->delegateItemChanged(delegateItem, nullptr);
- if (view && oldWidget != widget)
- view->d_func()->widgetChanged(oldWidget, widget);
+ if (viewPrivate && oldDelegateItem != delegateItem)
+ viewPrivate->delegateItemChanged(oldDelegateItem, delegateItem);
}
-void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegateQuick *oldWidget,
- RenderWidgetHostViewQtDelegateQuick *newWidget)
+void QQuickWebEngineViewPrivate::delegateItemChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *oldDelegateItem,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *newDelegateItem)
{
Q_Q(QQuickWebEngineView);
- if (oldWidget) {
- oldWidget->setParentItem(nullptr);
+ if (oldDelegateItem) {
+ oldDelegateItem->setParentItem(nullptr);
#if QT_CONFIG(accessibility)
- if (!QtWebEngineCore::closingDown())
- QAccessible::deleteAccessibleInterface(
- QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget)));
+ if (!QtWebEngineCore::closingDown()) {
+ if (auto iface = QAccessible::queryAccessibleInterface(oldDelegateItem))
+ QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(iface));
+ }
#endif
}
- if (newWidget) {
+ if (newDelegateItem) {
Q_ASSERT(!QtWebEngineCore::closingDown());
#if QT_CONFIG(accessibility)
- QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateQuickAccessible(newWidget, q));
+ QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateQuickAccessible(newDelegateItem, q));
#endif
- newWidget->setParentItem(q);
- newWidget->setSize(q->boundingRect().size());
+ newDelegateItem->setParentItem(q);
+ newDelegateItem->setSize(q->boundingRect().size());
// Focus on creation if the view accepts it
if (q->activeFocusOnPress())
- newWidget->setFocus(true);
+ newDelegateItem->setFocus(true);
}
}
@@ -1013,6 +1142,22 @@ void QQuickWebEngineViewPrivate::updateEditActions()
updateAction(QQuickWebEngineView::Unselect);
}
+QQuickWebEngineScriptCollection *QQuickWebEngineViewPrivate::getUserScripts()
+{
+ Q_Q(QQuickWebEngineView);
+ if (!m_scriptCollection)
+ m_scriptCollection.reset(
+ new QQuickWebEngineScriptCollection(
+ new QQuickWebEngineScriptCollectionPrivate(
+ new QWebEngineScriptCollectionPrivate(
+ profileAdapter()->userResourceController(), adapter))));
+
+ if (!m_scriptCollection->qmlEngine())
+ m_scriptCollection->setQmlEngine(qmlEngine(q));
+
+ return m_scriptCollection.data();
+}
+
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
@@ -1086,9 +1231,11 @@ void QQuickWebEngineView::stop()
void QQuickWebEngineView::setZoomFactor(qreal arg)
{
Q_D(QQuickWebEngineView);
- if (d->adapter->isInitialized() && !qFuzzyCompare(d->m_zoomFactor, d->adapter->currentZoomFactor())) {
+ if (d->adapter->isInitialized() && !qFuzzyCompare(arg, zoomFactor())) {
d->adapter->setZoomFactor(arg);
- emit zoomFactorChanged(arg);
+ // MEMO: should reset if factor was not applied due to being invalid
+ d->m_zoomFactor = zoomFactor();
+ emit zoomFactorChanged(d->m_zoomFactor);
} else {
d->m_zoomFactor = arg;
}
@@ -1134,7 +1281,7 @@ QQuickWebEngineSettings *QQuickWebEngineView::settings()
QQuickWebEngineScriptCollection *QQuickWebEngineView::userScripts()
{
Q_D(QQuickWebEngineView);
- return d->m_scriptCollection.data();
+ return d->getUserScripts();
}
void QQuickWebEngineViewPrivate::updateAdapter()
@@ -1238,9 +1385,34 @@ void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText)
ui()->showToolTip(toolTipText);
}
-QtWebEngineCore::TouchHandleDrawableClient *QQuickWebEngineViewPrivate::createTouchHandle(const QMap<int, QImage> &images)
+QtWebEngineCore::TouchHandleDrawableDelegate *
+QQuickWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &images)
{
- return new QQuickWebEngineTouchHandle(ui(), images);
+ Q_Q(QQuickWebEngineView);
+ // lifecycle managed by Chromium's TouchHandleDrawable
+ QQuickWebEngineTouchHandle *handle = new QQuickWebEngineTouchHandle();
+ if (m_touchHandleDelegate) {
+ QQmlContext *qmlContext = QQmlEngine::contextForObject(q);
+ QQmlContext *context = new QQmlContext(qmlContext, handle);
+ context->setContextObject(handle);
+ QObject *delegate = m_touchHandleDelegate->create(context);
+ Q_ASSERT(delegate);
+ QQuickItem *item = qobject_cast<QQuickItem *>(delegate);
+ item->setParentItem(q);
+ handle->setItem(item, false);
+ } else {
+ QQuickItem *item = ui()->createTouchHandle();
+ Q_ASSERT(item);
+ QQmlEngine *engine = qmlEngine(item);
+ Q_ASSERT(engine);
+ QQuickWebEngineTouchHandleProvider *touchHandleProvider =
+ static_cast<QQuickWebEngineTouchHandleProvider *>(
+ engine->imageProvider(QQuickWebEngineTouchHandleProvider::identifier()));
+ Q_ASSERT(touchHandleProvider);
+ touchHandleProvider->init(images);
+ handle->setItem(item, true);
+ }
+ return handle;
}
void QQuickWebEngineViewPrivate::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &selectionBounds, const QSize &handleSize)
@@ -1281,6 +1453,12 @@ void QQuickWebEngineViewPrivate::hideTouchSelectionMenu()
ui()->hideTouchSelectionMenu();
}
+void QQuickWebEngineViewPrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *request)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->webAuthUxRequested(request);
+}
+
bool QQuickWebEngineView::isLoading() const
{
Q_D(const QQuickWebEngineView);
@@ -1322,7 +1500,11 @@ void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId,
d->ensureContentsAdapter();
if (!callback.isUndefined()) {
quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, worldId);
- d->m_callbacks.insert(requestId, callback);
+ if (requestId) {
+ d->m_callbacks.insert(requestId, callback);
+ } else {
+ callback.call();
+ }
} else
d->adapter->runJavaScript(script, worldId);
}
@@ -1539,6 +1721,12 @@ QQuickWebEngineView *QQuickWebEngineView::devToolsView() const
return d->devToolsView;
}
+QString QQuickWebEngineView::devToolsId()
+{
+ Q_D(QQuickWebEngineView);
+ d->ensureContentsAdapter();
+ return d->adapter->devToolsId();
+}
void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView)
{
@@ -1597,6 +1785,15 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu
d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission,
granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission);
break;
+ case ClipboardReadWrite:
+ d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite,
+ granted ? ProfileAdapter::AllowedPermission
+ : ProfileAdapter::DeniedPermission);
+ break;
+ case LocalFontsAccess:
+ d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission,
+ granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission);
+ break;
default:
Q_UNREACHABLE();
}
@@ -1635,8 +1832,8 @@ void QQuickWebEngineView::geometryChange(const QRectF &newGeometry, const QRectF
{
QQuickItem::geometryChange(newGeometry, oldGeometry);
Q_D(QQuickWebEngineView);
- if (d->widget)
- d->widget->setSize(newGeometry.size());
+ if (d->delegateItem)
+ d->delegateItem->setSize(newGeometry.size());
}
void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
@@ -1945,8 +2142,15 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
case InsertUnorderedList:
runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QWebEngineScript::ApplicationWorld);
break;
+ case ChangeTextDirectionLTR:
+ d->adapter->changeTextDirection(true /*left to right*/);
+ break;
+ case ChangeTextDirectionRTL:
+ d->adapter->changeTextDirection(false /*left to right*/);
+ break;
default:
- Q_UNREACHABLE();
+ // Reachable when a spell checker replacement word has been selected
+ break;
}
}
@@ -1960,165 +2164,113 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action)
return d->actions[action];
}
- QString text;
+ const QString text = QWebEnginePagePrivate::actionText(action);
QString iconName;
switch (action) {
case Back:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back);
iconName = QStringLiteral("go-previous");
break;
case Forward:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward);
iconName = QStringLiteral("go-next");
break;
case Stop:
- text = tr("Stop");
iconName = QStringLiteral("process-stop");
break;
case Reload:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload);
iconName = QStringLiteral("view-refresh");
break;
case ReloadAndBypassCache:
- text = tr("Reload and Bypass Cache");
iconName = QStringLiteral("view-refresh");
break;
case Cut:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut);
iconName = QStringLiteral("edit-cut");
break;
case Copy:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy);
iconName = QStringLiteral("edit-copy");
break;
case Paste:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste);
iconName = QStringLiteral("edit-paste");
break;
case Undo:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo);
iconName = QStringLiteral("edit-undo");
break;
case Redo:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo);
iconName = QStringLiteral("edit-redo");
break;
case SelectAll:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll);
iconName = QStringLiteral("edit-select-all");
break;
case PasteAndMatchStyle:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle);
iconName = QStringLiteral("edit-paste");
break;
case OpenLinkInThisWindow:
- text = tr("Open link in this window");
- break;
case OpenLinkInNewWindow:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow);
- break;
case OpenLinkInNewTab:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab);
- break;
case CopyLinkToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard);
- break;
case DownloadLinkToDisk:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk);
- break;
case CopyImageToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard);
- break;
case CopyImageUrlToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard);
- break;
case DownloadImageToDisk:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk);
- break;
case CopyMediaUrlToClipboard:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard);
- break;
case ToggleMediaControls:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls);
- break;
case ToggleMediaLoop:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop);
break;
case ToggleMediaPlayPause:
- text = tr("Toggle Play/Pause");
iconName = QStringLiteral("media-playback-start");
break;
case ToggleMediaMute:
- text = tr("Toggle Mute");
iconName = QStringLiteral("audio-volume-muted");
break;
case DownloadMediaToDisk:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk);
- break;
case InspectElement:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement);
break;
case ExitFullScreen:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen);
iconName = QStringLiteral("view-fullscreen");
break;
case RequestClose:
- text = tr("Close Page");
iconName = QStringLiteral("window-close");
break;
case Unselect:
- text = tr("Unselect");
iconName = QStringLiteral("edit-select-none");
break;
case SavePage:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage);
iconName = QStringLiteral("document-save");
break;
+ case OpenLinkInNewBackgroundTab:
+ break;
case ViewSource:
- text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource);
break;
case ToggleBold:
- text = tr("&Bold");
iconName = QStringLiteral("format-text-bold");
break;
case ToggleItalic:
- text = tr("&Italic");
iconName = QStringLiteral("format-text-italic");
break;
case ToggleUnderline:
- text = tr("&Underline");
iconName = QStringLiteral("format-text-underline");
break;
case ToggleStrikethrough:
- text = tr("&Strikethrough");
iconName = QStringLiteral("format-text-strikethrough");
break;
case AlignLeft:
- text = tr("Align &Left");
break;
case AlignCenter:
- text = tr("Align &Center");
break;
case AlignRight:
- text = tr("Align &Right");
break;
case AlignJustified:
- text = tr("Align &Justified");
break;
case Indent:
- text = tr("&Indent");
iconName = QStringLiteral("format-indent-more");
break;
case Outdent:
- text = tr("&Outdent");
iconName = QStringLiteral("format-indent-less");
break;
case InsertOrderedList:
- text = tr("Insert &Ordered List");
- break;
case InsertUnorderedList:
- text = tr("Insert &Unordered List");
+ case ChangeTextDirectionLTR:
+ case ChangeTextDirectionRTL:
break;
case NoWebAction:
case WebActionCount:
@@ -2150,14 +2302,14 @@ void QQuickWebEngineView::componentComplete()
QQuickItem::componentComplete();
Q_D(QQuickWebEngineView);
d->initializeProfile();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
// Enable accessibility via a dynamic QQmlProperty, instead of using private API call
// QQuickAccessibleAttached::qmlAttachedProperties(this). The qmlContext is required, otherwise
// it is not possible to reference attached properties.
QQmlContext *qmlContext = QQmlEngine::contextForObject(this);
QQmlProperty role(this, QStringLiteral("Accessible.role"), qmlContext);
role.write(QAccessible::Grouping);
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
QTimer::singleShot(0, this, &QQuickWebEngineView::lazyInitialize);
}
@@ -2194,10 +2346,11 @@ QQuickContextMenuBuilder::QQuickContextMenuBuilder(QWebEngineContextMenuRequest
void QQuickContextMenuBuilder::appendExtraItems(QQmlEngine *engine)
{
+ Q_UNUSED(engine);
m_view->d_ptr->ui()->addMenuSeparator(m_menu);
if (QObject *menuExtras = m_view->d_ptr->contextMenuExtraItems->create(qmlContext(m_view))) {
menuExtras->setParent(m_menu);
- QQmlListReference entries(m_menu, defaultPropertyName(m_menu), engine);
+ QQmlListReference entries(m_menu, defaultPropertyName(m_menu));
if (entries.isValid())
entries.append(menuExtras);
}
@@ -2296,10 +2449,12 @@ void QQuickContextMenuBuilder::addMenuItem(ContextMenuItem menuItem)
case ContextMenuItem::SpellingSuggestions:
{
QPointer<QQuickWebEngineView> thisRef(m_view);
- for (int i = 0; i < m_contextData->spellCheckerSuggestions().count() && i < 4; i++) {
+ for (int i = 0; i < m_contextData->spellCheckerSuggestions().size() && i < 4; i++) {
action = new QQuickWebEngineAction(m_menu);
QString replacement = m_contextData->spellCheckerSuggestions().at(i);
QObject::connect(action, &QQuickWebEngineAction::triggered, [thisRef, replacement] { thisRef->replaceMisspelledWord(replacement); });
+ action->d_ptr->m_text = replacement;
+ action->d_ptr->m_enabled = true;
m_view->d_ptr->ui()->addMenuItem(action, m_menu);
}
return;
@@ -2360,44 +2515,28 @@ bool QQuickContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem)
Q_UNREACHABLE();
}
-
-QQuickWebEngineTouchHandle::QQuickWebEngineTouchHandle(QtWebEngineCore::UIDelegatesManager *ui, const QMap<int, QImage> &images)
+void QQuickWebEngineView::setTouchHandleDelegate(QQmlComponent *delegate)
{
- Q_ASSERT(ui);
- m_item.reset(ui->createTouchHandle());
-
- QQmlEngine *engine = qmlEngine(m_item.data());
- Q_ASSERT(engine);
- QQuickWebEngineTouchHandleProvider *touchHandleProvider =
- static_cast<QQuickWebEngineTouchHandleProvider *>(engine->imageProvider(QQuickWebEngineTouchHandleProvider::identifier()));
- Q_ASSERT(touchHandleProvider);
- touchHandleProvider->init(images);
-}
-
-void QQuickWebEngineTouchHandle::setImage(int orientation)
-{
- QUrl url = QQuickWebEngineTouchHandleProvider::url(orientation);
- m_item->setProperty("source", url);
-}
-
-void QQuickWebEngineTouchHandle::setBounds(const QRect &bounds)
-{
- m_item->setProperty("x", bounds.x());
- m_item->setProperty("y", bounds.y());
- m_item->setProperty("width", bounds.width());
- m_item->setProperty("height", bounds.height());
+ if (d_ptr->m_touchHandleDelegate != delegate) {
+ d_ptr->m_touchHandleDelegate = delegate;
+ d_ptr->webContentsAdapter()->resetTouchSelectionController();
+ emit touchHandleDelegateChanged();
+ }
}
-void QQuickWebEngineTouchHandle::setVisible(bool visible)
+QQmlComponent *QQuickWebEngineView::touchHandleDelegate() const
{
- m_item->setProperty("visible", visible);
+ return d_ptr->m_touchHandleDelegate;
}
-void QQuickWebEngineTouchHandle::setOpacity(float opacity)
+void QQuickWebEngineView::save(const QString &filePath,
+ QWebEngineDownloadRequest::SavePageFormat format) const
{
- m_item->setProperty("opacity", opacity);
+ Q_D(const QQuickWebEngineView);
+ d->adapter->save(filePath, format);
}
QT_END_NAMESPACE
#include "moc_qquickwebengineview_p.cpp"
+#include "moc_qquickwebengineforeigntypes_p.cpp"
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index 1a42726e4..0fdd9f787 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEVIEW_P_H
#define QQUICKWEBENGINEVIEW_P_H
@@ -52,18 +16,18 @@
//
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/qwebenginequotarequest.h>
+#include <QtWebEngineCore/qwebenginedesktopmediarequest.h>
+#include <QtWebEngineCore/qwebenginedownloadrequest.h>
#include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h>
#include <QtGui/qcolor.h>
#include <QtQml/qqmlregistration.h>
#include <QtQuick/qquickitem.h>
-namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateQuick;
-}
-
QT_BEGIN_NAMESPACE
class QQmlWebChannel;
+class QQmlComponent;
class QQuickContextMenuBuilder;
class QQuickWebEngineAction;
class QQuickWebEngineAuthenticationDialogRequest;
@@ -78,18 +42,19 @@ class QQuickWebEngineTooltipRequest;
class QQuickWebEngineViewPrivate;
class QWebEngineCertificateError;
class QWebEngineContextMenuRequest;
+class QWebEngineFileSystemAccessRequest;
class QWebEngineFindTextResult;
class QWebEngineFullScreenRequest;
class QWebEngineHistory;
class QWebEngineLoadingInfo;
class QWebEngineNavigationRequest;
class QWebEngineNewWindowRequest;
-class QWebEngineQuotaRequest;
class QWebEngineRegisterProtocolHandlerRequest;
class QQuickWebEngineScriptCollection;
class QQuickWebEngineTouchSelectionMenuRequest;
+class QWebEngineWebAuthUxRequest;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineView : public QQuickItem {
Q_OBJECT
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged FINAL)
@@ -118,11 +83,14 @@ class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(QQuickWebEngineView *inspectedView READ inspectedView WRITE setInspectedView NOTIFY inspectedViewChanged REVISION(1,7) FINAL)
Q_PROPERTY(QQuickWebEngineView *devToolsView READ devToolsView WRITE setDevToolsView NOTIFY devToolsViewChanged REVISION(1,7) FINAL)
+ Q_PROPERTY(QString devToolsId READ devToolsId CONSTANT REVISION(6,6) FINAL)
Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged REVISION(1,10) FINAL)
Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged REVISION(1,10) FINAL)
Q_PROPERTY(qint64 renderProcessPid READ renderProcessPid NOTIFY renderProcessPidChanged FINAL REVISION(1,11))
+ Q_PROPERTY(QQmlComponent *touchHandleDelegate READ touchHandleDelegate WRITE
+ setTouchHandleDelegate NOTIFY touchHandleDelegateChanged REVISION(0) FINAL)
QML_NAMED_ELEMENT(WebEngineView)
QML_ADDED_IN_VERSION(1, 0)
QML_EXTRA_VERSION(2, 0)
@@ -205,6 +173,8 @@ QT_WARNING_POP
DesktopVideoCapture,
DesktopAudioVideoCapture,
Notifications,
+ ClipboardReadWrite,
+ LocalFontsAccess,
};
Q_ENUM(Feature)
@@ -248,6 +218,7 @@ QT_WARNING_POP
RequestClose,
Unselect,
SavePage,
+ OpenLinkInNewBackgroundTab, // Not supported in QML
ViewSource,
ToggleBold,
@@ -265,6 +236,9 @@ QT_WARNING_POP
InsertOrderedList,
InsertUnorderedList,
+ ChangeTextDirectionLTR,
+ ChangeTextDirectionRTL,
+
WebActionCount
};
Q_ENUM(WebAction)
@@ -296,8 +270,6 @@ QT_WARNING_POP
// must match QPageSize::PageSizeId
enum PrintedPageSizeId {
// Existing Qt sizes
- A4,
- B5,
Letter,
Legal,
Executive,
@@ -305,21 +277,24 @@ QT_WARNING_POP
A1,
A2,
A3,
+ A4,
A5,
A6,
A7,
A8,
A9,
+ A10,
B0,
B1,
- B10,
B2,
B3,
B4,
+ B5,
B6,
B7,
B8,
B9,
+ B10,
C5E,
Comm10E,
DLE,
@@ -329,7 +304,6 @@ QT_WARNING_POP
Custom,
// New values derived from PPD standard
- A10,
A3Extra,
A4Extra,
A4Plus,
@@ -432,10 +406,8 @@ QT_WARNING_POP
EnvelopePrc10,
EnvelopeYou4,
- // Last item, with commonly used synynoms from QPagedPrintEngine / QPrinter
+ // Last item
LastPageSize = EnvelopeYou4,
- NPageSize = LastPageSize,
- NPaperSize = LastPageSize,
// Convenience overloads for naming consistency
AnsiA = Letter,
@@ -490,12 +462,16 @@ QT_WARNING_POP
QQuickWebEngineView *inspectedView() const;
void setDevToolsView(QQuickWebEngineView *);
QQuickWebEngineView *devToolsView() const;
+ QString devToolsId();
LifecycleState lifecycleState() const;
void setLifecycleState(LifecycleState state);
LifecycleState recommendedState() const;
+ QQmlComponent *touchHandleDelegate() const;
+ void setTouchHandleDelegate(QQmlComponent *delegagte);
+
public Q_SLOTS:
void runJavaScript(const QString&, const QJSValue & = QJSValue());
Q_REVISION(1,3) void runJavaScript(const QString&, quint32 worldId, const QJSValue & = QJSValue());
@@ -508,12 +484,15 @@ public Q_SLOTS:
void stop();
Q_REVISION(1,1) void findText(const QString &subString, FindFlags options = { }, const QJSValue &callback = QJSValue());
Q_REVISION(1,1) void fullScreenCancelled();
- Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted);
+ Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature, bool granted);
Q_REVISION(1,2) void setActiveFocusOnPress(bool arg);
Q_REVISION(1,2) void triggerWebAction(WebAction action);
Q_REVISION(1,3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait);
Q_REVISION(1,3) void printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait);
Q_REVISION(1,4) void replaceMisspelledWord(const QString &replacement);
+ Q_REVISION(6, 6) void save(const QString &filePath,
+ QWebEngineDownloadRequest::SavePageFormat format =
+ QWebEngineDownloadRequest::MimeHtmlSaveFormat) const;
private Q_SLOTS:
void lazyInitialize();
@@ -526,17 +505,22 @@ Q_SIGNALS:
void loadProgressChanged();
void linkHovered(const QUrl &hoveredUrl);
void navigationRequested(QWebEngineNavigationRequest *request);
- void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID);
+ void javaScriptConsoleMessage(QQuickWebEngineView::JavaScriptConsoleMessageLevel level,
+ const QString &message, int lineNumber, const QString &sourceID);
Q_REVISION(1,1) void certificateError(const QWebEngineCertificateError &error);
Q_REVISION(1,1) void fullScreenRequested(const QWebEngineFullScreenRequest &request);
Q_REVISION(1,1) void isFullScreenChanged();
- Q_REVISION(1,1) void featurePermissionRequested(const QUrl &securityOrigin, Feature feature);
+ Q_REVISION(1, 1)
+ void featurePermissionRequested(const QUrl &securityOrigin,
+ QQuickWebEngineView::Feature feature);
Q_REVISION(1,1) void zoomFactorChanged(qreal arg);
Q_REVISION(1,1) void profileChanged();
Q_REVISION(1,1) void webChannelChanged();
Q_REVISION(1,2) void activeFocusOnPressChanged(bool);
Q_REVISION(1,2) void backgroundColorChanged();
- Q_REVISION(1,2) void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
+ Q_REVISION(1, 2)
+ void renderProcessTerminated(QQuickWebEngineView::RenderProcessTerminationStatus terminationStatus,
+ int exitCode);
Q_REVISION(1,2) void windowCloseRequested();
Q_REVISION(1,3) void contentsSizeChanged(const QSizeF& size);
Q_REVISION(1,3) void scrollPositionChanged(const QPointF& position);
@@ -549,7 +533,10 @@ Q_SIGNALS:
Q_REVISION(1,4) void colorDialogRequested(QQuickWebEngineColorDialogRequest *request);
Q_REVISION(1,4) void fileDialogRequested(QQuickWebEngineFileDialogRequest *request);
Q_REVISION(1,5) void pdfPrintingFinished(const QString &filePath, bool success);
- Q_REVISION(1,7) void quotaRequested(const QWebEngineQuotaRequest &request);
+#if QT_DEPRECATED_SINCE(6, 5)
+ QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.")
+ Q_REVISION(1, 7) void quotaRequested(const QWebEngineQuotaRequest &request);
+#endif
Q_REVISION(1,7) void geometryChangeRequested(const QRect &geometry, const QRect &frameGeometry);
Q_REVISION(1,7) void inspectedViewChanged();
Q_REVISION(1,7) void devToolsViewChanged();
@@ -557,14 +544,18 @@ Q_SIGNALS:
Q_REVISION(1,8) void printRequested();
Q_REVISION(1,9) void selectClientCertificate(QQuickWebEngineClientCertificateSelection *clientCertSelection);
Q_REVISION(1,10) void tooltipRequested(QQuickWebEngineTooltipRequest *request);
- Q_REVISION(1,10) void lifecycleStateChanged(LifecycleState state);
- Q_REVISION(1,10) void recommendedStateChanged(LifecycleState state);
+ Q_REVISION(1, 10) void lifecycleStateChanged(QQuickWebEngineView::LifecycleState state);
+ Q_REVISION(1, 10) void recommendedStateChanged(QQuickWebEngineView::LifecycleState state);
Q_REVISION(1,10) void findTextFinished(const QWebEngineFindTextResult &result);
Q_REVISION(1,11) void renderProcessPidChanged(qint64 pid);
Q_REVISION(1,11) void canGoBackChanged();
Q_REVISION(1,11) void canGoForwardChanged();
Q_REVISION(1,12) void newWindowRequested(QQuickWebEngineNewWindowRequest *request);
Q_REVISION(6,3) void touchSelectionMenuRequested(QQuickWebEngineTouchSelectionMenuRequest *request);
+ Q_REVISION(6,4) void touchHandleDelegateChanged();
+ Q_REVISION(6,4) void fileSystemAccessRequested(const QWebEngineFileSystemAccessRequest &request);
+ Q_REVISION(6, 7) void webAuthUxRequested(QWebEngineWebAuthUxRequest *request);
+ Q_REVISION(6,7) void desktopMediaRequested(const QWebEngineDesktopMediaRequest &request);
protected:
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
@@ -580,13 +571,12 @@ private:
Q_DECLARE_PRIVATE(QQuickWebEngineView)
QScopedPointer<QQuickWebEngineViewPrivate> d_ptr;
- friend class QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick;
friend class QQuickContextMenuBuilder;
friend class FaviconImageResponse;
friend class FaviconImageResponseRunnable;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
friend class QQuickWebEngineViewAccessible;
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
};
QT_END_NAMESPACE
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 4647d671e..ee7da99b9 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKWEBENGINEVIEW_P_P_H
#define QQUICKWEBENGINEVIEW_P_P_H
@@ -51,9 +15,11 @@
// We mean it.
//
+#include "qquickwebenginetouchhandle_p.h"
#include "qquickwebengineview_p.h"
#include "render_view_context_menu_qt.h"
#include "touch_handle_drawable_client.h"
+#include "ui_delegates_manager.h"
#include "web_contents_adapter_client.h"
#include <QtCore/qcompilerdetection.h>
@@ -61,10 +27,9 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qstring.h>
-#include <QtGui/qaccessibleobject.h>
namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateQuick;
+class RenderWidgetHostViewQtDelegateItem;
class TouchSelectionMenuController;
class UIDelegatesManager;
class WebContentsAdapter;
@@ -80,7 +45,7 @@ class QWebEngineContextMenuRequest;
class QWebEngineFindTextResult;
class QWebEngineHistory;
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCore::WebContentsAdapterClient
+class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCore::WebContentsAdapterClient
{
public:
Q_DECLARE_PUBLIC(QQuickWebEngineView)
@@ -103,6 +68,7 @@ public:
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl&) override;
void selectionChanged() override;
+ void zoomUpdateIsNeeded() override;
void recentlyAudibleChanged(bool recentlyAudible) override;
void renderProcessPidChanged(qint64 pid) override;
QRectF viewportRect() const override;
@@ -125,6 +91,7 @@ public:
void navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame) override;
void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) override;
void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) override;
+ void desktopMediaRequested(QtWebEngineCore::DesktopMediaController *) override;
void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) override;
void didRunJavaScript(quint64, const QVariant&) override;
void didFetchDocumentMarkup(quint64, const QString&) override { }
@@ -136,8 +103,8 @@ public:
void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
- void runQuotaRequest(QWebEngineQuotaRequest) override;
void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
+ void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override;
QObject *accessibilityParentObject() override;
QWebEngineSettings *webEngineSettings() const override;
void allowCertificateError(const QWebEngineCertificateError &error) override;
@@ -153,7 +120,7 @@ public:
QObject *dragSource() const override;
bool isEnabled() const override;
void setToolTip(const QString &toolTipText) override;
- QtWebEngineCore::TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &images) override;
+ QtWebEngineCore::TouchHandleDrawableDelegate *createTouchHandleDelegate(const QMap<int, QImage> &images) override;
void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override;
void hideTouchSelectionMenu() override;
const QObject *holdingQObject() const override;
@@ -163,6 +130,11 @@ public:
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
void printRequested() override;
void findTextFinished(const QWebEngineFindTextResult &result) override;
+ void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ const QRect &bounds, bool autoselectFirstSuggestion) override;
+ void hideAutofillPopup() override;
+ void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) override;
+
void updateAction(QQuickWebEngineView::WebAction) const;
bool adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
void setProfile(QQuickWebEngineProfile *profile);
@@ -170,9 +142,9 @@ public:
void ensureContentsAdapter();
void setFullScreenMode(bool);
- static void bindViewAndWidget(QQuickWebEngineView *view, QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget);
- void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *oldWidget,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *newWidget);
+ static void bindViewAndDelegateItem(QQuickWebEngineViewPrivate *viewPrivate, QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *delegateItem);
+ void delegateItemChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *oldDelegateItem,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *newDelegateItem);
QQuickWebEngineProfile *m_profile;
QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
@@ -186,8 +158,6 @@ public:
bool m_fullscreenMode;
bool isLoading;
bool m_activeFocusOnPress;
- bool m_navigationActionTriggered;
- qreal devicePixelRatio;
QMap<quint64, QJSValue> m_callbacks;
QQmlWebChannel *m_webChannel;
QPointer<QQuickWebEngineView> inspectedView;
@@ -196,9 +166,10 @@ public:
bool m_defaultAudioMuted;
bool m_isBeingAdopted;
mutable QQuickWebEngineAction *actions[QQuickWebEngineView::WebActionCount];
- QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget = nullptr;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *delegateItem = nullptr;
bool profileInitialized() const;
+ QQuickWebEngineScriptCollection *getUserScripts();
private:
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
@@ -207,28 +178,9 @@ private:
bool m_profileInitialized;
QWebEngineContextMenuRequest *m_contextMenuRequest;
QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection;
- QQuickWebEngineFaviconProvider *m_faviconProvider = nullptr;
-};
-
-#ifndef QT_NO_ACCESSIBILITY
-class QQuickWebEngineViewAccessible : public QAccessibleObject
-{
-public:
- QQuickWebEngineViewAccessible(QQuickWebEngineView *o);
- bool isValid() const override;
- QAccessibleInterface *parent() const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface*) const override;
- QString text(QAccessible::Text) const override;
- QAccessible::Role role() const override;
- QAccessible::State state() const override;
-
-private:
- QQuickWebEngineView *engineView() const { return static_cast<QQuickWebEngineView*>(object()); }
+ QPointer<QQuickWebEngineFaviconProvider> m_faviconProvider;
+ QQmlComponent *m_touchHandleDelegate;
};
-#endif // QT_NO_ACCESSIBILITY
class QQuickContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt
{
@@ -248,19 +200,6 @@ private:
QObject *m_menu;
};
-class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineTouchHandle : public QtWebEngineCore::TouchHandleDrawableClient {
-public:
- QQuickWebEngineTouchHandle(QtWebEngineCore::UIDelegatesManager *ui, const QMap<int, QImage> &images);
-
- void setImage(int orientation) override;
- void setBounds(const QRect &bounds) override;
- void setVisible(bool visible) override;
- void setOpacity(float opacity) override;
-
-private:
- QScopedPointer<QQuickItem> m_item;
-};
-
QT_END_NAMESPACE
#endif // QQUICKWEBENGINEVIEW_P_P_H
diff --git a/src/webenginequick/api/qtwebenginequickglobal.cpp b/src/webenginequick/api/qtwebenginequickglobal.cpp
index d441c9f36..e24ef643b 100644
--- a/src/webenginequick/api/qtwebenginequickglobal.cpp
+++ b/src/webenginequick/api/qtwebenginequickglobal.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qcoreapplication.h>
#include <QtQuick/qquickwindow.h>
@@ -73,15 +37,22 @@ namespace QtWebEngineQuick {
*/
void initialize()
{
+ auto api = QQuickWindow::graphicsApi();
if (!QCoreApplication::startingUp()) {
- qWarning("QtWebEngineQuick::initialize() called with QCoreApplication object already created and should be call before. "\
- "This is depreciated and may fail in the future.");
+ if (api == QSGRendererInterface::OpenGL || (api != QSGRendererInterface::Vulkan
+ && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11)) {
+ qWarning("QtWebEngineQuick::initialize() called with QCoreApplication object already created and should be call before. "\
+ "This is depreciated and may fail in the future.");
+ }
QtWebEngineCore::initialize();
return;
}
+
// call initialize the same way as widgets do
qAddPreRoutine(QtWebEngineCore::initialize);
- QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
+ if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan
+ && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11)
+ QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
}
} // namespace QtWebEngineQuick
diff --git a/src/webenginequick/api/qtwebenginequickglobal.h b/src/webenginequick/api/qtwebenginequickglobal.h
index d8b96fbdd..1580bf6db 100644
--- a/src/webenginequick/api/qtwebenginequickglobal.h
+++ b/src/webenginequick/api/qtwebenginequickglobal.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTWEBENGINEQUICKGLOBAL_H
#define QTWEBENGINEQUICKGLOBAL_H
diff --git a/src/webenginequick/api/qtwebenginequickglobal_p.h b/src/webenginequick/api/qtwebenginequickglobal_p.h
index 8053a791f..256bcd590 100644
--- a/src/webenginequick/api/qtwebenginequickglobal_p.h
+++ b/src/webenginequick/api/qtwebenginequickglobal_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTWEBENGINEQUICKGLOBAL_P_H
#define QTWEBENGINEQUICKGLOBAL_P_H
@@ -55,10 +19,4 @@
#include <QtCore/private/qglobal_p.h>
#include <QtWebEngineQuick/private/qtwebenginequick-config_p.h>
-QT_BEGIN_NAMESPACE
-
-#define Q_WEBENGINEQUICK_PRIVATE_EXPORT Q_WEBENGINEQUICK_EXPORT
-
-QT_END_NAMESPACE
-
#endif // QTWEBENGINEQUICKGLOBAL_P_H
diff --git a/src/webenginequick/configure.cmake b/src/webenginequick/configure.cmake
index 649154301..b256e5a1d 100644
--- a/src/webenginequick/configure.cmake
+++ b/src/webenginequick/configure.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_feature("webenginequick-ui-delegates" PRIVATE
SECTION "WebEngine"
LABEL "UI Delegates"
diff --git a/src/webenginequick/doc/snippets/minimal/main.cpp b/src/webenginequick/doc/snippets/minimal/main.cpp
new file mode 100644
index 000000000..e17493a36
--- /dev/null
+++ b/src/webenginequick/doc/snippets/minimal/main.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [Minimal Example]
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ QtWebEngineQuick::initialize();
+ QGuiApplication app(argc, argv);
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ return app.exec();
+}
+//! [Minimal Example]
diff --git a/src/webenginequick/doc/snippets/minimal/main.qml b/src/webenginequick/doc/snippets/minimal/main.qml
new file mode 100644
index 000000000..87a8757df
--- /dev/null
+++ b/src/webenginequick/doc/snippets/minimal/main.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [Minimal Example]
+import QtQuick
+import QtQuick.Window
+import QtWebEngine
+
+Window {
+ width: 1024
+ height: 750
+ visible: true
+ WebEngineView {
+ anchors.fill: parent
+ url: "https://www.qt.io"
+ }
+}
+//! [Minimal Example]
diff --git a/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc b/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc
index b21efbdf9..f8fbbd669 100644
--- a/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc
+++ b/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc
@@ -1,40 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [0]
QT += webenginequick
//! [0]
-
-//! [1]
-#include <QtWebEngineQuick>
-//! [1]
-
//! [2]
-find_package(Qt6 COMPONENTS WebEngineQuick REQUIRED)
-target_link_libraries(target PRIVATE Qt::WebEngineQuick)
+find_package(Qt6 REQUIRED COMPONENTS WebEngineQuick)
+target_link_libraries(target PRIVATE Qt6::WebEngineQuick)
//! [2]
diff --git a/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml b/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml
new file mode 100644
index 000000000..2fd5f490b
--- /dev/null
+++ b/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml
@@ -0,0 +1,123 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+import QtWebEngine
+import QtQuick.Controls
+import QtQuick.Layouts
+
+ApplicationWindow {
+ id: window
+ visible: true
+ width: 800
+ height: 600
+ title: qsTr("WebEngineAction Example")
+
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+//! [0]
+ ToolButton {
+ property int itemAction: WebEngineView.Back
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+//! [0]
+ ToolButton {
+ property int itemAction: WebEngineView.Forward
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ ToolButton {
+ property int itemAction: webEngineView.loading ? WebEngineView.Stop : WebEngineView.Reload
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ TextField {
+ Layout.fillWidth: true
+
+ text: webEngineView.url
+ selectByMouse: true
+ onEditingFinished: webEngineView.url = utils.fromUserInput(text)
+ }
+
+ ToolButton {
+ id: settingsButton
+ text: "Settings"
+ icon.name: "settings-configure"
+ display: AbstractButton.TextUnderIcon
+ onClicked: settingsMenu.open()
+ checked: settingsMenu.visible
+
+ Menu {
+ id: settingsMenu
+ y: settingsButton.height
+
+ MenuItem {
+ id: customContextMenuOption
+ checkable: true
+ checked: true
+
+ text: "Custom context menu"
+ }
+ }
+ }
+ }
+ }
+
+ WebEngineView {
+ id: webEngineView
+ url: "https://qt.io"
+ anchors.fill: parent
+
+ Component.onCompleted: {
+ profile.downloadRequested.connect(function(download){
+ download.accept();
+ })
+ }
+
+//! [1]
+ property Menu contextMenu: Menu {
+ Repeater {
+ model: [
+ WebEngineView.Back,
+ WebEngineView.Forward,
+ WebEngineView.Reload,
+ WebEngineView.SavePage,
+ WebEngineView.Copy,
+ WebEngineView.Paste,
+ WebEngineView.Cut,
+ WebEngineView.ChangeTextDirectionLTR,
+ WebEngineView.ChangeTextDirectionRTL,
+ ]
+ MenuItem {
+ text: webEngineView.action(modelData).text
+ enabled: webEngineView.action(modelData).enabled
+ onClicked: webEngineView.action(modelData).trigger()
+ icon.name: webEngineView.action(modelData).iconName
+ display: MenuItem.TextBesideIcon
+ }
+ }
+ }
+
+ onContextMenuRequested: function(request) {
+ if (customContextMenuOption.checked) {
+ request.accepted = true;
+ contextMenu.popup();
+ }
+ }
+//! [1]
+ }
+}
diff --git a/src/webenginequick/doc/snippets/qtwebengine_webengineview_newviewrequested.qml b/src/webenginequick/doc/snippets/qtwebengine_webengineview_newviewrequested.qml
index 0297a62fd..6b10df752 100644
--- a/src/webenginequick/doc/snippets/qtwebengine_webengineview_newviewrequested.qml
+++ b/src/webenginequick/doc/snippets/qtwebengine_webengineview_newviewrequested.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Window
diff --git a/src/webenginequick/doc/src/context_menu_request.qdoc b/src/webenginequick/doc/src/context_menu_request.qdoc
index 40b595696..e7d732d5e 100644
--- a/src/webenginequick/doc/src/context_menu_request.qdoc
+++ b/src/webenginequick/doc/src/context_menu_request.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype ContextMenuRequest
diff --git a/src/webenginequick/doc/src/fullscreen_request.qdoc b/src/webenginequick/doc/src/fullscreen_request.qdoc
index ec7d93ba6..60da2748c 100644
--- a/src/webenginequick/doc/src/fullscreen_request.qdoc
+++ b/src/webenginequick/doc/src/fullscreen_request.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype FullScreenRequest
diff --git a/src/webenginequick/doc/src/loading_info.qdoc b/src/webenginequick/doc/src/loading_info.qdoc
index fe8e30a80..c97799e24 100644
--- a/src/webenginequick/doc/src/loading_info.qdoc
+++ b/src/webenginequick/doc/src/loading_info.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype WebEngineLoadingInfo
@@ -79,6 +55,8 @@
Error is related to the FTP connection.
\value WebEngineLoadingInfo.DnsErrorDomain
Error is related to the DNS connection.
+ \value WebEngineLoadingInfo.HttpStatusCodeDomain
+ Error is the HTTP response status code, even in case of success e.g. the server replied with status 200.
*/
/*!
\qmlproperty int WebEngineLoadingInfo::errorCode
diff --git a/src/webenginequick/doc/src/navigation_history.qdoc b/src/webenginequick/doc/src/navigation_history.qdoc
index 0f3a4c763..94876799d 100644
--- a/src/webenginequick/doc/src/navigation_history.qdoc
+++ b/src/webenginequick/doc/src/navigation_history.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype WebEngineHistoryModel
diff --git a/src/webenginequick/doc/src/qtwebengine-examples.qdoc b/src/webenginequick/doc/src/qtwebengine-examples.qdoc
index 3dedaa28f..eebf18ba1 100644
--- a/src/webenginequick/doc/src/qtwebengine-examples.qdoc
+++ b/src/webenginequick/doc/src/qtwebengine-examples.qdoc
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\group webengine-examples
\title Qt WebEngine Quick Examples
\brief Examples demonstrating the \QWE usage.
- \ingroup all-examples
These examples and demonstrations show a range of different uses for \l{Qt WebEngine},
from displaying Web pages within a QML user interface to an implementation of
diff --git a/src/webenginequick/doc/src/qtwebengine-module.qdoc b/src/webenginequick/doc/src/qtwebengine-module.qdoc
index ab6fc49ca..6f50cc2f4 100644
--- a/src/webenginequick/doc/src/qtwebengine-module.qdoc
+++ b/src/webenginequick/doc/src/qtwebengine-module.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\module QtWebEngineQuick
@@ -34,12 +10,7 @@
\qtvariable webenginequick
\qtcmakepackage WebEngineQuick
- The \QWE module exposes C++ functionality to Qt Quick.
-
- To include the definitions of the module's classes, use the
- following directive:
-
- \snippet qtwebengine_build_snippet.qdoc 1
+ The \QWE Quick module exposes C++ functionality to Qt Quick.
\if !defined(qtforpython)
To link against the module, add the following to your qmake project file:
diff --git a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
index ac1fff80b..ecf3a4a6e 100644
--- a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
+++ b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmlmodule QtWebEngine
@@ -32,11 +8,6 @@
\ingroup qtwebengine-modules
\ingroup qmlmodules
- The QML types can be imported into your application using the following import statements in
- your .qml file:
-
- \snippet qtwebengine_build_snippet.qdoc 1
-
To link against the module using build with qmake,
add the following QT variable to your qmake .pro file:
@@ -46,4 +17,13 @@
in the Qt6 package and \c target_link_libraries() to link against the module:
\snippet qtwebengine_build_snippet.qdoc 2
+
+ The minimal amount of code needed to load and display an HTML page using the QML engine
+ requires a proper initialization:
+
+ \snippet minimal/main.cpp Minimal Example
+
+ Where the content of main.qml is simply:
+
+ \snippet minimal/main.qml Minimal Example
*/
diff --git a/src/webenginequick/doc/src/quota_request.qdoc b/src/webenginequick/doc/src/quota_request.qdoc
index ee64c0484..01f4ec286 100644
--- a/src/webenginequick/doc/src/quota_request.qdoc
+++ b/src/webenginequick/doc/src/quota_request.qdoc
@@ -1,37 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype QuotaRequest
\instantiates QWebEngineQuotaRequest
\inqmlmodule QtWebEngine
\since QtWebEngine 1.7
+ \deprecated [6.5] Requesting host quota is no longer supported by Chromium.
- \brief A utility type for the WebEngineView::quotaRequested() signal.
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
+
+ For further details, see https://crbug.com/1233525
\sa WebEngineView::quotaRequested()
*/
@@ -39,36 +19,18 @@
/*!
\qmlproperty url QuotaRequest::origin
\readonly
-
- The URL of the web page that issued the quota request.
*/
/*!
\qmlproperty qint64 QuotaRequest::requestedSize
\readonly
-
- Contains the size of the requested disk space in bytes.
*/
/*!
\qmlmethod void QuotaRequest::accept()
-
- Accepts the quota request.
-
- \qml
- WebEngineView {
- onQuotaRequested: function(request) {
- if (request.requestedSize <= 5 * 1024 * 1024)
- request.accept();
- else
- request.reject();
- }
- }
- \endqml
*/
/*!
\qmlmethod void QuotaRequest::reject()
- Rejects the quota request.
*/
diff --git a/src/webenginequick/doc/src/register_protocol_handler_request.qdoc b/src/webenginequick/doc/src/register_protocol_handler_request.qdoc
index b3ebcb31b..d69f4d264 100644
--- a/src/webenginequick/doc/src/register_protocol_handler_request.qdoc
+++ b/src/webenginequick/doc/src/register_protocol_handler_request.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype RegisterProtocolHandlerRequest
diff --git a/src/webenginequick/doc/src/touch_selection_menu_request.qdoc b/src/webenginequick/doc/src/touch_selection_menu_request.qdoc
index da4c2062a..9ca6ed36b 100644
--- a/src/webenginequick/doc/src/touch_selection_menu_request.qdoc
+++ b/src/webenginequick/doc/src/touch_selection_menu_request.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype TouchSelectionMenuRequest
diff --git a/src/webenginequick/doc/src/webengine_certificate_error.qdoc b/src/webenginequick/doc/src/webengine_certificate_error.qdoc
index 3027aa4c2..93bad9fb1 100644
--- a/src/webenginequick/doc/src/webengine_certificate_error.qdoc
+++ b/src/webenginequick/doc/src/webengine_certificate_error.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype WebEngineCertificateError
@@ -33,7 +9,7 @@
\brief A utility type for ignoring certificate errors or rejecting erroneous certificates.
- This QML type contains information about a certificate error that occurred. The \l error
+ This QML type contains information about a certificate error that occurred. The \l type
property holds the reason that the error occurred and the \l description property holds a
short localized description of the error. The \l url property holds the URL that triggered
the error.
@@ -73,7 +49,7 @@
The URL that triggered the error.
*/
/*!
- \qmlproperty enumeration WebEngineCertificateError::error
+ \qmlproperty enumeration WebEngineCertificateError::type
\readonly
The type of the error.
diff --git a/src/webenginequick/doc/src/webengine_download_request.qdoc b/src/webenginequick/doc/src/webengine_download_request.qdoc
index 845a8ff07..96d84e0a3 100644
--- a/src/webenginequick/doc/src/webengine_download_request.qdoc
+++ b/src/webenginequick/doc/src/webengine_download_request.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\qmltype WebEngineDownloadRequest
diff --git a/src/webenginequick/doc/src/webenginescript.qdoc b/src/webenginequick/doc/src/webenginescript.qdoc
new file mode 100644
index 000000000..9708ffbf8
--- /dev/null
+++ b/src/webenginequick/doc/src/webenginescript.qdoc
@@ -0,0 +1,98 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \qmltype WebEngineScript
+ \instantiates QWebEngineScript
+ \brief Enables the programmatic injection of scripts in the JavaScript engine.
+ \since QtWebEngine 1.1
+ \ingroup qmlvaluetypes
+ \inqmlmodule QtWebEngine
+
+ The WebEngineScript type 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 content.
+
+ 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. The worldId property provides some predefined IDs for this
+ purpose.
+
+ The following \l Greasemonkey attributes are supported:
+ \c @exclude, \c @include, \c @name, \c @match, and \c @run-at.
+
+ Use \l{WebEngineScriptCollection} to access a list of scripts attached to the web view.
+*/
+
+/*!
+ \qmlproperty string WebEngineScript::name
+
+ The name of the script. Can be useful to retrieve a particular script from
+ \l{WebEngineScriptCollection::find}{WebEngineScriptCollection.find} method.
+*/
+
+/*!
+ \qmlproperty url WebEngineScript::sourceUrl
+
+ This property holds the remote source location of the user script (if any).
+
+ Unlike \l sourceCode, this property allows referring to user scripts that
+ are not already loaded in memory, for instance, when stored on disk.
+
+ Setting this property will change the \l sourceCode of the script.
+
+ \note At present, only file-based sources are supported.
+
+ \sa sourceCode
+*/
+
+/*!
+ \qmlproperty string WebEngineScript::sourceCode
+
+ This property holds the JavaScript source code of the user script.
+
+ \sa sourceUrl
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineScript::injectionPoint
+
+ The point in the loading process at which the script will be executed.
+ The default value is \c Deferred.
+
+ \value WebEngineScript.DocumentCreation
+ The script will be executed as soon as the document is created. This is not suitable for
+ any DOM operation.
+ \value WebEngineScript.DocumentReady
+ The script will run as soon as the DOM is ready. This is equivalent to the
+ \c DOMContentLoaded event firing in JavaScript.
+ \value WebEngineScript.Deferred
+ The script will run when the page load finishes, or 500 ms after the document is ready,
+ whichever comes first.
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineScript::worldId
+
+ The world ID defining which isolated world the script is executed in.
+
+ \value WebEngineScript.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 WebEngineScript.ApplicationWorld
+ The default isolated world used for application level functionality implemented in
+ JavaScript.
+ \value WebEngineScript.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 thumb, if that functionality is exposed to the
+ application users, each individual script should probably get its own isolated world.
+*/
+
+/*!
+ \qmlproperty int WebEngineScript::runOnSubframes
+
+ Set this property to \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.
+ The default value is \c{false}.
+*/
diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
index c2a002a35..eeae34dcc 100644
--- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc
+++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc
@@ -1,24 +1,7 @@
-/*
- * Copyright (C) 2019 The Qt Company Ltd.
- * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
- *
- * 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 program 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 program; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
+// Copyright (C) 2019 The Qt Company Ltd.
+// Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+// Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// The documentation in this file was imported from QtWebKit and is thus constrained
// by its LGPL license.
@@ -41,7 +24,7 @@
\l QtWebEngineQuick::initialize in the application main source file, as illustrated by the
following code snippet:
- \quotefromfile webenginequick/minimal/main.cpp
+ \quotefromfile minimal/main.cpp
\skipto main
\printuntil }
@@ -56,7 +39,7 @@
The following sample QML application loads a web page using the \c url property:
- \quotefromfile webenginequick/minimal/main.qml
+ \quotefromfile minimal/main.qml
\skipto import
\printuntil /^\}/
@@ -327,11 +310,13 @@
/*!
- \qmlproperty list<WebEngineScript> WebEngineView::userScripts
+ \qmlproperty WebEngineScriptCollection WebEngineView::userScripts
\readonly
\since QtWebEngine 1.1
- List of WebEngineScript objects attached to the view.
+ The user scripts' collection associated with the view.
+
+ \sa WebEngineScriptCollection
*/
/*!
@@ -371,9 +356,8 @@
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 external objects to
- be loaded, \c baseUrl cannot be empty. For example, if \a html
+ \a baseUrl is optional and used to resolve relative URLs in the document,
+ such as referenced images or stylesheets. 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,
should be at \c{http://www.example.com/documents/diagram.png}.
@@ -802,6 +786,7 @@
Exit the fullscreen mode. (Added in Qt 5.6)
\value WebEngineView.SavePage
Save the current web page to disk. (Added in Qt 5.7)
+ \omitvalue WebEngineView.OpenLinkInNewBackgroundTab
\value WebEngineView.ViewSource
Show the source of the current page in a new tab. Requires a handler for the
\l newWindowRequested() signal. (Added in Qt 5.8)
@@ -846,6 +831,10 @@
Inserts an unordered list at the current cursor position,
deleting the current selection.
Requires \c contenteditable="true". (Added in Qt 5.10)
+ \value WebEngineView.ChangeTextDirectionLTR
+ Changes text direction to left-to-right in the focused input element. (Added in Qt 6.6)
+ \value WebEngineView.ChangeTextDirectionRTL
+ Changes text direction to right-to-left in the focused input element. (Added in Qt 6.6)
\omitvalue WebActionCount
*/
@@ -863,13 +852,22 @@
Video devices, such as cameras.
\value WebEngineView.MediaAudioVideoCapture
Both audio and video capture devices.
- \value DesktopVideoCapture
+ \value WebEngineView.DesktopVideoCapture
Video output capture, that is, the capture of the user's display.
(Added in Qt 5.10)
- \value DesktopAudioVideoCapture
+ \value WebEngineView.DesktopAudioVideoCapture
Both audio and video output capture. (Added in Qt 5.10)
- \value WebEnginView.Notifications
+ \value WebEngineView.Notifications
Web notifications for the end-user.
+ \value WebEngineView.ClipboardReadWrite
+ Read and write access for the clipboard. If both \l{WebEngineSettings::JavascriptCanPaste}
+ {JavascriptCanPaste} and \l{WebEngineSettings::JavascriptCanAccessClipboard}
+ {JavascriptCanAccessClipboard} settings are enabled, this permission will always be granted
+ automatically and no feature requests will be made.
+ (Added in Qt 6.8)
+ \value WebEngineView.LocalFontsAccess
+ Access to the fonts installed on the user's machine. Only available on desktop platforms.
+ (Added in Qt 6.8)
\sa featurePermissionRequested(), grantFeaturePermission()
*/
@@ -1011,8 +1009,6 @@
\value WebEngineView.EnvelopePrc10
\value WebEngineView.EnvelopeYou4
\value WebEngineView.LastPageSize = \c EnvelopeYou4
- \omitvalue NPageSize
- \omitvalue NPaperSize
\sa WebEngineView::printToPdf()
*/
@@ -1090,8 +1086,6 @@
Also if the audio is paused, this signal is emitted with an approximate \b{two-second
delay}, from the moment the audio is paused.
- This signal is also emitted for Flash plugin audio.
-
If a web page contains two videos that are started in sequence, this signal
gets emitted only once, for the first video to generate sound. After both
videos are stopped, the signal is emitted upon the last sound generated.
@@ -1167,8 +1161,6 @@
\a wasRecentlyAudible, is changed, due to audio being played or stopped.
\note The signal is also emitted when calling the setAudioMuted method.
- Also if the audio is paused, this signal is emitted with an approximate \b{2 second
- delay}, from the moment the audio is paused.
*/
/*!
@@ -1249,10 +1241,13 @@
/*!
\qmlsignal WebEngineView::quotaRequested(QuotaRequest request)
\since QtWebEngine 1.7
+ \deprecated [6.5] This signal is no longer emitted.
+
+ Requesting host quota is no longer supported by Chromium.
+ The behavior of navigator.webkitPersistentStorage
+ is identical to navigator.webkitTemporaryStorage.
- This signal is emitted when the web page issues a \a request for a larger persistent storage
- than the application's current allocation in File System API. The default quota
- is 0 bytes.
+ For further details, see https://crbug.com/1233525
\sa QuotaRequest
*/
@@ -1316,6 +1311,20 @@
*/
/*!
+ \qmlproperty WebEngineView WebEngineView::devToolsId
+ \since QtWebEngine 6.6
+ \readonly
+
+ The id of the developer tools host associated with this page.
+
+ If remote debugging is enabled (see \l{Qt WebEngine Developer Tools}), the id can be used to
+ build the URL to connect to the developer tool websocket:
+ \c{ws://localhost:<debugggin-port>/devtools/page/<id>)}. The websocket can be used to to interact
+ with the page using the \l{https://chromedevtools.github.io/devtools-protocol/}{DevTools
+ Protocol}.
+*/
+
+/*!
\qmlmethod WebEngineAction WebEngineView::action(WebAction action)
\since 5.12
@@ -1331,10 +1340,11 @@
*/
/*!
- \qmlsignal WebEngineView::printRequest
+ \qmlsignal WebEngineView::printRequested
\since QtWebEngine 1.8
- This signal is emitted when the JavaScript \c{window.print()} method is called.
+ This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print
+ button of PDF viewer plugin.
Typically, the signal handler can simply call printToPdf().
\sa printToPdf
@@ -1477,3 +1487,99 @@
\sa renderProcessPid
*/
+
+/*!
+ \qmlsignal WebEngineView::touchSelectionMenuRequested(TouchSelectionMenuRequest *request)
+ \since QtWebEngine 6.3
+ \readonly
+
+ This signal is emitted when a touch selection menu is requested at a specified position.
+
+ The \a request can be handled by using the methods of the TouchSelectionMenuRequest
+ type.
+
+ \note Signal handlers need to call \c{request.accepted = true} to prevent a default touch
+ selection menu from showing up.
+
+ \sa TouchSelectionMenuRequest
+*/
+
+/*!
+ \qmlproperty Component WebEngineView::touchHandleDelegate
+ \since QtWebEngine 6.4
+
+ The \a touchHandleDelegate provides a template defining visual touch handles instantiated by the view
+ whenever touch selection handling is required.
+
+ The handle's position, opacity, and visibility are updated automatically.
+ The delegate should be a QML Item or any QML type which inherits it.
+
+ \note If no QML Item is set, the default touch handles will be shown.
+
+ The following code uses a custom touch handle delegate:
+
+ \code
+ WebEngineView {
+ // ...
+ touchHandleDelegate: Rectangle {
+ color: "red"
+ }
+ // ...
+ }
+ \endcode
+
+ The touch handles can be also switched dynamically:
+
+ \code
+ Component {
+ id: circleTouchHandle
+ Rectangle {
+ color: "blue"
+ radius: 50
+ }
+ }
+ function showDefaultHandle(isDefault) {
+ if (isDefault)
+ webEngineView.touchHandleDelegate = circleTouchHandle
+ else
+ webEngineView.touchHandleDelegate = null
+ }
+ \endcode
+
+ \note If no delegate is provided, Chromium's default touch handles will appear.
+
+*/
+
+/*!
+ \qmlmethod void WebEngineView::save(const QString &filePath, QWebEngineDownloadRequest::SavePageFormat format)
+ \since QtWebEngine 6.6
+
+ Save the current web page to disk.
+
+ The web page is saved to \a filePath in the specified \a{format}.
+
+ This is a shortcut for the following actions:
+ \list
+ \li Trigger the Save web action.
+ \li Accept the next download item and set the specified file path and save format.
+ \endlist
+
+ This function issues an asynchronous download request for the web page and returns immediately.
+
+ \sa QWebEngineDownloadRequest::SavePageFormat
+*/
+
+/*!
+ \qmlsignal WebEngineView::webAuthUxRequested(QWebEngineWebAuthUxRequest *request);
+ \since QtWebEngine 6.7
+
+ This signal is emitted when a WebAuth authenticator requires user interaction
+ during the authentication process. These requests are handled by displaying a dialog to the user.
+
+ The \a request contains the information and API required to complete the WebAuth UX request.
+
+ \sa QWebEngineWebAuthUxRequest
+*/
+
+ \sa {WebEngine Qt Quick Custom Touch Handle Example}
+*/
diff --git a/src/webenginequick/plugin.cpp b/src/webenginequick/plugin.cpp
index f04f4f54e..e06596b44 100644
--- a/src/webenginequick/plugin.cpp
+++ b/src/webenginequick/plugin.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtQml/qqmlextensionplugin.h>
#include <QtWebEngineQuick/QQuickWebEngineProfile>
@@ -43,7 +7,13 @@
#include <QtWebEngineQuick/private/qquickwebenginefaviconprovider_p_p.h>
#include <QtWebEngineQuick/private/qquickwebenginetouchhandleprovider_p_p.h>
-void Q_WEBENGINEQUICK_PRIVATE_EXPORT qml_register_types_QtWebEngine();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
+QT_BEGIN_NAMESPACE
+void Q_WEBENGINEQUICK_EXPORT qml_register_types_QtWebEngine();
+QT_END_NAMESPACE
+#else
+void Q_WEBENGINEQUICK_EXPORT qml_register_types_QtWebEngine();
+#endif
QT_BEGIN_NAMESPACE
diff --git a/src/webenginequick/qquickwebengine_accessible.cpp b/src/webenginequick/qquickwebengine_accessible.cpp
new file mode 100644
index 000000000..2941f01b5
--- /dev/null
+++ b/src/webenginequick/qquickwebengine_accessible.cpp
@@ -0,0 +1,147 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickwebengine_accessible.h"
+
+#include <QQuickItem>
+#include <QQuickWindow>
+
+#include "api/qquickwebengineview_p.h"
+#include "api/qquickwebengineview_p_p.h"
+#include "web_contents_adapter.h"
+
+QT_BEGIN_NAMESPACE
+QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o)
+ : QAccessibleObject(o)
+{}
+
+bool QQuickWebEngineViewAccessible::isValid() const
+{
+ if (!QAccessibleObject::isValid())
+ return false;
+
+ if (!engineView() || !engineView()->d_func())
+ return false;
+
+ return true;
+}
+
+QAccessibleInterface *QQuickWebEngineViewAccessible::parent() const
+{
+ QQuickItem *parent = engineView()->parentItem();
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parent);
+ if (!iface)
+ return QAccessible::queryAccessibleInterface(engineView()->window());
+ return iface;
+}
+
+QAccessibleInterface *QQuickWebEngineViewAccessible::focusChild() const
+{
+ if (child(0) && child(0)->focusChild())
+ return child(0)->focusChild();
+ return const_cast<QQuickWebEngineViewAccessible *>(this);
+}
+
+int QQuickWebEngineViewAccessible::childCount() const
+{
+ return child(0) ? 1 : 0;
+}
+
+QAccessibleInterface *QQuickWebEngineViewAccessible::child(int index) const
+{
+ if (index == 0 && isValid())
+ return engineView()->d_func()->adapter->browserAccessible();
+ return nullptr;
+}
+
+int QQuickWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ if (child(0) && c == child(0))
+ return 0;
+ return -1;
+}
+
+QString QQuickWebEngineViewAccessible::text(QAccessible::Text) const
+{
+ return QString();
+}
+
+QAccessible::Role QQuickWebEngineViewAccessible::role() const
+{
+ return QAccessible::Client;
+}
+
+QAccessible::State QQuickWebEngineViewAccessible::state() const
+{
+ QAccessible::State s;
+ return s;
+}
+
+QQuickWebEngineView *QQuickWebEngineViewAccessible::engineView() const
+{
+ return static_cast<QQuickWebEngineView*>(object());
+}
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+RenderWidgetHostViewQtDelegateQuickAccessible::RenderWidgetHostViewQtDelegateQuickAccessible(QObject *o, QQuickWebEngineView *view)
+ : QAccessibleObject(o)
+ , m_view(view)
+{
+}
+
+bool RenderWidgetHostViewQtDelegateQuickAccessible::isValid() const
+{
+ if (!viewAccessible() || !viewAccessible()->isValid())
+ return false;
+
+ return QAccessibleObject::isValid();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::parent() const
+{
+ return viewAccessible()->parent();
+}
+
+QString RenderWidgetHostViewQtDelegateQuickAccessible::text(QAccessible::Text) const
+{
+ return QString();
+}
+
+QAccessible::Role RenderWidgetHostViewQtDelegateQuickAccessible::role() const
+{
+ return QAccessible::Client;
+}
+
+QAccessible::State RenderWidgetHostViewQtDelegateQuickAccessible::state() const
+{
+ return viewAccessible()->state();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::focusChild() const
+{
+ return viewAccessible()->focusChild();
+}
+
+int RenderWidgetHostViewQtDelegateQuickAccessible::childCount() const
+{
+ return viewAccessible()->childCount();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::child(int index) const
+{
+ return viewAccessible()->child(index);
+}
+
+int RenderWidgetHostViewQtDelegateQuickAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ return viewAccessible()->indexOfChild(c);
+}
+
+QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::viewAccessible() const
+{
+ return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
+}
+} // namespace QtWebEngineCore
diff --git a/src/webenginequick/qquickwebengine_accessible.h b/src/webenginequick/qquickwebengine_accessible.h
new file mode 100644
index 000000000..479de9789
--- /dev/null
+++ b/src/webenginequick/qquickwebengine_accessible.h
@@ -0,0 +1,56 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQUICKWEBENGINE_ACCESSIBLE_H
+#define QQUICKWEBENGINE_ACCESSIBLE_H
+
+#include <QtCore/qpointer.h>
+#include <QtGui/qaccessibleobject.h>
+
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineView;
+
+class QQuickWebEngineViewAccessible : public QAccessibleObject
+{
+public:
+ QQuickWebEngineViewAccessible(QQuickWebEngineView *o);
+ bool isValid() const override;
+ QAccessibleInterface *parent() const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *) const override;
+ QString text(QAccessible::Text) const override;
+ QAccessible::Role role() const override;
+ QAccessible::State state() const override;
+
+private:
+ QQuickWebEngineView *engineView() const;
+};
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+class RenderWidgetHostViewQtDelegateQuickAccessible : public QAccessibleObject
+{
+public:
+ RenderWidgetHostViewQtDelegateQuickAccessible(QObject *o, QQuickWebEngineView *view);
+
+ bool isValid() const override;
+ QAccessibleInterface *parent() const override;
+ QString text(QAccessible::Text t) const override;
+ QAccessible::Role role() const override;
+ QAccessible::State state() const override;
+
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *) const override;
+
+private:
+ QQuickWebEngineViewAccessible *viewAccessible() const;
+ QPointer<QQuickWebEngineView> m_view;
+};
+} // namespace QtWebEngineCore
+
+#endif // QQUICKWEBENGINE_ACCESSIBLE_H
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp
deleted file mode 100644
index cdc0cf426..000000000
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "render_widget_host_view_qt_delegate_quick.h"
-
-#include "render_widget_host_view_qt_delegate_client.h"
-
-#include "qquickwebengineview_p.h"
-#include "qquickwebengineview_p_p.h"
-
-#include <QtCore/qvariant.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qwindow.h>
-#include <QtQuick/qquickwindow.h>
-#include <QtQuick/qsgimagenode.h>
-
-namespace QtWebEngineCore {
-
-RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
- : m_client(client)
- , m_isPopup(isPopup)
-{
- setFlag(ItemHasContents);
- setAcceptedMouseButtons(Qt::AllButtons);
- setAcceptHoverEvents(true);
- setAcceptTouchEvents(true);
- if (!isPopup) {
- setFocus(true);
- setActiveFocusOnTab(true);
- }
- bind(client->compositorId());
-}
-
-RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
-{
- unbind();
- QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &screenRect)
-{
- //note this is called when there is no windowing system
- //otherwsie see RenderWidgetHostViewQtDelegateQuickWindow
- Q_ASSERT(m_isPopup && parentItem());
- setPosition(screenRect.topLeft());
- setSize(screenRect.size());
- setVisible(true);
-}
-
-QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const
-{
- // Transform the entire rect to find the correct top left corner.
- const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
- const QPointF p2 = mapToGlobal(mapFromScene(QPointF(width(), height())));
- QRectF geometry = QRectF(p1, p2).normalized();
- // But keep the size untransformed to behave like other QQuickItems.
- geometry.setSize(size());
- return geometry;
-}
-
-QRect RenderWidgetHostViewQtDelegateQuick::windowGeometry() const
-{
- if (!window())
- return QRect();
- return window()->frameGeometry();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::setKeyboardFocus()
-{
- setFocus(true);
-}
-
-bool RenderWidgetHostViewQtDelegateQuick::hasKeyboardFocus()
-{
- return hasActiveFocus();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::lockMouse()
-{
- grabMouse();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::unlockMouse()
-{
- ungrabMouse();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::show()
-{
- setVisible(true);
- m_client->notifyShown();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::hide()
-{
- setVisible(false);
- m_client->notifyHidden();
-}
-
-bool RenderWidgetHostViewQtDelegateQuick::isVisible() const
-{
- return QQuickItem::isVisible();
-}
-
-QWindow* RenderWidgetHostViewQtDelegateQuick::window() const
-{
- return QQuickItem::window();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::readyToSwap()
-{
- // Call update() on UI thread.
- QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::updateCursor(const QCursor &cursor)
-{
- setCursor(cursor);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::resize(int width, int height)
-{
- setSize(QSizeF(width, height));
-}
-
-void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVisible, bool passwordInput)
-{
- setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);
-
- if (parentItem())
- parentItem()->setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);
-
- qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
- if (qApp->inputMethod()->isVisible() != editorVisible)
- qApp->inputMethod()->setVisible(editorVisible);
-}
-
-bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event)
-{
- if (event->type() == QEvent::ShortcutOverride)
- return m_client->forwardEvent(event);
-
-#ifndef QT_NO_GESTURES
- if (event->type() == QEvent::NativeGesture)
- return m_client->forwardEvent(event);
-#endif
-
- return QQuickItem::event(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::focusInEvent(QFocusEvent *event)
-{
-#if QT_CONFIG(accessibility)
- if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(this)->focusChild()) {
- QAccessibleEvent focusEvent(iface, QAccessible::Focus);
- QAccessible::updateAccessibility(&focusEvent);
- }
-#endif // QT_CONFIG(accessibility)
-
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event)
-{
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event)
-{
- QQuickItem *parent = parentItem();
- if (!m_isPopup && (parent && parent->property("activeFocusOnPress").toBool()))
- forceActiveFocus();
- if (!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
- event->ignore();
- return;
- }
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::mouseMoveEvent(QMouseEvent *event)
-{
- QQuickItem *parent = parentItem();
- if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
- event->ignore();
- return;
- }
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::mouseReleaseEvent(QMouseEvent *event)
-{
- QQuickItem *parent = parentItem();
- if (!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
- event->ignore();
- return;
- }
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::keyPressEvent(QKeyEvent *event)
-{
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::keyReleaseEvent(QKeyEvent *event)
-{
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event)
-{
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event)
-{
- QQuickItem *parent = parentItem();
- if (event->type() == QEvent::TouchBegin && !m_isPopup
- && (parent && parent->property("activeFocusOnPress").toBool()))
- forceActiveFocus();
- if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
- event->ignore();
- return;
- }
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::hoverMoveEvent(QHoverEvent *event)
-{
- QQuickItem *parent = parentItem();
- if ((!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool()
- && !parent->hasActiveFocus())
- || event->position() == event->oldPosF()) {
- event->ignore();
- return;
- }
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::hoverLeaveEvent(QHoverEvent *event)
-{
- m_client->forwardEvent(event);
-}
-
-QVariant RenderWidgetHostViewQtDelegateQuick::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- return m_client->inputMethodQuery(query);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::inputMethodEvent(QInputMethodEvent *event)
-{
- m_client->forwardEvent(event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- QQuickItem::geometryChange(newGeometry, oldGeometry);
- m_client->visualPropertiesChanged();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const ItemChangeData &value)
-{
- QQuickItem::itemChange(change, value);
- if (change == QQuickItem::ItemSceneChange) {
- for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
- disconnect(c);
- m_windowConnections.clear();
- if (value.window) {
- m_windowConnections.append(connect(value.window, SIGNAL(beforeRendering()),
- SLOT(onBeforeRendering()), Qt::DirectConnection));
- 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())));
- }
- m_client->visualPropertiesChanged();
- } else if (change == QQuickItem::ItemVisibleHasChanged) {
- if (!m_isPopup && !value.boolValue)
- onHide();
- }
-}
-
-QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
- auto comp = compositor();
- if (!comp)
- return nullptr;
-
- QQuickWindow *win = QQuickItem::window();
-
- // Delete old node before swapFrame to decrement refcount of
- // QImage in software mode.
- delete oldNode;
- QSGImageNode *node = win->createImageNode();
- node->setOwnsTexture(true);
-
- comp->swapFrame();
-
- QSize texSize = comp->size();
- QSizeF texSizeInDips = QSizeF(texSize) / comp->devicePixelRatio();
- node->setRect(QRectF(QPointF(0, 0), texSizeInDips));
-
- if (comp->type() == Compositor::Type::Software) {
- QImage image = comp->image();
- node->setTexture(win->createTextureFromImage(image));
- } else if (comp->type() == Compositor::Type::OpenGL) {
- QQuickWindow::CreateTextureOptions texOpts;
-#if QT_CONFIG(opengl)
- if (comp->hasAlphaChannel())
- texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
- int texId = comp->textureId();
- node->setTexture(QNativeInterface::QSGOpenGLTexture::fromNative(texId, win, texSize, texOpts));
- node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
-#else
- Q_UNREACHABLE();
-#endif
- } else {
- Q_UNREACHABLE();
- }
-
- return node;
-}
-
-void RenderWidgetHostViewQtDelegateQuick::onBeforeRendering()
-{
- auto comp = compositor();
- if (!comp || comp->type() != Compositor::Type::OpenGL)
- return;
- comp->waitForTexture();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged()
-{
- m_client->visualPropertiesChanged();
-}
-
-void RenderWidgetHostViewQtDelegateQuick::onHide()
-{
- QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
- m_client->forwardEvent(&event);
-}
-
-void RenderWidgetHostViewQtDelegateQuick::adapterClientChanged(WebContentsAdapterClient *client)
-{
- QQuickWebEngineViewPrivate::bindViewAndWidget(
- static_cast<QQuickWebEngineViewPrivate *>(client)->q_func(), this);
-}
-
-#if QT_CONFIG(accessibility)
-RenderWidgetHostViewQtDelegateQuickAccessible::RenderWidgetHostViewQtDelegateQuickAccessible(RenderWidgetHostViewQtDelegateQuick *o, QQuickWebEngineView *view)
- : QAccessibleObject(o)
- , m_view(view)
-{
-}
-
-bool RenderWidgetHostViewQtDelegateQuickAccessible::isValid() const
-{
- if (!viewAccessible() || !viewAccessible()->isValid())
- return false;
-
- return QAccessibleObject::isValid();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::parent() const
-{
- return viewAccessible()->parent();
-}
-
-QString RenderWidgetHostViewQtDelegateQuickAccessible::text(QAccessible::Text) const
-{
- return QString();
-}
-
-QAccessible::Role RenderWidgetHostViewQtDelegateQuickAccessible::role() const
-{
- return QAccessible::Client;
-}
-
-QAccessible::State RenderWidgetHostViewQtDelegateQuickAccessible::state() const
-{
- return viewAccessible()->state();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::focusChild() const
-{
- return viewAccessible()->focusChild();
-}
-
-int RenderWidgetHostViewQtDelegateQuickAccessible::childCount() const
-{
- return viewAccessible()->childCount();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::child(int index) const
-{
- return viewAccessible()->child(index);
-}
-
-int RenderWidgetHostViewQtDelegateQuickAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- return viewAccessible()->indexOfChild(c);
-}
-
-QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::viewAccessible() const
-{
- return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
-}
-#endif // QT_CONFIG(accessibility)
-
-} // namespace QtWebEngineCore
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quick.h b/src/webenginequick/render_widget_host_view_qt_delegate_quick.h
deleted file mode 100644
index 1580e0614..000000000
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quick.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
-#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
-
-#include "compositor/compositor.h"
-#include "render_widget_host_view_qt_delegate.h"
-
-#include <QtGui/qaccessibleobject.h>
-#include <QtQuick/qquickitem.h>
-
-QT_BEGIN_NAMESPACE
-class QQuickWebEngineView;
-class QQuickWebEngineViewAccessible;
-class QQuickWebEngineViewPrivate;
-QT_END_NAMESPACE
-
-namespace QtWebEngineCore {
-
-class RenderWidgetHostViewQtDelegateClient;
-
-class RenderWidgetHostViewQtDelegateQuick : public QQuickItem,
- public RenderWidgetHostViewQtDelegate,
- public Compositor::Observer
-{
- Q_OBJECT
-public:
- RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
- ~RenderWidgetHostViewQtDelegateQuick();
-
- void initAsPopup(const QRect&) override;
- QRectF viewGeometry() const override;
- QRect windowGeometry() const override;
- void setKeyboardFocus() override;
- bool hasKeyboardFocus() override;
- void lockMouse() override;
- void unlockMouse() override;
- void show() override;
- void hide() override;
- bool isVisible() const override;
- QWindow* window() const override;
- void updateCursor(const QCursor &) override;
- void resize(int width, int height) override;
- void move(const QPoint&) override { }
- void inputMethodStateChanged(bool editorVisible, bool isPasswordInput) override;
- void setInputMethodHints(Qt::InputMethodHints) override { }
- // The QtQuick view doesn't have a backbuffer of its own and doesn't need this
- void setClearColor(const QColor &) override { }
- void readyToSwap() override;
- void adapterClientChanged(WebContentsAdapterClient *client) override;
-
-protected:
- bool event(QEvent *event) override;
- void focusInEvent(QFocusEvent *event) override;
- void focusOutEvent(QFocusEvent *event) override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void keyPressEvent(QKeyEvent *event) override;
- void keyReleaseEvent(QKeyEvent *event) override;
- void wheelEvent(QWheelEvent *event) override;
- void touchEvent(QTouchEvent *event) override;
- void hoverMoveEvent(QHoverEvent *event) override;
- void hoverLeaveEvent(QHoverEvent *event) override;
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
- void inputMethodEvent(QInputMethodEvent *event) override;
- void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
- void itemChange(ItemChange change, const ItemChangeData &value) override;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
-
-private Q_SLOTS:
- void onBeforeRendering();
- void onWindowPosChanged();
- void onHide();
-
-private:
- friend QQuickWebEngineViewPrivate;
-
- RenderWidgetHostViewQtDelegateClient *m_client;
- QList<QMetaObject::Connection> m_windowConnections;
- bool m_isPopup;
- QQuickWebEngineView *m_view = nullptr;
-};
-
-#if QT_CONFIG(accessibility)
-class RenderWidgetHostViewQtDelegateQuickAccessible : public QAccessibleObject
-{
-public:
- RenderWidgetHostViewQtDelegateQuickAccessible(RenderWidgetHostViewQtDelegateQuick *o, QQuickWebEngineView *view);
-
- bool isValid() const override;
- QAccessibleInterface *parent() const override;
- QString text(QAccessible::Text t) const override;
- QAccessible::Role role() const override;
- QAccessible::State state() const override;
-
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface *) const override;
-
-private:
- QQuickWebEngineViewAccessible *viewAccessible() const;
- QQuickWebEngineView *m_view;
-};
-#endif // QT_CONFIG(accessibility)
-
-} // namespace QtWebEngineCore
-
-#endif
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
index 7cae38b2e..b003dabe4 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -1,46 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "render_widget_host_view_qt_delegate_quick.h"
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#include "render_widget_host_view_qt_delegate_quickwindow.h"
-#include <QtQuick/qquickitem.h>
+#include "api/qquickwebengineview_p_p.h"
namespace QtWebEngineCore {
@@ -68,14 +31,19 @@ static inline QPointF transformPoint(const QPointF &point, const QTransform &tra
}
RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(
- RenderWidgetHostViewQtDelegateQuick *realDelegate, QWindow *parent)
+ RenderWidgetHostViewQtDelegateItem *realDelegate, QWindow *parent)
: QQuickWindow(parent), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_rotated(false)
{
setFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+ realDelegate->setParentItem(contentItem());
}
RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickWindow()
{
+ if (m_realDelegate) {
+ m_realDelegate->setWidgetDelegate(nullptr);
+ m_realDelegate->setParentItem(nullptr);
+ }
}
void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *virtualParent)
@@ -86,9 +54,9 @@ void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *vir
// rect is window geometry in form of parent window offset + offset in scene coordinates
// chromium knows nothing about local transformation
-void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
+void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
{
- m_rotated = m_virtualParent->parentItem()->rotation() > 0;
+ m_rotated = m_virtualParent->rotation() > 0 || m_virtualParent->parentItem()->rotation() > 0;
if (m_rotated) {
// code below tries to cover the case where webengine view is rotated,
// the code assumes the rotation is in the form of 90, 180, 270 degrees
@@ -104,7 +72,6 @@ void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
QPointF br = transformPoint(rect.bottomRight(), transform, offset, m_virtualParent);
QRectF popupRect(tl, br);
popupRect = popupRect.normalized();
- m_realDelegate->setSize(rect.size());
// include offset from parent window
popupRect.moveTo(popupRect.topLeft() - offset);
setGeometry(popupRect.adjusted(0, 0, 1, 1).toRect());
@@ -115,64 +82,51 @@ void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
m_realDelegate->setTransformOrigin(QQuickItem::Center);
m_realDelegate->setRotation(m_virtualParent->parentItem()->rotation());
} else {
- m_realDelegate->setSize(rect.size());
QRect geometry(rect);
geometry.moveTo(rect.topLeft() - getOffset(m_virtualParent));
setGeometry(geometry);
}
+ m_realDelegate->show();
raise();
show();
}
-QRectF RenderWidgetHostViewQtDelegateQuickWindow::viewGeometry() const
-{
- return m_rotated ? m_rect : geometry();
-}
-
-QRect RenderWidgetHostViewQtDelegateQuickWindow::windowGeometry() const
-{
- return m_rotated ? m_rect : frameGeometry();
-}
-
-void RenderWidgetHostViewQtDelegateQuickWindow::show()
+void RenderWidgetHostViewQtDelegateQuickWindow::Resize(int width, int height)
{
- QQuickWindow::show();
- m_realDelegate->show();
+ if (!m_rotated)
+ QQuickWindow::resize(width, height);
}
-void RenderWidgetHostViewQtDelegateQuickWindow::hide()
+void RenderWidgetHostViewQtDelegateQuickWindow::MoveWindow(const QPoint &screenPos)
{
- QQuickWindow::hide();
- m_realDelegate->hide();
+ if (!m_rotated)
+ QQuickWindow::setPosition(screenPos - getOffset(m_virtualParent));
}
-bool RenderWidgetHostViewQtDelegateQuickWindow::isVisible() const
+void RenderWidgetHostViewQtDelegateQuickWindow::SetClearColor(const QColor &color)
{
- return QQuickWindow::isVisible();
+ QQuickWindow::setColor(color);
}
-QWindow *RenderWidgetHostViewQtDelegateQuickWindow::window() const
+bool RenderWidgetHostViewQtDelegateQuickWindow::ActiveFocusOnPress()
{
- return const_cast<RenderWidgetHostViewQtDelegateQuickWindow*>(this);
+ return false;
}
-void RenderWidgetHostViewQtDelegateQuickWindow::updateCursor(const QCursor &cursor)
+void RenderWidgetHostViewQtDelegateQuickWindow::Bind(QtWebEngineCore::WebContentsAdapterClient *client)
{
- setCursor(cursor);
+ QQuickWebEngineViewPrivate::bindViewAndDelegateItem(
+ static_cast<QQuickWebEngineViewPrivate *>(client), m_realDelegate.data());
}
-void RenderWidgetHostViewQtDelegateQuickWindow::resize(int width, int height)
+void RenderWidgetHostViewQtDelegateQuickWindow::Unbind()
{
- if (!m_rotated) {
- QQuickWindow::resize(width, height);
- m_realDelegate->resize(width, height);
- }
+ QQuickWebEngineViewPrivate::bindViewAndDelegateItem(nullptr, m_realDelegate.data());
}
-void RenderWidgetHostViewQtDelegateQuickWindow::move(const QPoint &screenPos)
+void RenderWidgetHostViewQtDelegateQuickWindow::Destroy()
{
- if (!m_rotated)
- QQuickWindow::setPosition(screenPos - getOffset(m_virtualParent));
+ deleteLater();
}
} // namespace QtWebEngineCore
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h
index f7dfd1a05..712eef732 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h
@@ -1,83 +1,41 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICKWINDOW_H
#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICKWINDOW_H
#include "render_widget_host_view_qt_delegate.h"
+#include "render_widget_host_view_qt_delegate_item.h"
-#include <QtCore/qscopedpointer.h>
+#include <QtCore/qpointer.h>
#include <QtQuick/qquickwindow.h>
-namespace QtWebEngineCore {
+// silence syncqt
+QT_BEGIN_NAMESPACE
+QT_END_NAMESPACE
-class RenderWidgetHostViewQtDelegateQuick;
+namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public RenderWidgetHostViewQtDelegate {
+class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public WidgetDelegate {
public:
- RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate,
+ RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateItem *realDelegate,
QWindow *parent);
~RenderWidgetHostViewQtDelegateQuickWindow();
- void initAsPopup(const QRect&) override;
- QRectF viewGeometry() const override;
- QRect windowGeometry() const override;
- void setKeyboardFocus() override {}
- bool hasKeyboardFocus() override { return false; }
- void lockMouse() override {}
- void unlockMouse() override {}
- void show() override;
- void hide() override;
- bool isVisible() const override;
- QWindow* window() const override;
- void updateCursor(const QCursor &) override;
- void resize(int width, int height) override;
- void move(const QPoint &screenPos) override;
- void inputMethodStateChanged(bool, bool) override {}
- void setInputMethodHints(Qt::InputMethodHints) override { }
- void setClearColor(const QColor &) override { }
- void adapterClientChanged(WebContentsAdapterClient *) override { }
+ void InitAsPopup(const QRect &screenRect) override;
+ void SetClearColor(const QColor &) override;
+ bool ActiveFocusOnPress() override;
+ void MoveWindow(const QPoint &) override;
+ void Bind(WebContentsAdapterClient *) override;
+ void Unbind() override;
+ void Destroy() override;
+ void Resize(int width, int height) override;
+
void setVirtualParent(QQuickItem *virtualParent);
private:
- QScopedPointer<RenderWidgetHostViewQtDelegateQuick> m_realDelegate;
+ QPointer<RenderWidgetHostViewQtDelegateItem> m_realDelegate;
QQuickItem *m_virtualParent;
QRect m_rect;
bool m_rotated;
diff --git a/src/webenginequick/ui/AlertDialog.qml b/src/webenginequick/ui/AlertDialog.qml
index a806ec306..e4c17b056 100644
--- a/src/webenginequick/ui/AlertDialog.qml
+++ b/src/webenginequick/ui/AlertDialog.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
@@ -85,6 +49,7 @@ Dialog {
id: message
Layout.fillWidth: true
color: palette.windowText
+ textFormat: Text.PlainText
}
}
Item {
diff --git a/src/webenginequick/ui/AuthenticationDialog.qml b/src/webenginequick/ui/AuthenticationDialog.qml
index 1c865010a..d0611b84f 100644
--- a/src/webenginequick/ui/AuthenticationDialog.qml
+++ b/src/webenginequick/ui/AuthenticationDialog.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
@@ -86,6 +50,7 @@ Dialog {
Label {
id: message
color: palette.windowText
+ textFormat: Text.PlainText
}
GridLayout {
columns: 2
diff --git a/src/webenginequick/ui/AutofillPopup.qml b/src/webenginequick/ui/AutofillPopup.qml
new file mode 100644
index 000000000..0a14b6233
--- /dev/null
+++ b/src/webenginequick/ui/AutofillPopup.qml
@@ -0,0 +1,41 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Controls
+
+Popup {
+ id: root
+ // Let Chromium close the popup.
+ closePolicy: Popup.NoAutoClose
+
+ property variant controller: null
+ property int itemHeight: 0
+
+ signal selected(int index)
+ signal accepted()
+
+ function setCurrentIndex(index)
+ {
+ listView.currentIndex = index;
+ }
+
+ ListView {
+ id: listView
+ anchors.fill: parent
+ clip: true
+
+ model: controller.model
+ currentIndex: -1
+
+ delegate: ItemDelegate {
+ width: listView.width
+ height: root.itemHeight
+ text: model.display
+ highlighted: ListView.isCurrentItem
+
+ onHoveredChanged: if (hovered) selected(index);
+ onClicked: accepted();
+ }
+ }
+}
diff --git a/src/webenginequick/ui/CMakeLists.txt b/src/webenginequick/ui/CMakeLists.txt
index aa5832ba6..ac960535e 100644
--- a/src/webenginequick/ui/CMakeLists.txt
+++ b/src/webenginequick/ui/CMakeLists.txt
@@ -1,8 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (Qt6Quick_VERSION VERSION_GREATER_EQUAL "6.4.0")
+set(colorDialog "ColorDialog.qml")
+else()
+set(colorDialog "custom/ColorDialog.qml")
+endif()
+
set(qml_files
"AlertDialog.qml"
"AuthenticationDialog.qml"
- "ColorDialog.qml"
+ "AutofillPopup.qml"
"ConfirmDialog.qml"
+ "DirectoryPicker.qml"
"FilePicker.qml"
"Menu.qml"
"MenuItem.qml"
@@ -11,6 +21,7 @@ set(qml_files
"ToolTip.qml"
"TouchHandle.qml"
"TouchSelectionMenu.qml"
+ ${colorDialog}
)
set(resource_files
@@ -26,6 +37,7 @@ qt_internal_add_qml_module(WebEngineQuickDelegatesQml
NO_SYNC_QT
PLUGIN_TARGET qtwebenginequickdelegatesplugin
DEPENDENCIES QtQuickControls2
+ NO_GENERATE_CPP_EXPORTS
)
qt_internal_add_resource(qtwebenginequickdelegatesplugin "qtwebenginequickdelegatesplugin"
diff --git a/src/webenginequick/ui/ColorDialog.qml b/src/webenginequick/ui/ColorDialog.qml
index 56216f49b..f4d5b817b 100644
--- a/src/webenginequick/ui/ColorDialog.qml
+++ b/src/webenginequick/ui/ColorDialog.qml
@@ -1,321 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
+import QtQuick.Dialogs
-Dialog {
+ColorDialog {
id: colorDialog
- title: qsTr("Color Picker Dialog")
- modal: false
- anchors.centerIn: parent
objectName: "colorDialog"
- property bool handled: false
- property color color
-
signal selectedColor(var color)
- signal rejected()
-
- function accept() {
- handled = true;
- selectedColor(colorDialog.color)
- close();
- }
-
- function reject() {
- handled = true;
- rejected();
- close();
- }
-
- // Handle the case where users simply closes or clicks out of the dialog.
- onVisibleChanged: {
- if (!visible && !handled) {
- handled = true;
- rejected();
- } else {
- handled = false;
- }
- }
-
- function selectColorFromPalette(paletteColor) {
- colorDialog.color = paletteColor;
- }
-
- function zeroPadding(text, length = 2) {
- var textLength = text.length;
-
- if (textLength >= length) {
- return text;
- }
-
- for (var i = 0; i < length - textLength; i++) {
- text = "0" + text;
- }
-
- return text;
- }
-
- function calculateRGBA() {
-
- var rgbArray = [colorDialog.color.r, colorDialog.color.g, colorDialog.color.b]
- if (colorDialog.color.a != 1) {
- rgbArray.push(colorDialog.color.a);
- }
-
- for (var i = 0; i < rgbArray.length; i++) {
- rgbArray[i] = Number(Math.round(rgbArray[i] * 255)).toString(16);
- rgbArray[i] = zeroPadding(rgbArray[i]);
- }
-
- return "#" + rgbArray.join("");
- }
-
-
- function isNaNOrUndefined(value) {
- return value == null || value == undefined || Number.isNaN(value);
- }
-
- function parseColorText(colorText) {
- if (colorText[0] == '#') {
- colorText = colorText.substring(1);
- }
-
- if (!(colorText.length == 6 || colorText.length == 8)) {
- return undefined;
- }
-
- var rgbaValues = [parseInt("0x" + colorText.substring(0,2)),
- parseInt("0x" + colorText.substring(2,4)),
- parseInt("0x" + colorText.substring(4,6)),
- parseInt("0x" + (colorText.length > 6 ? colorText.substring(6,8) : "FF"))]
-
- for (var i = 0; i < rgbaValues.length; i++) {
- if (isNaNOrUndefined(rgbaValues[i])) {
- return undefined;
- }
- rgbaValues[i] = rgbaValues[i] / 255;
- }
-
- return Qt.rgba(rgbaValues[0], rgbaValues[1], rgbaValues[2], rgbaValues[3]);
- }
-
- ListModel {
- id: colorList
- ListElement { rectangleColor: "red" }
- ListElement { rectangleColor: "orangered" }
- ListElement { rectangleColor: "orange" }
- ListElement { rectangleColor: "gold" }
- ListElement { rectangleColor: "yellow" }
- ListElement { rectangleColor: "yellowgreen" }
- ListElement { rectangleColor: "green" }
- ListElement { rectangleColor: "lightskyblue" }
- ListElement { rectangleColor: "blue" }
- ListElement { rectangleColor: "blueviolet" }
- ListElement { rectangleColor: "violet" }
- ListElement { rectangleColor: "mediumvioletred" }
- ListElement { rectangleColor: "black" }
- ListElement { rectangleColor: "white" }
- }
-
- contentItem: GridLayout {
- id: grid
- columns: 7
- rows: 5
-
- Repeater {
- model: colorList
- delegate: Rectangle {
- width: 50
- height: 50
- color: rectangleColor
- border.color: "black"
- border.width: 1
-
- MouseArea {
- anchors.fill: parent
- onClicked: selectColorFromPalette(parent.color)
- }
- }
- }
- ColumnLayout {
- id: colorTools
- Layout.columnSpan: 4
- Layout.rowSpan: 2
- Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
-
- Rectangle {
- height: 100
- width: 200
- border.color: "black"
- border.width: 1
-
- Binding on color {
- when: colorDialog.color
- value: colorDialog.color
- }
- }
- TextField {
- id: colorTextField
- width: 100
- selectByMouse: true
- Layout.alignment: Qt.AlignHCenter
-
- Binding on text {
- when: colorDialog.color
- value: calculateRGBA()
- delayed: true
- }
-
- onTextEdited: {
- var parsedColor = parseColorText(colorTextField.text);
- if (parsedColor != undefined) {
- colorDialog.color = parsedColor;
- }
- }
-
- MouseArea {
- id: colorTextFieldMouseArea
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- onClicked: colorTextFieldContextMenu.open()
- }
-
- Menu {
- id: colorTextFieldContextMenu
- x: colorTextFieldMouseArea.mouseX
- y: colorTextFieldMouseArea.mouseY
- MenuItem {
- text: qsTr("Copy color")
- onTriggered: {
- colorTextField.selectAll();
- colorTextField.copy();
- colorTextField.deselect();
- }
- }
- MenuSeparator {}
- MenuItem {
- text: qsTr("Paste")
- onTriggered: {
- colorTextField.selectAll();
- colorTextField.paste();
- }
- enabled: colorTextField.canPaste
- }
- }
- }
- }
- ListModel {
- id: sliderBoxElements
- ListElement { labelText: "Red value"; colorChannel: 0 }
- ListElement { labelText: "Green value"; colorChannel: 1 }
- ListElement { labelText: "Blue value"; colorChannel: 2 }
- ListElement { labelText: "Alpha value"; colorChannel: 3 }
- }
- ColumnLayout {
- id: sliderBox
- Layout.columnSpan: 3
- Layout.rowSpan: 2
- Layout.fillWidth: true
- Layout.fillHeight: true
-
- Repeater {
- model: sliderBoxElements
- delegate: ColumnLayout {
- Label {
- text: labelText
- }
- Slider {
- id: colorSlider
- property int channel: colorChannel
- from: 0
- to: 255
- stepSize: 1
- value: {
- if (colorSlider.channel == 0)
- return colorDialog.color.r * 255;
- else if (colorSlider.channel == 1)
- return colorDialog.color.g * 255;
- else if (colorSlider.channel == 2)
- return colorDialog.color.b * 255;
- else if (colorSlider.channel == 3)
- return colorDialog.color.a * 255;
- }
-
- Connections {
- function onMoved() {
- var redChannelValue = colorDialog.color.r;
- var greenChannelValue = colorDialog.color.g;
- var blueChannelValue = colorDialog.color.b;
- var alphaChannelValue = colorDialog.color.a;
-
- if (colorSlider.channel == 0)
- redChannelValue = colorSlider.value / 255;
- else if (colorSlider.channel == 1)
- greenChannelValue = colorSlider.value / 255;
- else if (colorSlider.channel == 2)
- blueChannelValue = colorSlider.value / 255;
- else if (colorSlider.channel == 3)
- alphaChannelValue = colorSlider.value / 255;
-
- colorDialog.color = Qt.rgba(redChannelValue, greenChannelValue, blueChannelValue, alphaChannelValue);
- }
- }
- }
- }
- }
- }
- DialogButtonBox {
- id: dialogButtonBox
- Layout.columnSpan: 7
- Layout.alignment: Qt.AlignRight
- Button {
- text: qsTr("Apply")
- onClicked: accept()
- }
- Button {
- text: qsTr("Cancel")
- onClicked: reject()
- }
- }
- }
+ onAccepted : selectedColor(selectedColor)
}
diff --git a/src/webenginequick/ui/ConfirmDialog.qml b/src/webenginequick/ui/ConfirmDialog.qml
index 0ce7a97f2..cfffe7c4d 100644
--- a/src/webenginequick/ui/ConfirmDialog.qml
+++ b/src/webenginequick/ui/ConfirmDialog.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
@@ -91,6 +55,7 @@ Dialog {
id: message
Layout.fillWidth: true
color: palette.windowText
+ textFormat: Text.PlainText
}
}
Item {
diff --git a/src/webenginequick/ui/DirectoryPicker.qml b/src/webenginequick/ui/DirectoryPicker.qml
new file mode 100644
index 000000000..a8a6d47c9
--- /dev/null
+++ b/src/webenginequick/ui/DirectoryPicker.qml
@@ -0,0 +1,15 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick.Dialogs
+
+FolderDialog {
+ id: folderDialog
+ objectName: "folderDialog"
+
+ signal folderSelected(var folder)
+
+ onAccepted: {
+ folderSelected([selectedFolder])
+ }
+}
diff --git a/src/webenginequick/ui/FilePicker.qml b/src/webenginequick/ui/FilePicker.qml
index e84ff2265..d82c3bf35 100644
--- a/src/webenginequick/ui/FilePicker.qml
+++ b/src/webenginequick/ui/FilePicker.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick.Dialogs
diff --git a/src/webenginequick/ui/Menu.qml b/src/webenginequick/ui/Menu.qml
index b6d799d02..bfa037d1c 100644
--- a/src/webenginequick/ui/Menu.qml
+++ b/src/webenginequick/ui/Menu.qml
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
-import QtQuick.Controls
+import QtQuick.Controls as C
-Menu {
+C.Menu {
id: menu
signal done()
objectName: "menu"
diff --git a/src/webenginequick/ui/MenuItem.qml b/src/webenginequick/ui/MenuItem.qml
index b4e06ccc2..8fefcdc69 100644
--- a/src/webenginequick/ui/MenuItem.qml
+++ b/src/webenginequick/ui/MenuItem.qml
@@ -1,44 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
-import QtQuick.Controls
-
-MenuItem { }
+import QtQuick.Controls as C
+C.MenuItem { }
diff --git a/src/webenginequick/ui/MenuSeparator.qml b/src/webenginequick/ui/MenuSeparator.qml
index 3d73adf5e..af37f57a9 100644
--- a/src/webenginequick/ui/MenuSeparator.qml
+++ b/src/webenginequick/ui/MenuSeparator.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
diff --git a/src/webenginequick/ui/PromptDialog.qml b/src/webenginequick/ui/PromptDialog.qml
index 81b9812ad..275deace8 100644
--- a/src/webenginequick/ui/PromptDialog.qml
+++ b/src/webenginequick/ui/PromptDialog.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
@@ -88,6 +52,7 @@ Dialog {
id: message
Layout.fillWidth: true
color: palette.windowText
+ textFormat: Text.PlainText
}
TextField {
id:field
diff --git a/src/webenginequick/ui/ToolTip.qml b/src/webenginequick/ui/ToolTip.qml
index 8800bb1f8..525258e2f 100644
--- a/src/webenginequick/ui/ToolTip.qml
+++ b/src/webenginequick/ui/ToolTip.qml
@@ -1,45 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-import QtQuick.Controls
+import QtQuick.Controls as C
-ToolTip {
+C.ToolTip {
delay: 1000
timeout: 1500
objectName: "toolTip"
diff --git a/src/webenginequick/ui/TouchHandle.qml b/src/webenginequick/ui/TouchHandle.qml
index 1c7490c88..a879ec71b 100644
--- a/src/webenginequick/ui/TouchHandle.qml
+++ b/src/webenginequick/ui/TouchHandle.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
diff --git a/src/webenginequick/ui/TouchSelectionMenu.qml b/src/webenginequick/ui/TouchSelectionMenu.qml
index 4bb803271..f42c256bb 100644
--- a/src/webenginequick/ui/TouchSelectionMenu.qml
+++ b/src/webenginequick/ui/TouchSelectionMenu.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Layouts
diff --git a/src/webenginequick/ui/custom/ColorDialog.qml b/src/webenginequick/ui/custom/ColorDialog.qml
new file mode 100644
index 000000000..895c90198
--- /dev/null
+++ b/src/webenginequick/ui/custom/ColorDialog.qml
@@ -0,0 +1,285 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+Dialog {
+ id: colorDialog
+ title: qsTr("Color Picker Dialog")
+ modal: false
+ anchors.centerIn: parent
+ objectName: "colorDialog"
+
+ property bool handled: false
+ property color color
+
+ signal selectedColor(var color)
+ signal rejected()
+
+ function accept() {
+ handled = true;
+ selectedColor(colorDialog.color)
+ close();
+ }
+
+ function reject() {
+ handled = true;
+ rejected();
+ close();
+ }
+
+ // Handle the case where users simply closes or clicks out of the dialog.
+ onVisibleChanged: {
+ if (!visible && !handled) {
+ handled = true;
+ rejected();
+ } else {
+ handled = false;
+ }
+ }
+
+ function selectColorFromPalette(paletteColor) {
+ colorDialog.color = paletteColor;
+ }
+
+ function zeroPadding(text, length = 2) {
+ var textLength = text.length;
+
+ if (textLength >= length) {
+ return text;
+ }
+
+ for (var i = 0; i < length - textLength; i++) {
+ text = "0" + text;
+ }
+
+ return text;
+ }
+
+ function calculateRGBA() {
+
+ var rgbArray = [colorDialog.color.r, colorDialog.color.g, colorDialog.color.b]
+ if (colorDialog.color.a != 1) {
+ rgbArray.push(colorDialog.color.a);
+ }
+
+ for (var i = 0; i < rgbArray.length; i++) {
+ rgbArray[i] = Number(Math.round(rgbArray[i] * 255)).toString(16);
+ rgbArray[i] = zeroPadding(rgbArray[i]);
+ }
+
+ return "#" + rgbArray.join("");
+ }
+
+
+ function isNaNOrUndefined(value) {
+ return value == null || value == undefined || Number.isNaN(value);
+ }
+
+ function parseColorText(colorText) {
+ if (colorText[0] == '#') {
+ colorText = colorText.substring(1);
+ }
+
+ if (!(colorText.length == 6 || colorText.length == 8)) {
+ return undefined;
+ }
+
+ var rgbaValues = [parseInt("0x" + colorText.substring(0,2)),
+ parseInt("0x" + colorText.substring(2,4)),
+ parseInt("0x" + colorText.substring(4,6)),
+ parseInt("0x" + (colorText.length > 6 ? colorText.substring(6,8) : "FF"))]
+
+ for (var i = 0; i < rgbaValues.length; i++) {
+ if (isNaNOrUndefined(rgbaValues[i])) {
+ return undefined;
+ }
+ rgbaValues[i] = rgbaValues[i] / 255;
+ }
+
+ return Qt.rgba(rgbaValues[0], rgbaValues[1], rgbaValues[2], rgbaValues[3]);
+ }
+
+ ListModel {
+ id: colorList
+ ListElement { rectangleColor: "red" }
+ ListElement { rectangleColor: "orangered" }
+ ListElement { rectangleColor: "orange" }
+ ListElement { rectangleColor: "gold" }
+ ListElement { rectangleColor: "yellow" }
+ ListElement { rectangleColor: "yellowgreen" }
+ ListElement { rectangleColor: "green" }
+ ListElement { rectangleColor: "lightskyblue" }
+ ListElement { rectangleColor: "blue" }
+ ListElement { rectangleColor: "blueviolet" }
+ ListElement { rectangleColor: "violet" }
+ ListElement { rectangleColor: "mediumvioletred" }
+ ListElement { rectangleColor: "black" }
+ ListElement { rectangleColor: "white" }
+ }
+
+ contentItem: GridLayout {
+ id: grid
+ columns: 7
+ rows: 5
+
+ Repeater {
+ model: colorList
+ delegate: Rectangle {
+ width: 50
+ height: 50
+ color: rectangleColor
+ border.color: "black"
+ border.width: 1
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: selectColorFromPalette(parent.color)
+ }
+ }
+ }
+ ColumnLayout {
+ id: colorTools
+ Layout.columnSpan: 4
+ Layout.rowSpan: 2
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ Rectangle {
+ height: 100
+ width: 200
+ border.color: "black"
+ border.width: 1
+
+ Binding on color {
+ when: colorDialog.color
+ value: colorDialog.color
+ }
+ }
+ TextField {
+ id: colorTextField
+ width: 100
+ selectByMouse: true
+ Layout.alignment: Qt.AlignHCenter
+
+ Binding on text {
+ when: colorDialog.color
+ value: calculateRGBA()
+ delayed: true
+ }
+
+ onTextEdited: {
+ var parsedColor = parseColorText(colorTextField.text);
+ if (parsedColor != undefined) {
+ colorDialog.color = parsedColor;
+ }
+ }
+
+ MouseArea {
+ id: colorTextFieldMouseArea
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: colorTextFieldContextMenu.open()
+ }
+
+ Menu {
+ id: colorTextFieldContextMenu
+ x: colorTextFieldMouseArea.mouseX
+ y: colorTextFieldMouseArea.mouseY
+ MenuItem {
+ text: qsTr("Copy color")
+ onTriggered: {
+ colorTextField.selectAll();
+ colorTextField.copy();
+ colorTextField.deselect();
+ }
+ }
+ MenuSeparator {}
+ MenuItem {
+ text: qsTr("Paste")
+ onTriggered: {
+ colorTextField.selectAll();
+ colorTextField.paste();
+ }
+ enabled: colorTextField.canPaste
+ }
+ }
+ }
+ }
+ ListModel {
+ id: sliderBoxElements
+ ListElement { labelText: "Red value"; colorChannel: 0 }
+ ListElement { labelText: "Green value"; colorChannel: 1 }
+ ListElement { labelText: "Blue value"; colorChannel: 2 }
+ ListElement { labelText: "Alpha value"; colorChannel: 3 }
+ }
+ ColumnLayout {
+ id: sliderBox
+ Layout.columnSpan: 3
+ Layout.rowSpan: 2
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Repeater {
+ model: sliderBoxElements
+ delegate: ColumnLayout {
+ Label {
+ text: labelText
+ }
+ Slider {
+ id: colorSlider
+ property int channel: colorChannel
+ from: 0
+ to: 255
+ stepSize: 1
+ value: {
+ if (colorSlider.channel == 0)
+ return colorDialog.color.r * 255;
+ else if (colorSlider.channel == 1)
+ return colorDialog.color.g * 255;
+ else if (colorSlider.channel == 2)
+ return colorDialog.color.b * 255;
+ else if (colorSlider.channel == 3)
+ return colorDialog.color.a * 255;
+ }
+
+ Connections {
+ function onMoved() {
+ var redChannelValue = colorDialog.color.r;
+ var greenChannelValue = colorDialog.color.g;
+ var blueChannelValue = colorDialog.color.b;
+ var alphaChannelValue = colorDialog.color.a;
+
+ if (colorSlider.channel == 0)
+ redChannelValue = colorSlider.value / 255;
+ else if (colorSlider.channel == 1)
+ greenChannelValue = colorSlider.value / 255;
+ else if (colorSlider.channel == 2)
+ blueChannelValue = colorSlider.value / 255;
+ else if (colorSlider.channel == 3)
+ alphaChannelValue = colorSlider.value / 255;
+
+ colorDialog.color = Qt.rgba(redChannelValue, greenChannelValue, blueChannelValue, alphaChannelValue);
+ }
+ }
+ }
+ }
+ }
+ }
+ DialogButtonBox {
+ id: dialogButtonBox
+ Layout.columnSpan: 7
+ Layout.alignment: Qt.AlignRight
+
+ Button {
+ text: qsTr("Apply")
+ onClicked: accept()
+ }
+ Button {
+ text: qsTr("Cancel")
+ onClicked: reject()
+ }
+ }
+ }
+}
diff --git a/src/webenginequick/ui_delegates_manager.cpp b/src/webenginequick/ui_delegates_manager.cpp
index 849dd3e6d..3d6eff649 100644
--- a/src/webenginequick/ui_delegates_manager.cpp
+++ b/src/webenginequick/ui_delegates_manager.cpp
@@ -1,54 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "ui_delegates_manager.h"
#include "api/qquickwebengineaction_p.h"
-#include "api/qquickwebengineview_p.h"
+#include "api/qquickwebengineview_p_p.h"
#include <authentication_dialog_controller.h>
+#include <autofill_popup_controller.h>
#include <color_chooser_controller.h>
#include <file_picker_controller.h>
#include <javascript_dialog_controller.h>
#include <touch_selection_menu_controller.h>
#include <web_contents_adapter_client.h>
+#include <QtCore/qdiriterator.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qlist.h>
#include <QtCore/qtimer.h>
@@ -58,6 +24,9 @@
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlproperty.h>
+#include <QtQuick/qquickwindow.h>
+
+#include <algorithm>
// Uncomment for QML debugging
//#define UI_DELEGATES_DEBUG
@@ -65,15 +34,9 @@
namespace QtWebEngineCore {
#define NO_SEPARATOR
-#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
-#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
- case UIDelegatesManager::TYPE:\
- return QString::fromLatin1(#TYPE ##".qml");
-#else
#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \
case UIDelegatesManager::TYPE:\
return QStringLiteral(#TYPE".qml");
-#endif
static QString fileNameForComponent(UIDelegatesManager::ComponentType type)
{
@@ -125,11 +88,14 @@ const char *defaultPropertyName(QObject *obj)
#define COMPONENT_MEMBER_INIT(TYPE, COMPONENT) \
, COMPONENT##Component(0)
+// clang-format off
UIDelegatesManager::UIDelegatesManager(QQuickWebEngineView *view)
: m_view(view)
, m_toolTip(nullptr)
, m_touchSelectionMenu(nullptr)
+ , m_autofillPopup(nullptr)
FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_INIT, NO_SEPARATOR)
+// clang-format on
{
}
@@ -165,7 +131,7 @@ bool UIDelegatesManager::ensureComponentLoaded(ComponentType type)
if (!engine)
return false;
- for (const QString &importDir : qAsConst(m_importDirs)) {
+ for (const QString &importDir : std::as_const(m_importDirs)) {
const QString componentFilePath = importDir % QLatin1Char('/') % fileName;
if (!QFileInfo(componentFilePath).exists())
@@ -203,7 +169,7 @@ void UIDelegatesManager::addMenuSeparator(QObject *menu)
QObject *sep = menuSeparatorComponent->create(itemContext);
sep->setParent(menu);
- QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view));
+ QQmlListReference entries(menu, defaultPropertyName(menu));
if (entries.isValid() && entries.count() > 0)
entries.append(sep);
}
@@ -385,6 +351,10 @@ void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogControlle
void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> controller)
{
+ if (controller->mode() == FilePickerController::UploadFolder) {
+ showDirectoryPicker(controller);
+ return;
+ }
if (!ensureComponentLoaded(FilePicker))
return;
@@ -396,19 +366,21 @@ void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> con
filePicker->setParent(m_view);
filePickerComponent->completeCreate();
+ static int fileModeIndex = filePicker->metaObject()->indexOfEnumerator("FileMode");
+ QMetaEnum fileModeEnum = filePicker->metaObject()->enumerator(fileModeIndex);
+
// Fine-tune some properties depending on the mode.
switch (controller->mode()) {
case FilePickerController::Open:
+ filePicker->setProperty("fileMode", fileModeEnum.keyToValue("OpenFile"));
break;
case FilePickerController::Save:
- filePicker->setProperty("selectExisting", false);
+ filePicker->setProperty("fileMode", fileModeEnum.keyToValue("SaveFile"));
break;
case FilePickerController::OpenMultiple:
- filePicker->setProperty("selectMultiple", true);
+ filePicker->setProperty("fileMode", fileModeEnum.keyToValue("OpenFiles"));
break;
case FilePickerController::UploadFolder:
- filePicker->setProperty("selectFolder", true);
- break;
default:
Q_UNREACHABLE();
}
@@ -432,6 +404,35 @@ void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> con
QMetaObject::invokeMethod(filePicker, "open");
}
+void UIDelegatesManager::showDirectoryPicker(QSharedPointer<FilePickerController> controller)
+{
+ if (!ensureComponentLoaded(DirectoryPicker))
+ return;
+
+ QQmlContext *context = qmlContext(m_view);
+ QObject *directoryPicker = directoryPickerComponent->beginCreate(context);
+ if (QQuickItem *item = qobject_cast<QQuickItem*>(directoryPicker))
+ item->setParentItem(m_view);
+ directoryPicker->setParent(m_view);
+ directoryPickerComponent->completeCreate();
+
+ QQmlProperty directoryPickedSignal(directoryPicker, QStringLiteral("onFolderSelected"));
+ CHECK_QML_SIGNAL_PROPERTY(directoryPickedSignal, directoryPickerComponent->url());
+ QQmlProperty rejectSignal(directoryPicker, QStringLiteral("onRejected"));
+ CHECK_QML_SIGNAL_PROPERTY(rejectSignal, directoryPickerComponent->url());
+ static int acceptedIndex = controller->metaObject()->indexOfSlot("accepted(QVariant)");
+ QObject::connect(directoryPicker, directoryPickedSignal.method(), controller.data(), controller->metaObject()->method(acceptedIndex));
+ static int rejectedIndex = controller->metaObject()->indexOfSlot("rejected()");
+ QObject::connect(directoryPicker, rejectSignal.method(), controller.data(), controller->metaObject()->method(rejectedIndex));
+
+ // delete when done.
+ static int deleteLaterIndex = directoryPicker->metaObject()->indexOfSlot("deleteLater()");
+ QObject::connect(directoryPicker, directoryPickedSignal.method(), directoryPicker, directoryPicker->metaObject()->method(deleteLaterIndex));
+ QObject::connect(directoryPicker, rejectSignal.method(), directoryPicker, directoryPicker->metaObject()->method(deleteLaterIndex));
+
+ QMetaObject::invokeMethod(directoryPicker, "open");
+}
+
class TemporaryCursorMove
{
public:
@@ -567,6 +568,158 @@ void UIDelegatesManager::hideTouchSelectionMenu()
QTimer::singleShot(0, m_view, [this] { m_touchSelectionMenu.reset(); });
}
+bool AutofillPopupEventFilter::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::ShortcutOverride) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ if (keyEvent->key() == Qt::Key_Escape) {
+ m_manager->hideAutofillPopup();
+ return true;
+ }
+
+ // Ignore shortcuts while the popup is open. It may result unwanted
+ // edit commands sent to Chromium that blocks the key press.
+ event->ignore();
+ return true;
+ }
+
+ // AutofillPopupControllerImpl::HandleKeyPressEvent()
+ // chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ switch (keyEvent->key()) {
+ case Qt::Key_Up:
+ m_controller->selectPreviousSuggestion();
+ return true;
+ case Qt::Key_Down:
+ m_controller->selectNextSuggestion();
+ return true;
+ case Qt::Key_PageUp:
+ m_controller->selectFirstSuggestion();
+ return true;
+ case Qt::Key_PageDown:
+ m_controller->selectLastSuggestion();
+ return true;
+ case Qt::Key_Escape:
+ m_manager->hideAutofillPopup();
+ return true;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ m_controller->acceptSuggestion();
+ return true;
+ case Qt::Key_Delete:
+ // Remove suggestion is not supported for datalist.
+ // Forward delete to view to be able to remove selected text.
+ break;
+ case Qt::Key_Tab:
+ m_controller->acceptSuggestion();
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Do not forward release events of the overridden key presses.
+ if (event->type() == QEvent::KeyRelease) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ switch (keyEvent->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Escape:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ return QObject::eventFilter(object, event);
+}
+
+void UIDelegatesManager::showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ QPointF pos, int width, bool autoselectFirstSuggestion)
+{
+ static const int padding = 1;
+ static const int itemHeight = 20;
+ const int proposedHeight = itemHeight * (controller->model()->rowCount()) + padding * 2;
+
+ bool popupWasNull = false;
+ if (m_autofillPopup.isNull()) {
+ popupWasNull = true;
+ if (!ensureComponentLoaded(AutofillPopup))
+ return;
+
+ QQmlContext *context = qmlContext(m_view);
+ m_autofillPopup.reset(autofillPopupComponent->beginCreate(context));
+ if (QQuickItem *item = qobject_cast<QQuickItem *>(m_autofillPopup.data()))
+ item->setParentItem(m_view);
+ m_autofillPopup->setParent(m_view);
+ }
+
+ m_autofillPopup->setProperty("controller", QVariant::fromValue(controller));
+ m_autofillPopup->setProperty("x", pos.x());
+ m_autofillPopup->setProperty("y", pos.y());
+ m_autofillPopup->setProperty("width", width);
+ m_autofillPopup->setProperty("height",
+ std::min(proposedHeight, qRound(m_view->height() - pos.y())));
+ m_autofillPopup->setProperty("padding", padding);
+ m_autofillPopup->setProperty("itemHeight", itemHeight);
+
+ if (popupWasNull) {
+ QQmlProperty selectedSignal(m_autofillPopup.data(), QStringLiteral("onSelected"));
+ CHECK_QML_SIGNAL_PROPERTY(selectedSignal, autofillPopupComponent->url());
+ static int selectSuggestionIndex =
+ controller->metaObject()->indexOfSlot("selectSuggestion(int)");
+ QObject::connect(m_autofillPopup.data(), selectedSignal.method(), controller,
+ controller->metaObject()->method(selectSuggestionIndex));
+
+ QQmlProperty acceptedSignal(m_autofillPopup.data(), QStringLiteral("onAccepted"));
+ CHECK_QML_SIGNAL_PROPERTY(acceptedSignal, autofillPopupComponent->url());
+ static int acceptSuggestionIndex =
+ controller->metaObject()->indexOfSlot("acceptSuggestion()");
+ QObject::connect(m_autofillPopup.data(), acceptedSignal.method(), controller,
+ controller->metaObject()->method(acceptSuggestionIndex));
+
+ QObject::connect(controller, &QtWebEngineCore::AutofillPopupController::currentIndexChanged,
+ [this](const QModelIndex &index) {
+ QMetaObject::invokeMethod(m_autofillPopup.data(), "setCurrentIndex",
+ Qt::DirectConnection,
+ Q_ARG(QVariant, index.row()));
+ });
+
+ autofillPopupComponent->completeCreate();
+
+ m_view->window()->installEventFilter(
+ new AutofillPopupEventFilter(controller, this, m_autofillPopup.data()));
+
+ QMetaObject::invokeMethod(m_autofillPopup.data(), "open");
+ controller->notifyPopupShown();
+ }
+
+ if (autoselectFirstSuggestion)
+ controller->selectFirstSuggestion();
+}
+
+void UIDelegatesManager::hideAutofillPopup()
+{
+ if (!m_autofillPopup)
+ return;
+
+ QTimer::singleShot(0, m_view, [this] {
+ if (m_autofillPopup) {
+ QtWebEngineCore::AutofillPopupController *controller =
+ m_autofillPopup->property("controller")
+ .value<QtWebEngineCore::AutofillPopupController *>();
+ m_autofillPopup.reset();
+ controller->notifyPopupHidden();
+ }
+ });
+}
+
bool UIDelegatesManager::initializeImportDirs(QStringList &dirs, QQmlEngine *engine)
{
const QStringList paths = engine->importPathList();
@@ -579,8 +732,14 @@ bool UIDelegatesManager::initializeImportDirs(QStringList &dirs, QQmlEngine *eng
}
QFileInfo fi(controlsImportPath);
- if (fi.exists())
+ if (fi.exists()) {
dirs << fi.absolutePath();
+
+ // add subdirectories
+ QDirIterator it(controlsImportPath, QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while (it.hasNext())
+ dirs << QFileInfo(it.next()).absoluteFilePath();
+ }
}
return !dirs.isEmpty();
}
@@ -634,7 +793,7 @@ void UIDelegatesManager::addMenuItem(QQuickWebEngineAction *action, QObject *men
it->setParent(menu);
- QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view));
+ QQmlListReference entries(menu, defaultPropertyName(menu));
if (entries.isValid())
entries.append(it);
}
diff --git a/src/webenginequick/ui_delegates_manager.h b/src/webenginequick/ui_delegates_manager.h
index 0f515d4be..24dde656c 100644
--- a/src/webenginequick/ui_delegates_manager.h
+++ b/src/webenginequick/ui_delegates_manager.h
@@ -1,52 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef UI_DELEGATES_MANAGER_H
#define UI_DELEGATES_MANAGER_H
-#include <QtCore/qcoreapplication.h>
+#include <QtCore/qcoreapplication.h> // Q_DECLARE_TR_FUNCTIONS
+#include <QtCore/qobject.h>
#include <QtCore/qpoint.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
+// clang-format off
#define FOR_EACH_COMPONENT_TYPE(F, SEPARATOR) \
F(Menu, menu) SEPARATOR \
F(MenuItem, menuItem) SEPARATOR \
@@ -56,10 +22,12 @@
F(ConfirmDialog, confirmDialog) SEPARATOR \
F(PromptDialog, promptDialog) SEPARATOR \
F(FilePicker, filePicker) SEPARATOR \
+ F(DirectoryPicker, directoryPicker) SEPARATOR \
F(AuthenticationDialog, authenticationDialog) SEPARATOR \
F(ToolTip, toolTip) SEPARATOR \
F(TouchHandle, touchHandle) SEPARATOR \
F(TouchSelectionMenu, touchSelectionMenu) SEPARATOR \
+ F(AutofillPopup, autofillPopup) SEPARATOR
#define COMMA_SEPARATOR ,
#define SEMICOLON_SEPARATOR ;
@@ -67,8 +35,10 @@
TYPE
#define MEMBER_DECLARATION(TYPE, COMPONENT) \
QQmlComponent *COMPONENT##Component
+// clang-format on
QT_BEGIN_NAMESPACE
+class QEvent;
class QQmlComponent;
class QQmlContext;
class QQmlEngine;
@@ -79,6 +49,7 @@ QT_END_NAMESPACE
namespace QtWebEngineCore {
class AuthenticationDialogController;
+class AutofillPopupController;
class ColorChooserController;
class FilePickerController;
class JavaScriptDialogController;
@@ -110,19 +81,24 @@ public:
void showDialog(QSharedPointer<JavaScriptDialogController>);
void showDialog(QSharedPointer<AuthenticationDialogController>);
void showFilePicker(QSharedPointer<FilePickerController>);
+ void showDirectoryPicker(QSharedPointer<FilePickerController>);
virtual void showMenu(QObject *menu);
void showToolTip(const QString &text);
QQuickItem *createTouchHandle();
void showTouchSelectionMenu(TouchSelectionMenuController *, const QRect &, const int spacing);
void hideTouchSelectionMenu();
+ void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller, QPointF pos,
+ int width, bool autoselectFirstSuggestion);
+ void hideAutofillPopup();
private:
bool ensureComponentLoaded(ComponentType);
QQuickWebEngineView *m_view;
- QScopedPointer<QObject> m_toolTip;
QStringList m_importDirs;
+ QScopedPointer<QObject> m_toolTip;
QScopedPointer<QObject> m_touchSelectionMenu;
+ QScopedPointer<QObject> m_autofillPopup;
FOR_EACH_COMPONENT_TYPE(MEMBER_DECLARATION, SEMICOLON_SEPARATOR)
@@ -130,6 +106,25 @@ private:
};
+class AutofillPopupEventFilter : public QObject
+{
+ Q_OBJECT
+
+public:
+ AutofillPopupEventFilter(QtWebEngineCore::AutofillPopupController *controller,
+ UIDelegatesManager *manager, QObject *parent)
+ : QObject(parent), m_controller(controller), m_manager(manager)
+ {
+ }
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event) override;
+
+private:
+ QtWebEngineCore::AutofillPopupController *m_controller;
+ UIDelegatesManager *m_manager;
+};
+
} // namespace QtWebEngineCore
#endif // UI_DELEGATES_MANAGER_H
diff --git a/src/webenginewidgets/CMakeLists.txt b/src/webenginewidgets/CMakeLists.txt
index 6a25e7297..dd11e48be 100644
--- a/src/webenginewidgets/CMakeLists.txt
+++ b/src/webenginewidgets/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if(TARGET Qt::Designer)
add_subdirectory(plugins/qwebengineview)
else()
@@ -8,12 +11,15 @@ qt_internal_add_module(WebEngineWidgets
api/qtwebenginewidgetsglobal.h
api/qwebenginenotificationpresenter.cpp api/qwebenginenotificationpresenter_p.h
api/qwebengineview.cpp api/qwebengineview.h api/qwebengineview_p.h
- render_widget_host_view_qt_delegate_widget.cpp render_widget_host_view_qt_delegate_widget.h
+ ui/autofillpopupwidget.cpp ui/autofillpopupwidget_p.h
+ ui/touchhandlewidget.cpp ui/touchhandlewidget_p.h
+ ui/touchselectionmenuwidget.cpp ui/touchselectionmenuwidget_p.h
DEFINES
QT_BUILD_WEBENGINEWIDGETS_LIB
INCLUDE_DIRECTORIES
../core
api
+ ui
LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
@@ -26,6 +32,12 @@ qt_internal_add_module(WebEngineWidgets
Qt::Gui
Qt::Widgets
Qt::WebEngineCore
+ NO_GENERATE_CPP_EXPORTS
+)
+
+qt_internal_extend_target(WebEngineWidgets CONDITION QT_FEATURE_accessibility
+ SOURCES
+ qwebengine_accessible.cpp qwebengine_accessible.h
)
qt_internal_extend_target(WebEngineWidgets CONDITION QT_FEATURE_webengine_printing_and_pdf
diff --git a/src/webenginewidgets/api/qtwebenginewidgetsglobal.h b/src/webenginewidgets/api/qtwebenginewidgetsglobal.h
index 128704578..58b9c7a2b 100644
--- a/src/webenginewidgets/api/qtwebenginewidgetsglobal.h
+++ b/src/webenginewidgets/api/qtwebenginewidgetsglobal.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTWEBENGINEWIDGETSGLOBAL_H
#define QTWEBENGINEWIDGETSGLOBAL_H
diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
index 667605c37..83814fe4a 100644
--- a/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebenginenotificationpresenter_p.h"
@@ -46,7 +10,7 @@ QT_BEGIN_NAMESPACE
DefaultNotificationPresenter::DefaultNotificationPresenter(QObject *parent) : QObject(parent)
{
-#ifndef QT_NO_SYSTEMTRAYICON
+#if QT_CONFIG(systemtrayicon)
m_systemTrayIcon = new QSystemTrayIcon(this);
connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked, this, &DefaultNotificationPresenter::messageClicked);
#endif
@@ -66,7 +30,7 @@ void DefaultNotificationPresenter::show(std::unique_ptr<QWebEngineNotification>
m_activeNotification = std::move(notification);
-#ifndef QT_NO_SYSTEMTRAYICON
+#if QT_CONFIG(systemtrayicon)
if (m_activeNotification && m_systemTrayIcon) {
m_systemTrayIcon->setIcon(qApp->windowIcon());
m_systemTrayIcon->show();
@@ -90,7 +54,7 @@ void DefaultNotificationPresenter::messageClicked()
void DefaultNotificationPresenter::closeNotification()
{
-#ifndef QT_NO_SYSTEMTRAYICON
+#if QT_CONFIG(systemtrayicon)
const QWebEngineNotification *canceled = static_cast<const QWebEngineNotification *>(QObject::sender());
if (m_systemTrayIcon && canceled->matches(m_activeNotification.get()))
m_systemTrayIcon->hide();
@@ -107,3 +71,5 @@ void defaultNotificationPresenter(std::unique_ptr<QWebEngineNotification> notifi
QT_END_NAMESPACE
+
+#include "moc_qwebenginenotificationpresenter_p.cpp"
diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
index 33b6a6782..61e7f9e45 100644
--- a/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINENOTIFICATIONPRESENTER_P_H
#define QWEBENGINENOTIFICATIONPRESENTER_P_H
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index a282df3e3..e28f70b5f 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -1,53 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qapplication.h"
#include "qwebenginenotificationpresenter_p.h"
#include "qwebengineview.h"
#include "qwebengineview_p.h"
-#include "render_widget_host_view_qt_delegate_widget.h"
+#include "render_widget_host_view_qt_delegate_client.h"
+#include "render_widget_host_view_qt_delegate_item.h"
+#include "ui/autofillpopupwidget_p.h"
+#include "touchhandlewidget_p.h"
+#include "touchselectionmenuwidget_p.h"
#include <QtWebEngineCore/private/qwebenginepage_p.h>
#include <QtWebEngineCore/qwebenginecontextmenurequest.h>
#include <QtWebEngineCore/qwebenginehistory.h>
#include <QtWebEngineCore/qwebenginehttprequest.h>
#include <QtWebEngineCore/qwebengineprofile.h>
+
+#include "autofill_popup_controller.h"
#include "color_chooser_controller.h"
+#include "touch_selection_menu_controller.h"
#include "web_contents_adapter.h"
#include <QContextMenuEvent>
@@ -57,6 +29,11 @@
#include <QIcon>
#include <QStyle>
#include <QGuiApplication>
+#include <QQuickWidget>
+
+#if QT_CONFIG(accessibility)
+#include "qwebengine_accessible.h"
+#endif
#if QT_CONFIG(action)
#include <QAction>
@@ -87,11 +64,311 @@
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/printer_worker.h"
+#include <QPrintEngine>
#include <QPrinter>
#include <QThread>
#endif
QT_BEGIN_NAMESPACE
+class QSpontaneKeyEvent
+{
+public:
+ static inline void makeSpontaneous(QEvent *ev) { ev->setSpontaneous(); }
+};
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+class WebEngineQuickWidget : public QQuickWidget, public WidgetDelegate
+{
+public:
+ WebEngineQuickWidget(RenderWidgetHostViewQtDelegateItem *widget, QWidget *parent)
+ : QQuickWidget(parent)
+ , m_contentItem(widget)
+ {
+ setFocusPolicy(Qt::StrongFocus);
+ setMouseTracking(true);
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ setAttribute(Qt::WA_AlwaysShowToolTips);
+
+ QQuickItem *root = new QQuickItem(); // Indirection so we don't delete m_contentItem
+ setContent(QUrl(), nullptr, root);
+ root->setFlags(QQuickItem::ItemHasContents);
+ root->setVisible(true);
+ m_contentItem->setParentItem(root);
+
+ connectRemoveParentBeforeParentDelete();
+ }
+ ~WebEngineQuickWidget() override
+ {
+ if (m_contentItem) {
+ m_contentItem->setWidgetDelegate(nullptr);
+ m_contentItem->setParentItem(nullptr);
+ }
+ }
+
+ void InitAsPopup(const QRect &screenRect) override
+ {
+ setAttribute(Qt::WA_ShowWithoutActivating);
+ setFocusPolicy(Qt::NoFocus);
+ setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+
+ setGeometry(screenRect);
+ raise();
+ m_contentItem->show();
+ show();
+ }
+
+ void Bind(WebContentsAdapterClient *client) override
+ {
+ QWebEnginePagePrivate *page = static_cast<QWebEnginePagePrivate *>(client);
+ if (m_pageDestroyedConnection)
+ QObject::disconnect(m_pageDestroyedConnection);
+ QWebEngineViewPrivate::bindPageAndWidget(page, this);
+ m_pageDestroyedConnection = QObject::connect(page->q_ptr, &QObject::destroyed, this, &WebEngineQuickWidget::Unbind);
+ }
+
+ void Unbind() override
+ {
+ if (m_pageDestroyedConnection) {
+ QObject::disconnect(m_pageDestroyedConnection);
+ m_pageDestroyedConnection = {};
+ }
+ QWebEngineViewPrivate::bindPageAndWidget(nullptr, this);
+ }
+
+ void Destroy() override
+ {
+ deleteLater();
+ }
+
+ bool ActiveFocusOnPress() override
+ {
+ return true;
+ }
+
+ void SetInputMethodEnabled(bool enabled) override
+ {
+ QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, enabled);
+ }
+ void SetInputMethodHints(Qt::InputMethodHints hints) override
+ {
+ QQuickWidget::setInputMethodHints(hints);
+ }
+ void SetClearColor(const QColor &color) override
+ {
+ setUpdatesEnabled(false);
+ QQuickWidget::setClearColor(color);
+ // QQuickWidget 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);
+ setUpdatesEnabled(true);
+ window()->update();
+ }
+ void MoveWindow(const QPoint &screenPos) override
+ {
+ QQuickWidget::move(screenPos);
+ }
+ void Resize(int width, int height) override
+ {
+ QQuickWidget::resize(width, height);
+ }
+ QWindow *Window() override
+ {
+ if (const QWidget *root = QQuickWidget::window())
+ return root->windowHandle();
+ return nullptr;
+ }
+ void unhandledWheelEvent(QWheelEvent *ev) override
+ {
+ auto parentWidget = QQuickWidget::parentWidget();
+ if (parentWidget) {
+ QSpontaneKeyEvent::makeSpontaneous(ev);
+ qApp->notify(parentWidget, ev);
+ }
+ }
+
+protected:
+ void closeEvent(QCloseEvent *event) override
+ {
+ QQuickWidget::closeEvent(event);
+
+ // If a close event was received from the window manager (e.g. when moving the parent window,
+ // clicking outside the popup area)
+ // make sure to notify the Chromium WebUI popup and its underlying
+ // RenderWidgetHostViewQtDelegate instance to be closed.
+ if (m_contentItem && m_contentItem->m_isPopup)
+ m_contentItem->m_client->closePopup();
+ }
+ void showEvent(QShowEvent *event) override
+ {
+ QQuickWidget::showEvent(event);
+ // We don't have a way to catch a top-level window change with QWidget
+ // but a widget will most likely be shown again if it changes, so do
+ // the reconnection at this point.
+ for (const QMetaObject::Connection &c : std::as_const(m_windowConnections))
+ disconnect(c);
+ m_windowConnections.clear();
+ if (QWindow *w = Window()) {
+ m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), m_contentItem, SLOT(onWindowPosChanged())));
+ m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), m_contentItem, SLOT(onWindowPosChanged())));
+ }
+ }
+ void resizeEvent(QResizeEvent *event) override
+ {
+ QQuickWidget::resizeEvent(event);
+ if (m_contentItem) { // FIXME: Not sure why we need to set m_contentItem size manually
+ m_contentItem->setSize(event->size());
+ m_contentItem->onWindowPosChanged();
+ }
+ }
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
+ {
+ if (m_contentItem)
+ return m_contentItem->inputMethodQuery(query);
+ return QVariant();
+ }
+ bool event(QEvent *event) override;
+
+ void connectRemoveParentBeforeParentDelete();
+ void removeParentBeforeParentDelete();
+
+private:
+ friend QWebEngineViewPrivate;
+ QPointer<RenderWidgetHostViewQtDelegateItem> m_contentItem; // deleted by core
+ QMetaObject::Connection m_parentDestroyedConnection;
+ QMetaObject::Connection m_pageDestroyedConnection;
+ QList<QMetaObject::Connection> m_windowConnections;
+};
+
+void WebEngineQuickWidget::connectRemoveParentBeforeParentDelete()
+{
+ disconnect(m_parentDestroyedConnection);
+
+ if (QWidget *parent = parentWidget()) {
+ m_parentDestroyedConnection = connect(parent, &QObject::destroyed,
+ this,
+ &WebEngineQuickWidget::removeParentBeforeParentDelete);
+ } else {
+ m_parentDestroyedConnection = QMetaObject::Connection();
+ }
+}
+
+void WebEngineQuickWidget::removeParentBeforeParentDelete()
+{
+ // Unset the parent, because parent is being destroyed, but the owner of this
+ // WebEngineQuickWidget is actually a RenderWidgetHostViewQt instance.
+ setParent(nullptr);
+
+ // If this widget represents a popup window, make sure to close it, so that if the popup was the
+ // last visible top level window, the application event loop can quit if it deems it necessarry.
+ if (m_contentItem && m_contentItem->m_isPopup)
+ close();
+}
+
+bool WebEngineQuickWidget::event(QEvent *event)
+{
+ bool handled = false;
+
+ // Track parent to make sure we don't get deleted.
+ if (event->type() == QEvent::ParentChange)
+ connectRemoveParentBeforeParentDelete();
+
+ if (!m_contentItem)
+ return QQuickWidget::event(event);
+
+ // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
+ // disabled.
+ if (!isEnabled()) {
+ switch (event->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ case QEvent::ContextMenu:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+#if QT_CONFIG(wheelevent)
+ case QEvent::Wheel:
+#endif
+ return false;
+ default:
+ break;
+ }
+ }
+
+ switch (event->type()) {
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ // We forward focus events later, once they have made it to the content item.
+ return QQuickWidget::event(event);
+ case QEvent::DragEnter:
+ case QEvent::DragLeave:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ // Let the parent handle these events.
+ return false;
+ default:
+ break;
+ }
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ // Don't forward mouse events synthesized by the system, which are caused by genuine touch
+ // events. Chromium would then process for e.g. a mouse click handler twice, once due to the
+ // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse
+ // transformation done by Chromium.
+ // Only allow them for popup type, since QWidgetWindow will ignore them for Qt::Popup flag,
+ // which is expected to get input through synthesized mouse events (either by system or Qt)
+ if (!m_contentItem->m_isPopup &&
+ static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem) {
+ Q_ASSERT(!windowFlags().testFlag(Qt::Popup));
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (event->type() == QEvent::MouseButtonDblClick) {
+ // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event.
+ // QtQuick is different by sending both the Press and DblClick events for the second press
+ // where we can simply ignore the DblClick event.
+ QMouseEvent *dblClick = static_cast<QMouseEvent *>(event);
+ QMouseEvent press(QEvent::MouseButtonPress, dblClick->position(), dblClick->scenePosition(),
+ dblClick->globalPosition(), dblClick->button(), dblClick->buttons(),
+ dblClick->modifiers(), dblClick->source());
+ press.setTimestamp(dblClick->timestamp());
+ handled = m_contentItem->m_client->forwardEvent(&press);
+ } else
+ handled = m_contentItem->m_client->forwardEvent(event);
+
+ if (!handled)
+ return QQuickWidget::event(event);
+ event->accept();
+ return true;
+}
+
+} // namespace QtWebEngineCore
+
+QT_BEGIN_NAMESPACE
void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage)
{
@@ -144,8 +421,8 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
Q_EMIT q->selectionChanged();
}
-void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget)
+void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::WebEngineQuickWidget *oldWidget,
+ QtWebEngineCore::WebEngineQuickWidget *newWidget)
{
Q_Q(QWebEngineView);
@@ -162,13 +439,13 @@ void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQ
if (newWidget) {
Q_ASSERT(!QtWebEngineCore::closingDown());
#if QT_CONFIG(accessibility)
- // An earlier QAccessible::queryAccessibleInterface() call may have already registered a default
- // QAccessibleInterface for newWidget: remove it first to avoid assert in QAccessibleCache::insert().
QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(QAccessible::queryAccessibleInterface(newWidget)));
QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateWidgetAccessible(newWidget, q));
#endif
q->layout()->addWidget(newWidget);
q->setFocusProxy(newWidget);
+ if (oldWidget && oldWidget == QApplication::focusWidget())
+ newWidget->setFocus();
newWidget->show();
}
}
@@ -188,7 +465,7 @@ void QWebEngineViewPrivate::contextMenuRequested(QWebEngineContextMenuRequest *r
Q_EMIT q_ptr->customContextMenuRequested(request->position());
return;
case Qt::ActionsContextMenu:
- if (q_ptr->actions().count()) {
+ if (q_ptr->actions().size()) {
QContextMenuEvent event(QContextMenuEvent::Mouse, request->position(),
q_ptr->mapToGlobal(request->position()));
QMenu::exec(q_ptr->actions(), event.globalPos(), 0, q_ptr);
@@ -267,6 +544,10 @@ void QWebEngineViewPrivate::showColorDialog(
QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), dialog, SLOT(deleteLater()));
QColorDialog::connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater()));
+#if defined(Q_OS_MACOS)
+ dialog->setOption(QColorDialog::DontUseNativeDialog);
+#endif
+
dialog->open();
#else
Q_UNUSED(controller);
@@ -277,8 +558,10 @@ bool QWebEngineViewPrivate::showAuthorizationDialog(const QString &title, const
{
#if QT_CONFIG(messagebox)
Q_Q(QWebEngineView);
- return QMessageBox::question(q, title, message, QMessageBox::Yes, QMessageBox::No)
- == QMessageBox::Yes;
+ QMessageBox msgBox(QMessageBox::Question, title, message, QMessageBox::Yes | QMessageBox::No,
+ q, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+ msgBox.setTextFormat(Qt::PlainText);
+ return msgBox.exec() == QMessageBox::Yes;
#else
return false;
#endif // QT_CONFIG(messagebox)
@@ -288,8 +571,12 @@ void QWebEngineViewPrivate::javaScriptAlert(const QUrl &url, const QString &msg)
{
#if QT_CONFIG(messagebox)
Q_Q(QWebEngineView);
- QMessageBox::information(q, QStringLiteral("Javascript Alert - %1").arg(url.toString()),
- msg.toHtmlEscaped());
+ QMessageBox msgBox(QMessageBox::Information,
+ QStringLiteral("Javascript Alert - %1").arg(url.toString()),
+ msg, QMessageBox::Ok, q,
+ Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+ msgBox.setTextFormat(Qt::PlainText);
+ msgBox.exec();
#else
Q_UNUSED(msg);
#endif // QT_CONFIG(messagebox)
@@ -299,10 +586,12 @@ bool QWebEngineViewPrivate::javaScriptConfirm(const QUrl &url, const QString &ms
{
#if QT_CONFIG(messagebox)
Q_Q(QWebEngineView);
- return (QMessageBox::information(q,
- QStringLiteral("Javascript Confirm - %1").arg(url.toString()),
- msg.toHtmlEscaped(), QMessageBox::Ok, QMessageBox::Cancel)
- == QMessageBox::Ok);
+ QMessageBox msgBox(QMessageBox::Information,
+ QStringLiteral("Javascript Confirm - %1").arg(url.toString()),
+ msg, QMessageBox::Ok | QMessageBox::Cancel, q,
+ Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+ msgBox.setTextFormat(Qt::PlainText);
+ return msgBox.exec() == QMessageBox::Ok;
#else
Q_UNUSED(msg);
return false;
@@ -315,10 +604,16 @@ bool QWebEngineViewPrivate::javaScriptPrompt(const QUrl &url, const QString &msg
#if QT_CONFIG(inputdialog)
Q_Q(QWebEngineView);
bool ret = false;
+
+ // Workaround: Do not interpret text as Qt::RichText
+ // QInputDialog uses Qt::AutoText that interprets the text string as
+ // Qt::RichText if Qt::mightBeRichText() returns true, otherwise as Qt::PlainText.
+ const QString message = Qt::mightBeRichText(msg) ? msg.toHtmlEscaped() : msg;
+
if (result)
*result = QInputDialog::getText(
q, QStringLiteral("Javascript Prompt - %1").arg(url.toString()),
- msg.toHtmlEscaped(), QLineEdit::Normal, defaultValue.toHtmlEscaped(), &ret);
+ message, QLineEdit::Normal, defaultValue, &ret);
return ret;
#else
Q_UNUSED(msg);
@@ -348,28 +643,29 @@ bool QWebEngineViewPrivate::passOnFocus(bool reverse)
return q->focusNextPrevChild(!reverse);
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object)
{
if (QWebEngineView *v = qobject_cast<QWebEngineView*>(object))
return new QWebEngineViewAccessible(v);
return nullptr;
}
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
QWebEngineViewPrivate::QWebEngineViewPrivate()
- : page(0)
+ : page(nullptr)
, m_dragEntered(false)
, m_ownsPage(false)
, m_contextRequest(nullptr)
{
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::installFactory(&webAccessibleFactory);
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
}
QWebEngineViewPrivate::~QWebEngineViewPrivate() = default;
+// static
void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view)
{
QWebEngineViewPrivate *v =
@@ -403,20 +699,28 @@ void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView
// Then notify.
- auto widget = page ? page->d_func()->widget : nullptr;
- auto oldWidget = (oldPage && oldPage->d_func()) ? oldPage->d_func()->widget : nullptr;
+ auto item = page ? page->d_func()->delegateItem : nullptr;
+ auto oldItem = (oldPage && oldPage->d_func()) ? oldPage->d_func()->delegateItem : nullptr;
+ auto widget = item ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(item->m_widgetDelegate) : nullptr;
+ auto oldWidget = oldItem ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(oldItem->m_widgetDelegate) : nullptr;
+ // New page/widget moving away from oldView
if (page && oldView != view && oldView) {
oldView->d_func()->pageChanged(page, nullptr);
if (widget)
oldView->d_func()->widgetChanged(widget, nullptr);
}
+ // New page/widget moving into new view
if (view && oldPage != page) {
if (oldPage && oldPage->d_func())
view->d_func()->pageChanged(oldPage, page);
else
view->d_func()->pageChanged(nullptr, page);
+ if (!widget && item) {
+ widget = new QtWebEngineCore::WebEngineQuickWidget(item, nullptr);
+ item->setWidgetDelegate(widget);
+ }
if (oldWidget != widget)
view->d_func()->widgetChanged(oldWidget, widget);
}
@@ -424,42 +728,47 @@ void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView
delete oldPage;
}
-void QWebEngineViewPrivate::bindPageAndWidget(
- QWebEnginePage *page, QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget)
+// static
+void QWebEngineViewPrivate::bindPageAndWidget(QWebEnginePagePrivate *pagePrivate,
+ QtWebEngineCore::WebEngineQuickWidget *widget)
{
- auto oldPage = widget ? widget->m_page : nullptr;
- auto oldWidget = page ? page->d_func()->widget : nullptr;
+ auto *oldAdapterClient = (widget && widget->m_contentItem) ? widget->m_contentItem->m_adapterClient : nullptr;
+ auto *oldPagePrivate = static_cast<QWebEnginePagePrivate *>(oldAdapterClient);
+ auto *oldItem = pagePrivate ? pagePrivate->delegateItem : nullptr;
+ auto *oldWidget = oldItem ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(oldItem->m_widgetDelegate) : nullptr;
// Change pointers first.
- if (widget && oldPage != page) {
- if (oldPage && oldPage->d_func())
- oldPage->d_func()->widget = nullptr;
- widget->m_page = page;
+ if (widget && oldPagePrivate != pagePrivate) {
+ if (oldPagePrivate)
+ oldPagePrivate->delegateItem = nullptr;
+ if (widget->m_contentItem)
+ widget->m_contentItem->m_adapterClient = pagePrivate;
}
- if (page && oldWidget != widget) {
- if (oldWidget)
- oldWidget->m_page = nullptr;
- page->d_func()->widget = widget;
+ if (pagePrivate && oldWidget != widget) {
+ if (oldWidget && oldWidget->m_contentItem)
+ oldWidget->m_contentItem->m_adapterClient = nullptr;
+ if (widget)
+ pagePrivate->delegateItem = widget->m_contentItem;
}
// Then notify.
- if (widget && oldPage != page && oldPage && oldPage->d_func()) {
- if (auto oldView = oldPage->d_func()->view)
+ if (oldPagePrivate && oldPagePrivate != pagePrivate) {
+ if (auto oldView = oldPagePrivate->view)
static_cast<QWebEngineViewPrivate *>(oldView)->widgetChanged(widget, nullptr);
}
- if (page && oldWidget != widget) {
- if (auto view = page->d_func()->view)
+ if (pagePrivate && oldWidget != widget) {
+ if (auto view = pagePrivate->view)
static_cast<QWebEngineViewPrivate *>(view)->widgetChanged(oldWidget, widget);
}
}
-QIcon QWebEngineViewPrivate::webActionIcon(QWebEnginePage::WebAction action)
+QIcon QWebEngineViewPrivate::webActionIcon(QWebEnginePage::WebAction action) const
{
- Q_Q(QWebEngineView);
+ Q_Q(const QWebEngineView);
QIcon icon;
QStyle *style = q->style();
@@ -540,7 +849,11 @@ void QWebEngineViewPrivate::didPrintPage(QPrinter *&currentPrinter, QSharedPoint
printerWorker->m_documentCopies = currentPrinter->copyCount();
printerWorker->m_collateCopies = currentPrinter->collateCopies();
- QObject::connect(printerWorker, &QtWebEngineCore::PrinterWorker::resultReady, q, [q, &currentPrinter](bool success) {
+ int oldCopyCount = currentPrinter->copyCount();
+ currentPrinter->printEngine()->setProperty(QPrintEngine::PPK_CopyCount, 1);
+
+ QObject::connect(printerWorker, &QtWebEngineCore::PrinterWorker::resultReady, q, [q, &currentPrinter, oldCopyCount](bool success) {
+ currentPrinter->printEngine()->setProperty(QPrintEngine::PPK_CopyCount, oldCopyCount);
currentPrinter = nullptr;
Q_EMIT q->printFinished(success);
});
@@ -585,14 +898,55 @@ QtWebEngineCore::RenderWidgetHostViewQtDelegate *
QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(
QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client)
{
+ auto *item = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, false);
+ auto *widget = new QtWebEngineCore::WebEngineQuickWidget(item, nullptr);
+ item->setWidgetDelegate(widget);
+ return item;
+}
+
+QtWebEngineCore::RenderWidgetHostViewQtDelegate *
+QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client)
+{
Q_Q(QWebEngineView);
- return new QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget(client, q);
+ auto *item = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, true);
+ auto *widget = new QtWebEngineCore::WebEngineQuickWidget(item, q);
+ item->setWidgetDelegate(widget);
+ return item;
}
QWebEngineContextMenuRequest *QWebEngineViewPrivate::lastContextMenuRequest() const
{
return m_contextRequest;
}
+
+void QWebEngineViewPrivate::showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ const QRect &bounds, bool autoselectFirstSuggestion)
+{
+ Q_Q(QWebEngineView);
+ if (!m_autofillPopupWidget)
+ m_autofillPopupWidget.reset(new QtWebEngineWidgetUI::AutofillPopupWidget(controller, q));
+ m_autofillPopupWidget->showPopup(q->mapToGlobal(bounds.bottomLeft()), bounds.width() + 2,
+ autoselectFirstSuggestion);
+ controller->notifyPopupShown();
+}
+
+void QWebEngineViewPrivate::hideAutofillPopup()
+{
+ if (!m_autofillPopupWidget)
+ return;
+
+ Q_Q(QWebEngineView);
+ QTimer::singleShot(0, q, [this] {
+ if (m_autofillPopupWidget) {
+ QtWebEngineCore::AutofillPopupController *controller =
+ m_autofillPopupWidget->m_controller;
+ m_autofillPopupWidget.reset();
+ controller->notifyPopupHidden();
+ }
+ });
+}
+
/*!
\fn QWebEngineView::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
\since 5.6
@@ -625,6 +979,40 @@ QWebEngineView::QWebEngineView(QWidget *parent)
setLayout(layout);
}
+/*!
+ \since 6.4
+
+ Constructs an empty web view using \a profile with the parent \a parent.
+
+ \note The \a profile object ownership is not taken and it should outlive the view.
+
+ \sa load()
+*/
+
+QWebEngineView::QWebEngineView(QWebEngineProfile *profile, QWidget *parent)
+ : QWebEngineView(parent)
+{
+ Q_D(QWebEngineView);
+ setPage(new QWebEnginePage(profile, this));
+ d->m_ownsPage = true;
+}
+
+/*!
+ \since 6.4
+
+ Constructs a web view containing \a page with the parent \a parent.
+
+ \note Ownership of \a page is not taken, and it is up to the caller to ensure it is deleted.
+
+ \sa load(), setPage()
+*/
+
+QWebEngineView::QWebEngineView(QWebEnginePage *page, QWidget *parent)
+ : QWebEngineView(parent)
+{
+ setPage(page);
+}
+
QWebEngineView::~QWebEngineView()
{
blockSignals(true);
@@ -663,7 +1051,10 @@ void QWebEngineView::setPage(QWebEnginePage *newPage)
disconnect(d->m_pageConnection);
d->m_pageConnection = {};
}
+
QWebEngineViewPrivate::bindPageAndView(newPage, this);
+ if (!newPage)
+ return;
d->m_pageConnection = connect(newPage, &QWebEnginePage::_q_aboutToDelete, this,
[newPage]() { QWebEngineViewPrivate::bindPageAndView(newPage, nullptr); });
auto profile = newPage->profile();
@@ -746,10 +1137,19 @@ QString QWebEngineView::selectedText() const
return page()->selectedText();
}
-#ifndef QT_NO_ACTION
+#if QT_CONFIG(action)
QAction* QWebEngineView::pageAction(QWebEnginePage::WebAction action) const
{
- return page()->action(action);
+ Q_D(const QWebEngineView);
+ QAction *pageAction = page()->action(action);
+
+ if (pageAction->icon().isNull()) {
+ auto icon = d->webActionIcon(action);
+ if (!icon.isNull())
+ pageAction->setIcon(icon);
+ }
+
+ return pageAction;
}
#endif
@@ -1023,7 +1423,8 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re
\fn void QWebEngineView::printRequested()
\since 6.2
- This signal is emitted when the JavaScript \c{window.print()} method is called.
+ This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print
+ button of PDF viewer plugin.
Typically, the signal handler can simply call print().
\sa print()
@@ -1052,6 +1453,9 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re
\note Printing runs on the browser process, which is by default not sandboxed.
+ \note The data generation step of printing can be interrupted for a short period of time using
+ the \l QWebEnginePage::Stop web action.
+
\note This function rasterizes the result when rendering onto \a printer. Please consider raising
the default resolution of \a printer to at least 300 DPI or using printToPdf() to produce
PDF file output more effectively.
@@ -1078,45 +1482,6 @@ void QWebEngineView::print(QPrinter *printer)
#endif
}
-#ifndef QT_NO_ACCESSIBILITY
-bool QWebEngineViewAccessible::isValid() const
-{
- if (!QAccessibleWidget::isValid())
- return false;
-
- if (!view() || !view()->d_func() || !view()->d_func()->page || !view()->d_func()->page->d_func())
- return false;
-
- return true;
-}
-
-QAccessibleInterface *QWebEngineViewAccessible::focusChild() const
-{
- if (child(0) && child(0)->focusChild())
- return child(0)->focusChild();
- return const_cast<QWebEngineViewAccessible *>(this);
-}
-
-int QWebEngineViewAccessible::childCount() const
-{
- return child(0) ? 1 : 0;
-}
-
-QAccessibleInterface *QWebEngineViewAccessible::child(int index) const
-{
- if (index == 0 && isValid())
- return view()->page()->d_func()->adapter->browserAccessible();
- return nullptr;
-}
-
-int QWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- if (child(0) && c == child(0))
- return 0;
- return -1;
-}
-#endif // QT_NO_ACCESSIBILITY
-
#if QT_CONFIG(action)
QContextMenuBuilder::QContextMenuBuilder(QWebEngineContextMenuRequest *request,
QWebEngineView *view, QMenu *menu)
@@ -1142,82 +1507,82 @@ void QContextMenuBuilder::addMenuItem(ContextMenuItem menuItem)
switch (menuItem) {
case ContextMenuItem::Back:
- action = thisRef->action(QWebEnginePage::Back);
+ action = m_view->pageAction(QWebEnginePage::Back);
break;
case ContextMenuItem::Forward:
- action = thisRef->action(QWebEnginePage::Forward);
+ action = m_view->pageAction(QWebEnginePage::Forward);
break;
case ContextMenuItem::Reload:
- action = thisRef->action(QWebEnginePage::Reload);
+ action = m_view->pageAction(QWebEnginePage::Reload);
break;
case ContextMenuItem::Cut:
- action = thisRef->action(QWebEnginePage::Cut);
+ action = m_view->pageAction(QWebEnginePage::Cut);
break;
case ContextMenuItem::Copy:
- action = thisRef->action(QWebEnginePage::Copy);
+ action = m_view->pageAction(QWebEnginePage::Copy);
break;
case ContextMenuItem::Paste:
- action = thisRef->action(QWebEnginePage::Paste);
+ action = m_view->pageAction(QWebEnginePage::Paste);
break;
case ContextMenuItem::Undo:
- action = thisRef->action(QWebEnginePage::Undo);
+ action = m_view->pageAction(QWebEnginePage::Undo);
break;
case ContextMenuItem::Redo:
- action = thisRef->action(QWebEnginePage::Redo);
+ action = m_view->pageAction(QWebEnginePage::Redo);
break;
case ContextMenuItem::SelectAll:
- action = thisRef->action(QWebEnginePage::SelectAll);
+ action = m_view->pageAction(QWebEnginePage::SelectAll);
break;
case ContextMenuItem::PasteAndMatchStyle:
- action = thisRef->action(QWebEnginePage::PasteAndMatchStyle);
+ action = m_view->pageAction(QWebEnginePage::PasteAndMatchStyle);
break;
case ContextMenuItem::OpenLinkInNewWindow:
- action = thisRef->action(QWebEnginePage::OpenLinkInNewWindow);
+ action = m_view->pageAction(QWebEnginePage::OpenLinkInNewWindow);
break;
case ContextMenuItem::OpenLinkInNewTab:
- action = thisRef->action(QWebEnginePage::OpenLinkInNewTab);
+ action = m_view->pageAction(QWebEnginePage::OpenLinkInNewTab);
break;
case ContextMenuItem::CopyLinkToClipboard:
- action = thisRef->action(QWebEnginePage::CopyLinkToClipboard);
+ action = m_view->pageAction(QWebEnginePage::CopyLinkToClipboard);
break;
case ContextMenuItem::DownloadLinkToDisk:
- action = thisRef->action(QWebEnginePage::DownloadLinkToDisk);
+ action = m_view->pageAction(QWebEnginePage::DownloadLinkToDisk);
break;
case ContextMenuItem::CopyImageToClipboard:
- action = thisRef->action(QWebEnginePage::CopyImageToClipboard);
+ action = m_view->pageAction(QWebEnginePage::CopyImageToClipboard);
break;
case ContextMenuItem::CopyImageUrlToClipboard:
- action = thisRef->action(QWebEnginePage::CopyImageUrlToClipboard);
+ action = m_view->pageAction(QWebEnginePage::CopyImageUrlToClipboard);
break;
case ContextMenuItem::DownloadImageToDisk:
- action = thisRef->action(QWebEnginePage::DownloadImageToDisk);
+ action = m_view->pageAction(QWebEnginePage::DownloadImageToDisk);
break;
case ContextMenuItem::CopyMediaUrlToClipboard:
- action = thisRef->action(QWebEnginePage::CopyMediaUrlToClipboard);
+ action = m_view->pageAction(QWebEnginePage::CopyMediaUrlToClipboard);
break;
case ContextMenuItem::ToggleMediaControls:
- action = thisRef->action(QWebEnginePage::ToggleMediaControls);
+ action = m_view->pageAction(QWebEnginePage::ToggleMediaControls);
break;
case ContextMenuItem::ToggleMediaLoop:
- action = thisRef->action(QWebEnginePage::ToggleMediaLoop);
+ action = m_view->pageAction(QWebEnginePage::ToggleMediaLoop);
break;
case ContextMenuItem::DownloadMediaToDisk:
- action = thisRef->action(QWebEnginePage::DownloadMediaToDisk);
+ action = m_view->pageAction(QWebEnginePage::DownloadMediaToDisk);
break;
case ContextMenuItem::InspectElement:
- action = thisRef->action(QWebEnginePage::InspectElement);
+ action = m_view->pageAction(QWebEnginePage::InspectElement);
break;
case ContextMenuItem::ExitFullScreen:
- action = thisRef->action(QWebEnginePage::ExitFullScreen);
+ action = m_view->pageAction(QWebEnginePage::ExitFullScreen);
break;
case ContextMenuItem::SavePage:
- action = thisRef->action(QWebEnginePage::SavePage);
+ action = m_view->pageAction(QWebEnginePage::SavePage);
break;
case ContextMenuItem::ViewSource:
- action = thisRef->action(QWebEnginePage::ViewSource);
+ action = m_view->pageAction(QWebEnginePage::ViewSource);
break;
case ContextMenuItem::SpellingSuggestions:
- for (int i = 0; i < m_contextData->spellCheckerSuggestions().count() && i < 4; i++) {
+ for (int i = 0; i < m_contextData->spellCheckerSuggestions().size() && i < 4; i++) {
action = new QAction(m_menu);
QString replacement = m_contextData->spellCheckerSuggestions().at(i);
QObject::connect(action, &QAction::triggered, [thisRef, replacement] {
@@ -1285,6 +1650,49 @@ bool QContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem)
}
#endif // QT_CONFIG(action)
+QtWebEngineCore::TouchHandleDrawableDelegate *
+QWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &images)
+{
+ Q_Q(QWebEngineView);
+ return new QtWebEngineWidgetUI::TouchHandleWidget(q, images);
+}
+
+void QWebEngineViewPrivate::hideTouchSelectionMenu()
+{
+ if (m_touchSelectionMenu)
+ m_touchSelectionMenu->close();
+}
+
+void QWebEngineViewPrivate::showTouchSelectionMenu(
+ QtWebEngineCore::TouchSelectionMenuController *controller, const QRect &selectionBounds)
+{
+ Q_ASSERT(m_touchSelectionMenu == nullptr);
+ Q_Q(QWebEngineView);
+
+ // Do not show outside of view
+ QSize parentSize = q->nativeParentWidget() ? q->nativeParentWidget()->size() : q->size();
+ if (selectionBounds.x() < 0 || selectionBounds.x() > parentSize.width()
+ || selectionBounds.y() < 0 || selectionBounds.y() > parentSize.height())
+ return;
+
+ m_touchSelectionMenu = new QtWebEngineWidgetUI::TouchSelectionMenuWidget(q, controller);
+
+ const int kSpacingBetweenButtons = 2;
+ const int kMenuButtonMinWidth = 80;
+ const int kMenuButtonMinHeight = 40;
+
+ int buttonCount = controller->buttonCount();
+ int width = (kSpacingBetweenButtons * (buttonCount + 1)) + (kMenuButtonMinWidth * buttonCount);
+ int height = kMenuButtonMinHeight + kSpacingBetweenButtons;
+ int x = (selectionBounds.x() + selectionBounds.x() + selectionBounds.width() - width) / 2;
+ int y = selectionBounds.y() - height - 2;
+
+ QPoint pos = q->mapToGlobal(QPoint(x, y));
+
+ m_touchSelectionMenu->setGeometry(pos.x(), pos.y(), width, height);
+ m_touchSelectionMenu->show();
+}
+
QT_END_NAMESPACE
#include "moc_qwebengineview.cpp"
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index b222de0df..f93d61b12 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEVIEW_H
#define QWEBENGINEVIEW_H
@@ -47,6 +11,10 @@
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
#include <QtWebEngineCore/qwebenginepage.h>
+namespace QtWebEngineWidgetUI {
+class AutofillPopupWidget;
+}
+
QT_BEGIN_NAMESPACE
class QContextMenuEvent;
@@ -72,6 +40,8 @@ class QWEBENGINEWIDGETS_EXPORT QWebEngineView : public QWidget
public:
explicit QWebEngineView(QWidget *parent = nullptr);
+ explicit QWebEngineView(QWebEngineProfile *profile, QWidget *parent = nullptr);
+ explicit QWebEngineView(QWebEnginePage *page, QWidget *parent = nullptr);
virtual ~QWebEngineView();
static QWebEngineView *forPage(const QWebEnginePage *page);
@@ -96,7 +66,7 @@ public:
bool hasSelection() const;
QString selectedText() const;
-#ifndef QT_NO_ACTION
+#if QT_CONFIG(action)
QAction *pageAction(QWebEnginePage::WebAction action) const;
#endif
void triggerPageAction(QWebEnginePage::WebAction action, bool checked = false);
@@ -167,8 +137,7 @@ private:
Q_DECLARE_PRIVATE(QWebEngineView)
QScopedPointer<QWebEngineViewPrivate> d_ptr;
- friend class QWebEnginePage;
- friend class QWebEnginePagePrivate;
+ friend class QtWebEngineWidgetUI::AutofillPopupWidget;
#if QT_CONFIG(accessibility)
friend class QWebEngineViewAccessible;
#endif
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index b5d38a6c1..aa330ac23 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEVIEW_P_H
#define QWEBENGINEVIEW_P_H
@@ -52,14 +16,24 @@
//
#include <QtWebEngineCore/private/qwebenginepage_p.h> // PageView
-#include <QtWidgets/qaccessiblewidget.h>
#include "render_view_context_menu_qt.h"
+#include <QtCore/qpointer.h>
+
namespace QtWebEngineCore {
+class AutofillPopupController;
class QWebEngineContextMenuRequest;
-class RenderWidgetHostViewQtDelegateWidget;
+class WebEngineQuickWidget;
class RenderWidgetHostViewQtDelegate;
+class RenderWidgetHostViewQtDelegateClient;
+class TouchSelectionMenuController;
+}
+
+namespace QtWebEngineWidgetUI {
+class AutofillPopupWidget;
+class TouchHandleDrawableDelegate;
+class TouchSelectionMenuWidget;
}
QT_BEGIN_NAMESPACE
@@ -75,8 +49,8 @@ public:
QWebEngineView *q_ptr;
void pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage);
- void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget);
+ void widgetChanged(QtWebEngineCore::WebEngineQuickWidget *oldWidget,
+ QtWebEngineCore::WebEngineQuickWidget *newWidget);
void contextMenuRequested(QWebEngineContextMenuRequest *request) override;
QStringList chooseFiles(QWebEnginePage::FileSelectionMode mode, const QStringList &oldFiles,
@@ -91,19 +65,29 @@ public:
void setToolTip(const QString &toolTipText) override;
QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate(
QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegateForPopup(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
QWebEngineContextMenuRequest *lastContextMenuRequest() const override;
QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) override;
QObject *accessibilityParentObject() override;
void didPrintPage(QPrinter *&printer, QSharedPointer<QByteArray> result) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
void printRequested() override;
-
+ void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller,
+ const QRect &bounds, bool autoselectFirstSuggestion) override;
+ void hideAutofillPopup() override;
+ QtWebEngineCore::TouchHandleDrawableDelegate *
+ createTouchHandleDelegate(const QMap<int, QImage> &images) override;
+
+ void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *,
+ const QRect &) override;
+ void hideTouchSelectionMenu() override;
QWebEngineViewPrivate();
virtual ~QWebEngineViewPrivate();
static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view);
- static void bindPageAndWidget(QWebEnginePage *page,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget);
- QIcon webActionIcon(QWebEnginePage::WebAction action);
+ static void bindPageAndWidget(QWebEnginePagePrivate *pagePrivate,
+ QtWebEngineCore::WebEngineQuickWidget *widget);
+ QIcon webActionIcon(QWebEnginePage::WebAction action) const;
void unhandledKeyEvent(QKeyEvent *event) override;
void focusContainer() override;
bool passOnFocus(bool reverse) override;
@@ -115,26 +99,10 @@ public:
bool m_dragEntered;
mutable bool m_ownsPage;
QWebEngineContextMenuRequest *m_contextRequest;
+ QScopedPointer<QtWebEngineWidgetUI::AutofillPopupWidget> m_autofillPopupWidget;
+ QPointer<QtWebEngineWidgetUI::TouchSelectionMenuWidget> m_touchSelectionMenu;
};
-#ifndef QT_NO_ACCESSIBILITY
-class QWebEngineViewAccessible : public QAccessibleWidget
-{
-public:
- QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o)
- {}
-
- bool isValid() const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface *child) const override;
-
-private:
- QWebEngineView *view() const { return static_cast<QWebEngineView *>(object()); }
-};
-#endif // QT_NO_ACCESSIBILITY
-
class QContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt
{
public:
diff --git a/src/webenginewidgets/doc/snippets/push-notifications/commands b/src/webenginewidgets/doc/snippets/push-notifications/commands
new file mode 100644
index 000000000..aee9761c1
--- /dev/null
+++ b/src/webenginewidgets/doc/snippets/push-notifications/commands
@@ -0,0 +1,19 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+npm init -y
+npm install web-push express
+//! [0]
+
+//! [1]
+"start": "node server.js"
+//! [1]
+
+//! [2]
+./node_odules/.bin/web-push generate-vapid-keys
+//! [2]
+
+//! [3]
+npm start
+//! [3]
diff --git a/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp b/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp
index 5d89cb8bc..64531cf3a 100644
--- a/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp
+++ b/src/webenginewidgets/doc/snippets/qtwebengine_qwebengineview_snippet.cpp
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
void wrapInFunction()
{
diff --git a/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc
index f48932eae..f11f550ff 100644
--- a/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc
+++ b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc
@@ -1,40 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [0]
QT += webenginewidgets
//! [0]
-
-//! [1]
-#include <QtWebEngineWidgets>
-//! [1]
-
//! [2]
-find_package(Qt6 COMPONENTS WebEngineWidgets REQUIRED)
-target_link_libraries(target PRIVATE Qt::WebEngineWidgets)
+find_package(Qt6 REQUIRED COMPONENTS WebEngineWidgets)
+target_link_libraries(target PRIVATE Qt6::WebEngineWidgets)
//! [2]
diff --git a/src/webenginewidgets/doc/snippets/simple/main.cpp b/src/webenginewidgets/doc/snippets/simple/main.cpp
index 39c07b84d..08613906b 100644
--- a/src/webenginewidgets/doc/snippets/simple/main.cpp
+++ b/src/webenginewidgets/doc/snippets/simple/main.cpp
@@ -1,65 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+//! [Minimal Example]
#include <QApplication>
-#include <QUrl>
#include <QWebEngineView>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- QWidget *parent = nullptr;
//! [Using QWebEngineView]
- QWebEngineView *view = new QWebEngineView(parent);
- view->load(QUrl("http://qt-project.org/"));
- view->show();
+ QWebEngineView view;
+ view.load(QUrl("https://qt-project.org/"));
+ view.resize(1024, 750);
+ view.show();
//! [Using QWebEngineView]
return app.exec();
}
+//! [Minimal Example]
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
index a9e0e69ea..c9bd76bf4 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\group webengine-widgetexamples
\title Qt WebEngine Widgets Examples
\brief Examples demonstrating the \QWE Widgets usage.
- \ingroup all-examples
Qt provides an integrated Web browser component based on Chromium, the popular
open source browser engine.
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
index cc1a33464..8eb28b797 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebenginewidgets-index.html
@@ -34,19 +10,14 @@
\section1 Getting Started
- 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 this line to your qmake project file:
- \snippet qtwebengine_build_snippet.qdoc 0
+ \snippet qtwebenginewidgets_build_snippet.qdoc 0
For build with CMake use the \c find_package() command to locate the needed module components
in the Qt6 package and \c target_link_libraries() to link against the module:
- \snippet qtwebengine_build_snippet.qdoc 2
+ \snippet qtwebenginewidgets_build_snippet.qdoc 2
\section1 Articles and Guides
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
index a2775d641..ef5a1c4b5 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\module QtWebEngineWidgets
@@ -34,14 +10,9 @@
\qtvariable webenginewidgets
\qtcmakepackage WebEngineWidgets
- The \QWEWidgets module provides a web browser engine as well as C++ classes to render
+ The \QWE Widgets 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 qtwebenginewidgets_build_snippet.qdoc 1
-
\if !defined(qtforpython)
To link against the module using build with qmake,
add the following QT variable to your qmake .pro file:
@@ -53,4 +24,9 @@
\snippet qtwebenginewidgets_build_snippet.qdoc 2
\endif
+
+ The minimum amount of code needed to load and display an HTML page requires just
+ implementing the \c QWebEngineView class.
+
+ \snippet simple/main.cpp Minimal Example
*/
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index 9e8cc463c..37b73c010 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtwebenginewidgets-qtwebkitportingguide.html
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 34aa53278..3153ec952 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -1,24 +1,8 @@
-/*
- Copyright (C) 2019 The Qt Company Ltd.
- Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- Copyright (C) 2008 Holger Hans Peter Freyther
- Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
-
- 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.
-*/
+// Copyright (C) 2019 The Qt Company Ltd.
+// Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+// Copyright (C) 2008 Holger Hans Peter Freyther
+// Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// The documentation in this file was imported from QtWebKit and is thus constrained
// by its LGPL license. Documentation written from scratch for new methods should be
@@ -77,7 +61,7 @@
new windows, such as pop-up windows, you can subclass QWebEngineView and
reimplement the createWindow() function.
- \sa {WebEngine Widgets Simple Browser Example}, {WebEngine Content Manipulation Example}, {WebEngine Markdown Editor Example}
+ \sa {WebEngine Widgets Simple Browser Example}, {WebEngine Content Manipulation Example}
*/
@@ -124,9 +108,8 @@
\fn void QWebEngineView::setHtml(const QString &html, const QUrl &baseUrl)
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. For external objects to
- be loaded, \c baseUrl cannot be empty. For example, if \a html
+ \a baseUrl is optional and used to resolve relative URLs in the document,
+ such as referenced images or stylesheets. 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,
should be at \c{http://www.example.com/documents/diagram.png}.
@@ -160,7 +143,7 @@
is empty, it is assumed that the content is \c{text/plain,charset=US-ASCII}.
External objects referenced in the content are located relative to \a baseUrl.
- For external objects to be loaded, \c baseUrl cannot be empty.
+ For external objects with relative URLs to be loaded, \c baseUrl cannot be empty.
The data is loaded immediately; external objects are loaded asynchronously.
@@ -226,6 +209,7 @@
/*!
\fn QAction *QWebEngineView::pageAction(QWebEnginePage::WebAction action) const
Returns a pointer to a QAction that encapsulates the specified web action \a action.
+ This function will also set a default styled icon to the QAction if it lacks one.
*/
/*!
diff --git a/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt b/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt
index 3e6f324da..0e7644bf7 100644
--- a/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt
+++ b/src/webenginewidgets/plugins/qwebengineview/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_plugin(QWebEngineViewPlugin
OUTPUT_NAME qwebengineview
PLUGIN_TYPE designer
diff --git a/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp b/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp
index dff041800..6ba64a178 100644
--- a/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp
+++ b/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwebengineview_plugin.h"
@@ -43,6 +7,7 @@
#include <QtDesigner/QExtensionManager>
#include <QtCore/qplugin.h>
+#include <QtQuick/QQuickWindow>
#include <QWebEngineView>
QT_BEGIN_NAMESPACE
diff --git a/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.h b/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.h
index 8c0960adc..a7150151d 100644
--- a/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.h
+++ b/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWEBENGINEVIEW_PLUGIN_H
#define QWEBENGINEVIEW_PLUGIN_H
diff --git a/src/webenginewidgets/qwebengine_accessible.cpp b/src/webenginewidgets/qwebengine_accessible.cpp
new file mode 100644
index 000000000..6880a5a3a
--- /dev/null
+++ b/src/webenginewidgets/qwebengine_accessible.cpp
@@ -0,0 +1,102 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebengine_accessible.h"
+
+#include "qwebengineview.h"
+#include "qwebengineview_p.h"
+
+#include "web_contents_adapter.h"
+
+QT_BEGIN_NAMESPACE
+
+QWebEngineViewAccessible::QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o)
+{
+}
+
+bool QWebEngineViewAccessible::isValid() const
+{
+ if (!QAccessibleWidget::isValid())
+ return false;
+
+ if (!view() || !view()->d_func() || !view()->d_func()->page || !view()->d_func()->page->d_func())
+ return false;
+
+ return true;
+}
+
+QAccessibleInterface *QWebEngineViewAccessible::focusChild() const
+{
+ if (child(0) && child(0)->focusChild())
+ return child(0)->focusChild();
+ return const_cast<QWebEngineViewAccessible *>(this);
+}
+
+int QWebEngineViewAccessible::childCount() const
+{
+ return child(0) ? 1 : 0;
+}
+
+QAccessibleInterface *QWebEngineViewAccessible::child(int index) const
+{
+ if (index == 0 && isValid())
+ return view()->page()->d_func()->adapter->browserAccessible();
+ return nullptr;
+}
+
+int QWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ if (child(0) && c == child(0))
+ return 0;
+ return -1;
+}
+
+QWebEngineView *QWebEngineViewAccessible::view() const
+{
+ return static_cast<QWebEngineView *>(object());
+}
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+RenderWidgetHostViewQtDelegateWidgetAccessible::RenderWidgetHostViewQtDelegateWidgetAccessible(QWidget *o, QWebEngineView *view)
+ : QAccessibleWidget(o)
+ , m_view(view)
+{
+}
+
+bool RenderWidgetHostViewQtDelegateWidgetAccessible::isValid() const
+{
+ if (!viewAccessible() || !viewAccessible()->isValid())
+ return false;
+
+ return QAccessibleWidget::isValid();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::focusChild() const
+{
+ return viewAccessible()->focusChild();
+}
+
+int RenderWidgetHostViewQtDelegateWidgetAccessible::childCount() const
+{
+ return viewAccessible()->childCount();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::child(int index) const
+{
+ return viewAccessible()->child(index);
+}
+
+int RenderWidgetHostViewQtDelegateWidgetAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ return viewAccessible()->indexOfChild(c);
+}
+
+QWebEngineViewAccessible *RenderWidgetHostViewQtDelegateWidgetAccessible::viewAccessible() const
+{
+ return static_cast<QWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/webenginewidgets/qwebengine_accessible.h b/src/webenginewidgets/qwebengine_accessible.h
new file mode 100644
index 000000000..f47996cf7
--- /dev/null
+++ b/src/webenginewidgets/qwebengine_accessible.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINE_ACCESSIBLE_H
+#define QWEBENGINE_ACCESSIBLE_H
+
+#include <QtCore/QPointer>
+#include <QtWidgets/QAccessibleWidget>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineView;
+
+class QWebEngineViewAccessible : public QAccessibleWidget
+{
+public:
+ QWebEngineViewAccessible(QWebEngineView *o);
+
+ bool isValid() const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *child) const override;
+
+private:
+ QWebEngineView *view() const;
+};
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQtDelegateWidgetAccessible : public QAccessibleWidget
+{
+public:
+ RenderWidgetHostViewQtDelegateWidgetAccessible(QWidget *o, QWebEngineView *view);
+
+ bool isValid() const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *child) const override;
+
+private:
+ QWebEngineViewAccessible *viewAccessible() const;
+ QPointer<QWebEngineView> m_view;
+};
+} // namespace QtWebEngineCore
+
+#endif // QWEBENGINE_ACCESSIBLE_H
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
deleted file mode 100644
index aa136b662..000000000
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "render_widget_host_view_qt_delegate_widget.h"
-
-#include "render_widget_host_view_qt_delegate_client.h"
-
-#include <QtWebEngineCore/private/qwebenginepage_p.h>
-#include "qwebengineview.h"
-#include "qwebengineview_p.h"
-
-#include <QGuiApplication>
-#include <QMouseEvent>
-#include <QResizeEvent>
-#include <QSGImageNode>
-#include <QWindow>
-
-namespace QtWebEngineCore {
-
-class RenderWidgetHostViewQuickItem : public QQuickItem, public Compositor::Observer
-{
-public:
- RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client)
- {
- setFlag(ItemHasContents, true);
- // Mark that this item should receive focus when the parent QQuickWidget receives focus.
- setFocus(true);
-
- bind(client->compositorId());
- }
- ~RenderWidgetHostViewQuickItem() { unbind(); }
-
-protected:
- bool event(QEvent *event) override
- {
- if (event->type() == QEvent::ShortcutOverride)
- return m_client->forwardEvent(event);
-
- return QQuickItem::event(event);
- }
- void focusInEvent(QFocusEvent *event) override
- {
- m_client->forwardEvent(event);
- }
- void focusOutEvent(QFocusEvent *event) override
- {
- m_client->forwardEvent(event);
- }
- void inputMethodEvent(QInputMethodEvent *event) override
- {
- m_client->forwardEvent(event);
- }
- void itemChange(ItemChange change, const ItemChangeData &value) override
- {
- QQuickItem::itemChange(change, value);
- if (change == QQuickItem::ItemSceneChange) {
- for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
- disconnect(c);
- m_windowConnections.clear();
- if (value.window) {
- m_windowConnections.append(connect(
- value.window, &QQuickWindow::beforeRendering, this,
- &RenderWidgetHostViewQuickItem::onBeforeRendering, Qt::DirectConnection));
- }
- }
- }
- QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override
- {
- auto comp = compositor();
- if (!comp)
- return nullptr;
-
- QQuickWindow *win = QQuickItem::window();
-
- // Delete old node before swapFrame to decrement refcount of
- // QImage in software mode.
- delete oldNode;
- QSGImageNode *node = win->createImageNode();
- node->setOwnsTexture(true);
-
- comp->swapFrame();
-
- QSize texSize = comp->size();
- QSizeF texSizeInDips = QSizeF(texSize) / comp->devicePixelRatio();
- node->setRect(QRectF(QPointF(0, 0), texSizeInDips));
-
- if (comp->type() == Compositor::Type::Software) {
- QImage image = comp->image();
- node->setTexture(win->createTextureFromImage(image));
- } else if (comp->type() == Compositor::Type::OpenGL) {
-#if QT_CONFIG(opengl)
- QQuickWindow::CreateTextureOptions texOpts;
- if (comp->hasAlphaChannel())
- texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
- int texId = comp->textureId();
- node->setTexture(QNativeInterface::QSGOpenGLTexture::fromNative(texId, win, texSize, texOpts));
- node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
-#else
- Q_UNREACHABLE();
-
-#endif
- } else {
- Q_UNREACHABLE();
- }
-
- return node;
- }
- void onBeforeRendering()
- {
- auto comp = compositor();
- if (!comp || comp->type() != Compositor::Type::OpenGL)
- return;
- comp->waitForTexture();
- }
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
- {
- return m_client->inputMethodQuery(query);
- }
- void readyToSwap() override
- {
- // Call update() on UI thread.
- QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
- }
-
-private:
- RenderWidgetHostViewQtDelegateClient *m_client;
- QList<QMetaObject::Connection> m_windowConnections;
-};
-
-RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent)
- : QQuickWidget(parent)
- , m_client(client)
- , m_rootItem(new RenderWidgetHostViewQuickItem(client))
- , m_isPopup(false)
-{
- setFocusPolicy(Qt::StrongFocus);
- setMouseTracking(true);
- setAttribute(Qt::WA_AcceptTouchEvents);
- setAttribute(Qt::WA_OpaquePaintEvent);
- setAttribute(Qt::WA_AlwaysShowToolTips);
-
- setContent(QUrl(), nullptr, m_rootItem.data());
-
- connectRemoveParentBeforeParentDelete();
-}
-
-RenderWidgetHostViewQtDelegateWidget::~RenderWidgetHostViewQtDelegateWidget()
-{
- QWebEngineViewPrivate::bindPageAndWidget(nullptr, this);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::connectRemoveParentBeforeParentDelete()
-{
- disconnect(m_parentDestroyedConnection);
-
- if (QWidget *parent = parentWidget()) {
- m_parentDestroyedConnection = connect(parent, &QObject::destroyed,
- this,
- &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
- } else {
- m_parentDestroyedConnection = QMetaObject::Connection();
- }
-}
-
-void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
-{
- // Unset the parent, because parent is being destroyed, but the owner of this
- // RenderWidgetHostViewQtDelegateWidget is actually a RenderWidgetHostViewQt instance.
- setParent(nullptr);
-
- // If this widget represents a popup window, make sure to close it, so that if the popup was the
- // last visible top level window, the application event loop can quit if it deems it necessarry.
- if (m_isPopup)
- close();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
-{
- m_isPopup = true;
-
- // The keyboard events are supposed to go to the parent RenderHostView
- // so the WebUI popups should never have focus. Besides, if the parent view
- // loses focus, WebKit will cause its associated popups (including this one)
- // to be destroyed.
- setAttribute(Qt::WA_ShowWithoutActivating);
- setFocusPolicy(Qt::NoFocus);
- setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
-
- setGeometry(screenRect);
- show();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::closeEvent(QCloseEvent *event)
-{
- Q_UNUSED(event);
-
- // If a close event was received from the window manager (e.g. when moving the parent window,
- // clicking outside the popup area)
- // make sure to notify the Chromium WebUI popup and its underlying
- // RenderWidgetHostViewQtDelegate instance to be closed.
- if (m_isPopup)
- m_client->closePopup();
-}
-
-QRectF RenderWidgetHostViewQtDelegateWidget::viewGeometry() const
-{
- return QRectF(mapToGlobal(pos()), size());
-}
-
-QRect RenderWidgetHostViewQtDelegateWidget::windowGeometry() const
-{
- if (!window())
- return QRect();
- return window()->frameGeometry();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
-{
- // The root item always has focus within the root focus scope:
- Q_ASSERT(m_rootItem->hasFocus());
-
- setFocus();
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::hasKeyboardFocus()
-{
- // The root item always has focus within the root focus scope:
- Q_ASSERT(m_rootItem->hasFocus());
-
- return hasFocus();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::lockMouse()
-{
- grabMouse();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::unlockMouse()
-{
- releaseMouse();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::show()
-{
- m_rootItem->setVisible(true);
- // Check if we're attached to a QWebEngineView, we don't
- // want to show anything else than popups as top-level.
- if (parent() || m_isPopup) {
- QQuickWidget::show();
- }
-}
-
-void RenderWidgetHostViewQtDelegateWidget::hide()
-{
- m_rootItem->setVisible(false);
- QQuickWidget::hide();
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
-{
- return QQuickWidget::isVisible() && m_rootItem->isVisible();
-}
-
-QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
-{
- const QWidget* root = QQuickWidget::window();
- return root ? root->windowHandle() : 0;
-}
-
-void RenderWidgetHostViewQtDelegateWidget::updateCursor(const QCursor &cursor)
-{
- QQuickWidget::setCursor(cursor);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::resize(int width, int height)
-{
- QQuickWidget::resize(width, height);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::move(const QPoint &screenPos)
-{
- Q_ASSERT(m_isPopup);
- QQuickWidget::move(screenPos);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVisible, bool passwordInput)
-{
- QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible && !passwordInput);
- qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
- if (qApp->inputMethod()->isVisible() != editorVisible)
- qApp->inputMethod()->setVisible(editorVisible);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::setInputMethodHints(Qt::InputMethodHints hints)
-{
- QQuickWidget::setInputMethodHints(hints);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color)
-{
- QQuickWidget::setClearColor(color);
- // QQuickWidget 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);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent)
-{
- QQuickWidget::resizeEvent(resizeEvent);
- m_client->visualPropertiesChanged();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
-{
- QQuickWidget::showEvent(event);
- // We don't have a way to catch a top-level window change with QWidget
- // but a widget will most likely be shown again if it changes, so do
- // the reconnection at this point.
- for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
- disconnect(c);
- m_windowConnections.clear();
- if (QWindow *w = window()) {
- m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
- m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
- }
- m_client->visualPropertiesChanged();
- m_client->notifyShown();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event)
-{
- QQuickWidget::hideEvent(event);
- m_client->notifyHidden();
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
-{
- bool handled = false;
-
- // Track parent to make sure we don't get deleted.
- switch (event->type()) {
- case QEvent::ParentChange:
- connectRemoveParentBeforeParentDelete();
- break;
- default:
- break;
- }
-
- // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
- // disabled.
- if (!isEnabled()) {
- switch (event->type()) {
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- case QEvent::TabletMove:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- case QEvent::TouchCancel:
- case QEvent::ContextMenu:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
-#endif
- return false;
- default:
- break;
- }
- }
-
- switch (event->type()) {
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- // We forward focus events later, once they have made it to the m_rootItem.
- return QQuickWidget::event(event);
- case QEvent::DragEnter:
- case QEvent::DragLeave:
- case QEvent::DragMove:
- case QEvent::Drop:
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- case QEvent::HoverMove:
- // Let the parent handle these events.
- return false;
- default:
- break;
- }
-
- if (event->type() == QEvent::MouseButtonDblClick) {
- // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event.
- // QtQuick is different by sending both the Press and DblClick events for the second press
- // where we can simply ignore the DblClick event.
- QMouseEvent *dblClick = static_cast<QMouseEvent *>(event);
- QMouseEvent press(QEvent::MouseButtonPress, dblClick->position(), dblClick->scenePosition(),
- dblClick->globalPosition(), dblClick->button(), dblClick->buttons(),
- dblClick->modifiers(), dblClick->source());
- press.setTimestamp(dblClick->timestamp());
- handled = m_client->forwardEvent(&press);
- } else
- handled = m_client->forwardEvent(event);
-
- if (!handled)
- return QQuickWidget::event(event);
- event->accept();
- return true;
-}
-
-void RenderWidgetHostViewQtDelegateWidget::unhandledWheelEvent(QWheelEvent *ev)
-{
- if (QWidget *p = parentWidget())
- qApp->sendEvent(p, ev);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::onWindowPosChanged()
-{
- m_client->visualPropertiesChanged();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::adapterClientChanged(WebContentsAdapterClient *client)
-{
- if (m_pageDestroyedConnection)
- disconnect(m_pageDestroyedConnection);
- QWebEnginePage *page = static_cast<QWebEnginePagePrivate *>(client)->q_func();
- QWebEngineViewPrivate::bindPageAndWidget(page, this);
- m_pageDestroyedConnection = connect(page, &QWebEnginePage::_q_aboutToDelete, this,
- [this]() { QWebEngineViewPrivate::bindPageAndWidget(nullptr, this); });
-}
-
-#if QT_CONFIG(accessibility)
-RenderWidgetHostViewQtDelegateWidgetAccessible::RenderWidgetHostViewQtDelegateWidgetAccessible(RenderWidgetHostViewQtDelegateWidget *o, QWebEngineView *view)
- : QAccessibleWidget(o)
- , m_view(view)
-{
-}
-
-bool RenderWidgetHostViewQtDelegateWidgetAccessible::isValid() const
-{
- if (!viewAccessible() || !viewAccessible()->isValid())
- return false;
-
- return QAccessibleWidget::isValid();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::focusChild() const
-{
- return viewAccessible()->focusChild();
-}
-
-int RenderWidgetHostViewQtDelegateWidgetAccessible::childCount() const
-{
- return viewAccessible()->childCount();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::child(int index) const
-{
- return viewAccessible()->child(index);
-}
-
-int RenderWidgetHostViewQtDelegateWidgetAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- return viewAccessible()->indexOfChild(c);
-}
-
-QWebEngineViewAccessible *RenderWidgetHostViewQtDelegateWidgetAccessible::viewAccessible() const
-{
- return static_cast<QWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
-}
-#endif // QT_CONFIG(accessibility)
-
-} // namespace QtWebEngineCore
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
deleted file mode 100644
index 1adebd3b5..000000000
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H
-#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H
-
-#include "render_widget_host_view_qt_delegate.h"
-#include "web_contents_adapter_client.h"
-
-#include <QAccessibleWidget>
-#include <QQuickItem>
-#include <QQuickWidget>
-
-QT_BEGIN_NAMESPACE
-class QWebEnginePage;
-class QWebEngineView;
-class QWebEngineViewAccessible;
-class QWebEngineViewPrivate;
-QT_END_NAMESPACE
-
-namespace QtWebEngineCore {
-
-// Useful information keyboard and mouse QEvent propagation.
-// A RenderWidgetHostViewQtDelegateWidget instance initialized as a popup will receive
-// no keyboard focus (so all keyboard QEvents will be sent to the parent RWHVQD instance),
-// but will still receive mouse input (all mouse QEvent moves and clicks will be given to the popup
-// RWHVQD instance, and the mouse interaction area covers the surface of the whole parent
-// QWebEngineView, and not only the smaller surface that an HTML select popup would occupy).
-class RenderWidgetHostViewQtDelegateWidget : public QQuickWidget, public RenderWidgetHostViewQtDelegate {
- Q_OBJECT
-public:
- RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent = nullptr);
- ~RenderWidgetHostViewQtDelegateWidget();
-
- void initAsPopup(const QRect&) override;
- QRectF viewGeometry() const override;
- QRect windowGeometry() const override;
- void setKeyboardFocus() override;
- bool hasKeyboardFocus() override;
- void lockMouse() override;
- void unlockMouse() override;
- void show() override;
- void hide() override;
- bool isVisible() const override;
- QWindow* window() const override;
- void updateCursor(const QCursor &) override;
- void resize(int width, int height) override;
- void move(const QPoint &screenPos) override;
- void inputMethodStateChanged(bool editorVisible, bool passwordInput) override;
- void setInputMethodHints(Qt::InputMethodHints) override;
- void setClearColor(const QColor &color) override;
- void unhandledWheelEvent(QWheelEvent *ev) override;
-
-protected:
- bool event(QEvent *event) override;
- void resizeEvent(QResizeEvent *resizeEvent) override;
- void showEvent(QShowEvent *) override;
- void hideEvent(QHideEvent *) override;
- void closeEvent(QCloseEvent *event) override;
-
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
- void adapterClientChanged(WebContentsAdapterClient *client) override;
-
-private Q_SLOTS:
- void onWindowPosChanged();
- void connectRemoveParentBeforeParentDelete();
- void removeParentBeforeParentDelete();
-
-private:
- friend QWebEngineViewPrivate;
-
- RenderWidgetHostViewQtDelegateClient *m_client;
- QScopedPointer<QQuickItem> m_rootItem;
- bool m_isPopup;
- QColor m_clearColor;
- QList<QMetaObject::Connection> m_windowConnections;
- QWebEnginePage *m_page = nullptr;
- QMetaObject::Connection m_parentDestroyedConnection;
- QMetaObject::Connection m_pageDestroyedConnection;
-};
-
-#if QT_CONFIG(accessibility)
-class RenderWidgetHostViewQtDelegateWidgetAccessible : public QAccessibleWidget
-{
-public:
- RenderWidgetHostViewQtDelegateWidgetAccessible(RenderWidgetHostViewQtDelegateWidget *o, QWebEngineView *view);
-
- bool isValid() const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface *child) const override;
-
-private:
- QWebEngineViewAccessible *viewAccessible() const;
- QWebEngineView *m_view;
-};
-#endif // QT_CONFIG(accessibility)
-
-} // namespace QtWebEngineCore
-
-#endif
diff --git a/src/webenginewidgets/ui/autofillpopupwidget.cpp b/src/webenginewidgets/ui/autofillpopupwidget.cpp
new file mode 100644
index 000000000..a4dc31beb
--- /dev/null
+++ b/src/webenginewidgets/ui/autofillpopupwidget.cpp
@@ -0,0 +1,201 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "autofillpopupwidget_p.h"
+#include "qwebengineview.h"
+#include "qwebengineview_p.h"
+
+#include "autofill_popup_controller.h"
+
+#include <QApplication>
+#include <QBoxLayout>
+#include <QEvent>
+#include <QKeyEvent>
+#include <QListView>
+#include <QMouseEvent>
+
+namespace QtWebEngineWidgetUI {
+
+AutofillPopupWidget::AutofillPopupWidget(QtWebEngineCore::AutofillPopupController *controller,
+ QWebEngineView *parent)
+ : QFrame(parent, Qt::Popup), m_controller(controller), m_webEngineView(parent)
+{
+ setAttribute(Qt::WA_WindowPropagation);
+ setAttribute(Qt::WA_X11NetWmWindowTypeCombo);
+
+ // we need a vertical layout
+ QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ layout->setSpacing(0);
+ layout->setContentsMargins(QMargins());
+
+ m_listView = new QListView(m_webEngineView);
+ m_listView->setModel(m_controller->model());
+ m_listView->setTextElideMode(Qt::ElideMiddle);
+
+ // Based on QComboBoxPrivateContainer::setItemView
+ m_listView->setParent(this);
+ m_listView->setAttribute(Qt::WA_MacShowFocusRect, false);
+ layout->insertWidget(0, m_listView);
+ m_listView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+
+ m_listView->installEventFilter(this);
+ // Necessary for filtering QEvent::MouseMove:
+ m_listView->viewport()->installEventFilter(this);
+
+ m_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ // TODO: Implement vertical scrollbar. Chromium also has it.
+ m_listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_listView->setMouseTracking(true);
+
+ m_listView->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ // Some styles (Mac) have a margin at the top and bottom of the popup.
+ layout->insertSpacing(0, 0);
+ layout->addSpacing(0);
+
+ connect(m_controller, &QtWebEngineCore::AutofillPopupController::currentIndexChanged,
+ m_listView, &QListView::setCurrentIndex);
+}
+
+AutofillPopupWidget::~AutofillPopupWidget() { }
+
+// Based on QComboBox::showPopup()
+void AutofillPopupWidget::showPopup(QPoint pos, int width, bool autoselectFirstSuggestion)
+{
+ QStyle *const style = m_webEngineView->style();
+ QStyleOptionComboBox opt;
+ opt.initFrom(m_webEngineView);
+
+ if (autoselectFirstSuggestion)
+ m_controller->selectFirstSuggestion();
+
+ QRect listRect(pos, QSize(width, 0));
+
+ // Calculate height
+ {
+ int listHeight = 0;
+ int rowCount = m_controller->model()->rowCount();
+ for (int i = 0; i < rowCount; ++i) {
+ QModelIndex idx = m_controller->model()->index(i, 0);
+ listHeight += m_listView->visualRect(idx).height();
+ }
+ if (rowCount > 1)
+ listHeight += (rowCount - 1) * m_listView->spacing() * 2;
+
+ listRect.setHeight(listRect.height() + listHeight);
+ }
+
+ // Calculate height margin
+ {
+ int heightMargin = m_listView->spacing() * 2;
+
+ // Add the frame of the popup
+ const QMargins pm = contentsMargins();
+ heightMargin += pm.top() + pm.bottom();
+
+ // Add the frame of the list view
+ const QMargins vm = m_listView->contentsMargins();
+ heightMargin += vm.top() + vm.bottom();
+ listRect.setHeight(listRect.height() + heightMargin);
+ }
+
+ // Add space for margin at top and bottom if the style wants it
+ int styleMargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) * 2;
+ listRect.setHeight(listRect.height() + styleMargin);
+
+ // Takes account of the mimium/maximum size of the popup
+ layout()->activate();
+ listRect.setSize(listRect.size().expandedTo(minimumSize()).boundedTo(maximumSize()));
+
+ setGeometry(listRect);
+ QFrame::show();
+}
+
+bool AutofillPopupWidget::eventFilter(QObject *object, QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::MouseMove:
+ if (isVisible()) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+ QModelIndex indexUnderMouse = m_listView->indexAt(mouseEvent->position().toPoint());
+ if (indexUnderMouse.isValid()
+ && indexUnderMouse.data(Qt::AccessibleDescriptionRole).toString()
+ != QLatin1String("separator")) {
+ m_controller->selectSuggestion(indexUnderMouse.row());
+ }
+ }
+ return true;
+ case QEvent::MouseButtonRelease: {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+ if (mouseEvent->button() == Qt::LeftButton) {
+ m_controller->acceptSuggestion();
+ return true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return QFrame::eventFilter(object, event);
+}
+
+void AutofillPopupWidget::keyPressEvent(QKeyEvent *event)
+{
+ // AutofillPopupControllerImpl::HandleKeyPressEvent()
+ // chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+ switch (event->key()) {
+ case Qt::Key_Up:
+ m_controller->selectPreviousSuggestion();
+ return;
+ case Qt::Key_Down:
+ m_controller->selectNextSuggestion();
+ return;
+ case Qt::Key_PageUp:
+ m_controller->selectFirstSuggestion();
+ return;
+ case Qt::Key_PageDown:
+ m_controller->selectLastSuggestion();
+ return;
+ case Qt::Key_Escape:
+ m_webEngineView->d_ptr->hideAutofillPopup();
+ return;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ m_controller->acceptSuggestion();
+ return;
+ case Qt::Key_Delete:
+ // Remove suggestion is not supported for datalist.
+ // Forward delete to view to be able to remove selected text.
+ break;
+ case Qt::Key_Tab:
+ m_controller->acceptSuggestion();
+ break;
+ default:
+ break;
+ }
+
+ QCoreApplication::sendEvent(m_webEngineView->focusWidget(), event);
+}
+
+void AutofillPopupWidget::keyReleaseEvent(QKeyEvent *event)
+{
+ // Do not forward release events of the overridden key presses.
+ switch (event->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Escape:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ return;
+ default:
+ break;
+ }
+
+ QCoreApplication::sendEvent(m_webEngineView->focusWidget(), event);
+}
+
+} // namespace QtWebEngineWidgetUI
diff --git a/src/webenginewidgets/ui/autofillpopupwidget_p.h b/src/webenginewidgets/ui/autofillpopupwidget_p.h
new file mode 100644
index 000000000..79decc6ab
--- /dev/null
+++ b/src/webenginewidgets/ui/autofillpopupwidget_p.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef AUTOFILLPOPUPWIDGET_P_H
+#define AUTOFILLPOPUPWIDGET_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 <QFrame>
+
+namespace QtWebEngineCore {
+class AutofillPopupController;
+}
+
+QT_BEGIN_NAMESPACE
+class QListView;
+class QWebEngineView;
+class QWebEngineViewPrivate;
+QT_END_NAMESPACE
+
+namespace QtWebEngineWidgetUI {
+
+// Based on QComboBoxPrivateContainer
+class AutofillPopupWidget : public QFrame
+{
+ Q_OBJECT
+public:
+ AutofillPopupWidget(QtWebEngineCore::AutofillPopupController *controller,
+ QWebEngineView *parent);
+ ~AutofillPopupWidget();
+
+ void showPopup(QPoint pos, int width, bool autoselectFirstSuggestion);
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+
+private:
+ QtWebEngineCore::AutofillPopupController *m_controller;
+ QWebEngineView *m_webEngineView;
+ QListView *m_listView;
+
+ friend class QT_PREPEND_NAMESPACE(QWebEngineViewPrivate);
+};
+
+} // namespace QtWebEngineWidgetUI
+
+#endif // AUTOFILLPOPUPWIDGET_P_H
diff --git a/src/webenginewidgets/ui/touchhandlewidget.cpp b/src/webenginewidgets/ui/touchhandlewidget.cpp
new file mode 100644
index 000000000..88af0ff36
--- /dev/null
+++ b/src/webenginewidgets/ui/touchhandlewidget.cpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "touchhandlewidget_p.h"
+#include "qwebengineview.h"
+
+#include <QBoxLayout>
+#include <QGraphicsOpacityEffect>
+#include <QLabel>
+#include <QWidget>
+
+namespace QtWebEngineWidgetUI {
+TouchHandleWidget::TouchHandleWidget(QWebEngineView *view, const QMap<int, QImage> &images)
+ : m_widget(new QWidget(view))
+ , m_label(new QLabel(m_widget))
+ , m_opacityEffect(new QGraphicsOpacityEffect(m_widget))
+ , m_images(images)
+{
+ m_widget->setAttribute(Qt::WA_AcceptTouchEvents, true);
+ m_widget->setAttribute(Qt::WA_TransparentForMouseEvents, true);
+}
+
+TouchHandleWidget::~TouchHandleWidget()
+{
+}
+
+void TouchHandleWidget::setImage(int orientation)
+{
+ const QImage &img = m_images[orientation];
+ m_label->setPixmap(QPixmap::fromImage(img));
+ m_label->setFrameStyle(QFrame::NoFrame);
+ m_label->resize(img.size());
+ m_label->setVisible(true);
+
+ QVBoxLayout layout;
+ layout.setSpacing(0);
+ layout.setContentsMargins(QMargins());
+ layout.addWidget(m_label);
+ layout.setParent(m_widget);
+ m_widget->setLayout(&layout);
+ m_widget->resize(img.size());
+}
+
+void TouchHandleWidget::setBounds(const QRect &bounds)
+{
+ m_widget->setGeometry(bounds);
+}
+
+void TouchHandleWidget::setVisible(bool visible)
+{
+ m_widget->setVisible(visible);
+}
+
+void TouchHandleWidget::setOpacity(float opacity)
+{
+ m_opacityEffect->setOpacity(opacity);
+ m_widget->setGraphicsEffect(m_opacityEffect);
+}
+} // namespace QtWebEngineWidgetUI
diff --git a/src/webenginewidgets/ui/touchhandlewidget_p.h b/src/webenginewidgets/ui/touchhandlewidget_p.h
new file mode 100644
index 000000000..9f181c935
--- /dev/null
+++ b/src/webenginewidgets/ui/touchhandlewidget_p.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef TOUCHHANDLEWIDGET_P_H
+#define TOUCHHANDLEWIDGET_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 "touch_handle_drawable_client.h"
+
+#include <QImage>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+class QGraphicsOpacityEffect;
+class QLabel;
+class QWebEngineView;
+class QWidget;
+QT_END_NAMESPACE
+
+namespace QtWebEngineWidgetUI {
+class TouchHandleWidget : public QtWebEngineCore::TouchHandleDrawableDelegate
+{
+public:
+ TouchHandleWidget(QWebEngineView *view, const QMap<int, QImage> &images);
+ ~TouchHandleWidget();
+
+ void setImage(int orientation) override;
+ void setBounds(const QRect &bounds) override;
+ void setVisible(bool visible) override;
+ void setOpacity(float opacity) override;
+
+private:
+ QWidget *m_widget;
+ QLabel *m_label;
+ QGraphicsOpacityEffect *m_opacityEffect;
+ QMap<int, QImage> m_images;
+};
+} // namespace QtWebEngineWidgetUI
+
+#endif // TOUCHHANDLEWIDGET_P_H
diff --git a/src/webenginewidgets/ui/touchselectionmenuwidget.cpp b/src/webenginewidgets/ui/touchselectionmenuwidget.cpp
new file mode 100644
index 000000000..ff69fe84b
--- /dev/null
+++ b/src/webenginewidgets/ui/touchselectionmenuwidget.cpp
@@ -0,0 +1,117 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "touchselectionmenuwidget_p.h"
+#include "qwebengineview.h"
+
+#include "touch_selection_menu_controller.h"
+
+#include <QBoxLayout>
+#include <QEvent>
+
+namespace QtWebEngineWidgetUI {
+namespace {
+// The Widgets module is built with rtti in developer-build while Core is not.
+// The MOC will throw "undefined reference to typeinfo..." errors if we connect slots
+// from QtWebEngineCore via function pointers, because it expects rtti on them.
+// To workaround this we use lambdas.
+void connectButton(TouchSelectionMenuWidget::TouchButton *button, std::function<void()> callback)
+{
+ QObject::connect(button, &QPushButton::clicked, std::move(callback));
+}
+} // namespace
+
+TouchSelectionMenuWidget::TouchButton::TouchButton(QString name, QWidget *parent)
+ : QPushButton(name, parent)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents, true);
+}
+
+TouchSelectionMenuWidget::TouchButton::~TouchButton()
+{
+}
+
+bool TouchSelectionMenuWidget::TouchButton::event(QEvent *ev)
+{
+ switch (ev->type()) {
+ case QEvent::TouchBegin:
+ ev->accept();
+ return true;
+ case QEvent::TouchEnd:
+ Q_EMIT clicked();
+ ev->accept();
+ return true;
+ default:
+ break;
+ }
+
+ return QPushButton::event(ev);
+}
+
+TouchSelectionMenuWidget::TouchSelectionMenuWidget(
+ QWebEngineView *view, QtWebEngineCore::TouchSelectionMenuController *controller)
+ : QWidget(view,
+ Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
+ | Qt::WindowDoesNotAcceptFocus)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents, true);
+ setAttribute(Qt::WA_TransparentForMouseEvents, true);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ bool cutEnabled =
+ controller->isCommandEnabled(QtWebEngineCore::TouchSelectionMenuController::Cut);
+ bool copyEnabled =
+ controller->isCommandEnabled(QtWebEngineCore::TouchSelectionMenuController::Copy);
+ bool pasteEnabled =
+ controller->isCommandEnabled(QtWebEngineCore::TouchSelectionMenuController::Paste);
+
+ QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ QHBoxLayout *layout = new QHBoxLayout();
+
+ if (cutEnabled) {
+ TouchButton *button = new TouchButton(tr("Cut"), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->cut(); });
+ }
+
+ if (copyEnabled) {
+ TouchButton *button = new TouchButton(tr("Copy"), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->copy(); });
+ }
+
+ if (pasteEnabled) {
+ TouchButton *button = new TouchButton(tr("Paste"), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->paste(); });
+ }
+
+ TouchButton *button = new TouchButton(tr("..."), this);
+ button->setSizePolicy(policy);
+ layout->addWidget(button);
+ connectButton(button, [controller]() { controller->runContextMenu(); });
+
+ layout->setSpacing(2);
+ layout->setSizeConstraint(QLayout::SetMinimumSize);
+ layout->setContentsMargins(0, 0, 0, 0);
+ setLayout(layout);
+
+ nativeParentWidget()->installEventFilter(this);
+}
+
+TouchSelectionMenuWidget::~TouchSelectionMenuWidget()
+{
+}
+
+bool TouchSelectionMenuWidget::eventFilter(QObject *obj, QEvent *ev)
+{
+ // Close the menu if the window is moved
+ if (ev->type() == QEvent::Move)
+ close();
+
+ return QWidget::eventFilter(obj, ev);
+}
+} // QtWebEngineWidgetUI
diff --git a/src/webenginewidgets/ui/touchselectionmenuwidget_p.h b/src/webenginewidgets/ui/touchselectionmenuwidget_p.h
new file mode 100644
index 000000000..1f822023b
--- /dev/null
+++ b/src/webenginewidgets/ui/touchselectionmenuwidget_p.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef TOUCHSELECTIONMENUWIDGET_P_H
+#define TOUCHSELECTIONMENUWIDGET_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 <QPushButton>
+#include <QWidget>
+
+namespace QtWebEngineCore {
+class TouchSelectionMenuController;
+}
+
+QT_BEGIN_NAMESPACE
+class QWebEngineView;
+QT_END_NAMESPACE
+
+namespace QtWebEngineWidgetUI {
+class TouchSelectionMenuWidget : public QWidget
+{
+public:
+ class TouchButton : public QPushButton
+ {
+ public:
+ TouchButton(QString name, QWidget *parent);
+ ~TouchButton();
+
+ protected:
+ bool event(QEvent *ev) override;
+ };
+
+ TouchSelectionMenuWidget(QWebEngineView *view,
+ QtWebEngineCore::TouchSelectionMenuController *controller);
+ ~TouchSelectionMenuWidget();
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *ev) override;
+};
+} // namespace QtWebEngineWidgetUI
+
+#endif // TOUCHSELECTIONMENUWIDGET_P_H
diff --git a/sync.profile b/sync.profile
deleted file mode 100644
index 44a85e829..000000000
--- a/sync.profile
+++ /dev/null
@@ -1,14 +0,0 @@
-%modules = ( # path to module name map
- "QtWebEngineQuick" => "$basedir/src/webenginequick",
- "QtWebEngineWidgets" => "$basedir/src/webenginewidgets",
- "QtWebEngineCore" => "$basedir/src/core/api",
- "QtPdf" => "$basedir/src/pdf",
- "QtPdfQuick" => "$basedir/src/pdfquick",
- "QtPdfWidgets" => "$basedir/src/pdfwidgets",
-);
-%moduleheaders = ( # restrict the module headers to those found in relative path
- "QtWebEngineQuick" => "api",
- "QtWebEngineWidgets" => "api"
-);
-%classnames = (
-);
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index e000203d9..1b0ff3e9d 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+add_subdirectory(cmake)
if(TARGET Qt::WebEngineCore)
add_subdirectory(httpserver)
add_subdirectory(util)
@@ -12,3 +15,6 @@ endif()
if(TARGET Qt::Pdf)
add_subdirectory(pdf)
endif()
+if(TARGET Qt::PdfQuick)
+ add_subdirectory(pdfquick)
+endif()
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index c5d7c3f9a..2fa1f915a 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -1,16 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
-
-project(qmake_cmake_files)
+project(qtwebengine_cmake_tests)
enable_testing()
-find_package(Qt5Core REQUIRED)
+find_package(Qt6Core REQUIRED)
-include("${_Qt5CTestMacros}")
+include("${_Qt6CTestMacros}")
-if (NOT NO_WIDGETS)
- test_module_includes(
- WebEngineWidgets QWebEngineView
+set(module_includes "")
+if(TARGET Qt6::WebEngineCore)
+ list(APPEND module_includes
+ WebEngineCore QWebEnginePage
+ )
+endif()
+if(TARGET Qt6::WebEngineWidgets)
+ list(APPEND module_includes
+ WebEngineWidgets QWebEngineView
)
endif()
+if(TARGET Qt6::Pdf)
+ list(APPEND module_includes
+ Pdf QPdfDocument
+ )
+endif()
+
+_qt_internal_test_module_includes(${module_includes})
diff --git a/tests/auto/core/CMakeLists.txt b/tests/auto/core/CMakeLists.txt
index ecb3b2cf9..5908756b4 100644
--- a/tests/auto/core/CMakeLists.txt
+++ b/tests/auto/core/CMakeLists.txt
@@ -1,10 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(qwebenginecookiestore)
+add_subdirectory(qwebengineloadinginfo)
add_subdirectory(qwebenginesettings)
+if(QT_FEATURE_ssl)
+ # only tests doh, and requires ssl
+ add_subdirectory(qwebengineglobalsettings)
+endif()
add_subdirectory(qwebengineurlrequestinterceptor)
+add_subdirectory(qwebengineurlrequestjob)
add_subdirectory(origins)
add_subdirectory(devtools)
+add_subdirectory(getdomainandregistry)
+add_subdirectory(qtversion)
if(QT_FEATURE_ssl)
add_subdirectory(qwebengineclientcertificatestore)
add_subdirectory(certificateerror)
endif()
+
+if(QT_FEATURE_webenginedriver)
+ add_subdirectory(webenginedriver)
+endif()
diff --git a/tests/auto/core/certificateerror/CMakeLists.txt b/tests/auto/core/certificateerror/CMakeLists.txt
index 57801e195..6223ca25c 100644
--- a/tests/auto/core/certificateerror/CMakeLists.txt
+++ b/tests/auto/core/certificateerror/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/core/certificateerror/tst_certificateerror.cpp b/tests/auto/core/certificateerror/tst_certificateerror.cpp
index 3c43d997f..67e2d8ae4 100644
--- a/tests/auto/core/certificateerror/tst_certificateerror.cpp
+++ b/tests/auto/core/certificateerror/tst_certificateerror.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <httpsserver.h>
#include <util.h>
@@ -92,8 +67,8 @@ void tst_CertificateError::handleError_data()
void tst_CertificateError::handleError()
{
- HttpsServer server(":/resources/server.pem",":/resources/server.key");
- server.setExpectError(true);
+ HttpsServer server(":/resources/server.pem", ":/resources/server.key", "");
+ server.setExpectError(false);
QVERIFY(server.start());
connect(&server, &HttpsServer::newRequest, [&] (HttpReqRep *rr) {
@@ -117,7 +92,7 @@ void tst_CertificateError::handleError()
QCOMPARE(chain[1].serialNumber(), "3c:16:83:83:59:c4:2a:65:8f:7a:b2:07:10:14:4e:2d:70:9a:3e:23");
if (deferError) {
- QCOMPARE(page.loadSpy.count(), 0);
+ QCOMPARE(page.loadSpy.size(), 0);
QCOMPARE(toPlainTextSync(&page), QString());
if (acceptCertificate)
@@ -127,9 +102,10 @@ void tst_CertificateError::handleError()
page.error.reset();
}
- QTRY_COMPARE_WITH_TIMEOUT(page.loadSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(page.loadSpy.size(), 1, 30000);
QCOMPARE(page.loadSpy.takeFirst().value(0).toBool(), acceptCertificate);
QCOMPARE(toPlainTextSync(&page), expectedContent);
+ QVERIFY(server.stop());
}
void tst_CertificateError::fatalError()
diff --git a/tests/auto/core/devtools/CMakeLists.txt b/tests/auto/core/devtools/CMakeLists.txt
index fd8d850f0..efde75240 100644
--- a/tests/auto/core/devtools/CMakeLists.txt
+++ b/tests/auto/core/devtools/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_devtools
SOURCES
tst_devtools.cpp
diff --git a/tests/auto/core/devtools/tst_devtools.cpp b/tests/auto/core/devtools/tst_devtools.cpp
index 3026b3931..57a2b83a3 100644
--- a/tests/auto/core/devtools/tst_devtools.cpp
+++ b/tests/auto/core/devtools/tst_devtools.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTest>
@@ -46,7 +21,10 @@ void tst_DevTools::attachAndDestroyPageFirst()
QSignalSpy spy(page, &QWebEnginePage::loadFinished);
page->load(QUrl("data:text/plain,foobarbaz"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 12000);
+
+ // shouldn't do anything until page is set
+ page->triggerAction(QWebEnginePage::InspectElement);
inspector->setInspectedPage(page);
page->triggerAction(QWebEnginePage::InspectElement);
@@ -62,12 +40,16 @@ void tst_DevTools::attachAndDestroyInspectorFirst()
{
// External inspector + manual destruction of inspector first
QWebEnginePage* page = new QWebEnginePage();
+
+ // shouldn't do anything until page is set
+ page->triggerAction(QWebEnginePage::InspectElement);
+
QWebEnginePage* inspector = new QWebEnginePage();
inspector->setInspectedPage(page);
QSignalSpy spy(page, &QWebEnginePage::loadFinished);
page->setHtml(QStringLiteral("<body><h1>FOO BAR!</h1></body>"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 12000);
page->triggerAction(QWebEnginePage::InspectElement);
diff --git a/tests/auto/core/getdomainandregistry/CMakeLists.txt b/tests/auto/core/getdomainandregistry/CMakeLists.txt
new file mode 100644
index 000000000..c2b65f9dc
--- /dev/null
+++ b/tests/auto/core/getdomainandregistry/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../util/util.cmake)
+
+qt_internal_add_test(tst_getdomainandregistry
+ SOURCES
+ tst_getdomainandregistry.cpp
+ LIBRARIES
+ Qt::WebEngineCore
+ Test::Util
+)
diff --git a/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp b/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp
new file mode 100644
index 000000000..e9e0bf105
--- /dev/null
+++ b/tests/auto/core/getdomainandregistry/tst_getdomainandregistry.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+class tst_GetDomainAndRegistry final : public QObject {
+ Q_OBJECT
+
+private Q_SLOTS:
+ void getDomainAndRegistry();
+};
+
+void tst_GetDomainAndRegistry::getDomainAndRegistry() {
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"http://www.google.com/"}), QString("google.com"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"http://www.google.co.uk/"}), QString("google.co.uk"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"http://127.0.0.1/"}), QString());
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://qt.io/"}), QString("qt.io"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://download.qt.io/"}), QString("qt.io"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://foo.fr/"}), QString("foo.fr"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://foo.gouv.fr/"}), QString("foo.gouv.fr"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://bar.foo.gouv.fr/"}), QString("foo.gouv.fr"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://fr.wikipedia.org/wiki/%C3%89l%C3%A9phant"}), QString("wikipedia.org"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://foo.günstigbestellen.de/"}), QString("foo.xn--gnstigbestellen-zvb.de"));
+ QCOMPARE(qWebEngineGetDomainAndRegistry({"https://foo.g\u00fcnstigbestellen.de/"}), QString("foo.xn--gnstigbestellen-zvb.de"));
+}
+
+
+QTEST_MAIN(tst_GetDomainAndRegistry)
+#include "tst_getdomainandregistry.moc"
diff --git a/tests/auto/core/origins/CMakeLists.txt b/tests/auto/core/origins/CMakeLists.txt
index 79b8278a7..306074994 100644
--- a/tests/auto/core/origins/CMakeLists.txt
+++ b/tests/auto/core/origins/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
@@ -6,6 +9,7 @@ qt_internal_add_test(tst_origins
tst_origins.cpp
LIBRARIES
Qt::WebEngineCore
+ Qt::WebEngineWidgets
Test::HttpServer
Test::Util
)
@@ -29,6 +33,8 @@ set(tst_origins_resource_files
"resources/viewSource.html"
"resources/websocket.html"
"resources/websocket2.html"
+ "resources/red.png"
+ "resources/fetchApi.html"
)
qt_internal_add_resource(tst_origins "tst_origins"
diff --git a/tests/auto/core/origins/resources/fetchApi.html b/tests/auto/core/origins/resources/fetchApi.html
new file mode 100644
index 000000000..7b54416fd
--- /dev/null
+++ b/tests/auto/core/origins/resources/fetchApi.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<body>
+ <script type="text/javascript">
+ const queryString = window.location.search;
+ const urlParams = new URLSearchParams(queryString);
+ const url = urlParams.get('url');
+ const f = fetch(url);
+ if (urlParams.get('printRes') == 'true') {
+ f.then((r) => r.text()).then((p) => console.log(p));
+ }
+ </script>
+</body>
+</html>
diff --git a/tests/auto/core/origins/resources/link.html b/tests/auto/core/origins/resources/link.html
new file mode 100644
index 000000000..297b9b273
--- /dev/null
+++ b/tests/auto/core/origins/resources/link.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Link</title>
+ </head>
+ <body>
+ <a id="link" href="">Link</a>
+ <script>
+ const urlParams = new URLSearchParams(window.location.search);
+ document.getElementById("link").href = urlParams.get('linkLocation');
+ </script>
+ </body>
+</html>
diff --git a/tests/auto/core/origins/resources/media.html b/tests/auto/core/origins/resources/media.html
new file mode 100644
index 000000000..091485b61
--- /dev/null
+++ b/tests/auto/core/origins/resources/media.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Media</title>
+ <script>
+ function addAudio(src) {
+ let aud = document.createElement('audio')
+ aud.src = src
+ document.getElementsByTagName("body")[0].appendChild(aud)
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/core/origins/resources/mixedSchemes.html b/tests/auto/core/origins/resources/mixedSchemes.html
index c73e9ecdc..3e50c2c3b 100644
--- a/tests/auto/core/origins/resources/mixedSchemes.html
+++ b/tests/auto/core/origins/resources/mixedSchemes.html
@@ -6,23 +6,34 @@
var result;
var canary;
- function setIFrameUrl(url) {
+ function setIFrameUrl(frameUrl,imgUrl) {
result = undefined;
canary = undefined;
- document.getElementById("iframe").setAttribute("src", url);
- // Early fire is OK unless the test is expecting cannotLoad.
- // If timeout is too short then a false positive is possible.
- setTimeout(() => { result = result || "cannotLoad"; }, 500);
+ let img = document.createElement('img');
+ img.onerror = function() {
+ console.log("TEST:cannotLoad");
+ console.log("TEST:done");
+ };
+ img.onload = function() {
+ document.getElementById("iframe").setAttribute("src", frameUrl);
+ };
+ img.src = imgUrl
}
addEventListener("load", function() {
document.getElementById("iframe").addEventListener("load", function() {
- if (canary && window[0].canary)
- result = "canLoadAndAccess";
- else
- result = "canLoadButNotAccess";
+ if (canary && window[0].canary) {
+ console.log("TEST:canLoadAndAccess");
+ console.log("TEST:done");
+ } else {
+ console.log("TEST:canLoadButNotAccess");
+ console.log("TEST:done");
+ }
});
});
+ window.onerror = function(message, url, line, col, errorObj) {
+ return true;
+ };
</script>
</head>
<body>
diff --git a/tests/auto/core/origins/resources/mixedSchemes_frame.html b/tests/auto/core/origins/resources/mixedSchemes_frame.html
index 00c20ba37..9499caa1f 100644
--- a/tests/auto/core/origins/resources/mixedSchemes_frame.html
+++ b/tests/auto/core/origins/resources/mixedSchemes_frame.html
@@ -3,8 +3,12 @@
<head>
<title>Mixed - Frame</title>
<script>
- var canary = true;
- parent.canary = true;
+ try{
+ var canary = true;
+ parent.canary = true;
+ }catch(exception){
+ };
+
</script>
</head>
<body></body>
diff --git a/tests/auto/core/origins/resources/red.png b/tests/auto/core/origins/resources/red.png
new file mode 100644
index 000000000..5ae85192b
--- /dev/null
+++ b/tests/auto/core/origins/resources/red.png
Binary files differ
diff --git a/tests/auto/core/origins/resources/redirect.css b/tests/auto/core/origins/resources/redirect.css
index 41d7560cc..a6a03d8f5 100644
--- a/tests/auto/core/origins/resources/redirect.css
+++ b/tests/auto/core/origins/resources/redirect.css
@@ -1,8 +1,3 @@
-@font-face {
- font-family: 'MyWebFont';
- src: url('redirect1:/resources/Akronim-Regular.woff2') format('woff2');
-}
-
body {
- font-family: 'MyWebFont', Fallback, sans-serif;
+ font-family: serif;
}
diff --git a/tests/auto/core/origins/resources/redirect.html b/tests/auto/core/origins/resources/redirect.html
index 04948e14b..603cb76f0 100644
--- a/tests/auto/core/origins/resources/redirect.html
+++ b/tests/auto/core/origins/resources/redirect.html
@@ -2,7 +2,14 @@
<html>
<head>
<title>redirect</title>
- <link rel="stylesheet" href="redirect1:/resources/redirect.css">
+ <script>
+ function addStylesheetLink(src) {
+ let link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.href = src;
+ document.getElementsByTagName("head")[0].appendChild(link);
+ }
+ </script>
</head>
<body>
Text
diff --git a/tests/auto/core/origins/tst_origins.cpp b/tests/auto/core/origins/tst_origins.cpp
index 08f9d097f..81385701f 100644
--- a/tests/auto/core/origins/tst_origins.cpp
+++ b/tests/auto/core/origins/tst_origins.cpp
@@ -1,42 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <util.h>
#include "httpserver.h"
#include <QtCore/qfile.h>
#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineCore/qwebengineurlrequestjob.h>
#include <QtWebEngineCore/qwebengineurlscheme.h>
#include <QtWebEngineCore/qwebengineurlschemehandler.h>
#include <QtWebEngineCore/qwebenginesettings.h>
#include <QtWebEngineCore/qwebengineprofile.h>
#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
#if defined(WEBSOCKETS)
#include <QtWebSockets/qwebsocket.h>
@@ -48,6 +25,8 @@
#define QSL QStringLiteral
#define QBAL QByteArrayLiteral
+Q_LOGGING_CATEGORY(lc, "qt.webengine.tests")
+
void registerSchemes()
{
{
@@ -125,14 +104,20 @@ void registerSchemes()
}
{
- QWebEngineUrlScheme scheme(QBAL("redirect1"));
+ QWebEngineUrlScheme scheme(QBAL("redirect"));
scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
QWebEngineUrlScheme::registerScheme(scheme);
}
{
- QWebEngineUrlScheme scheme(QBAL("redirect2"));
- scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme scheme(QBAL("redirect-secure"));
+ scheme.setFlags(QWebEngineUrlScheme::SecureScheme);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+
+ {
+ QWebEngineUrlScheme scheme(QBAL("redirect-local"));
+ scheme.setFlags(QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::LocalAccessAllowed);
QWebEngineUrlScheme::registerScheme(scheme);
}
@@ -142,7 +127,22 @@ void registerSchemes()
QWebEngineUrlScheme::registerScheme(scheme);
}
{
+ QWebEngineUrlScheme scheme(QBAL("secure-cors"));
+ scheme.setFlags(QWebEngineUrlScheme::SecureScheme | QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+ {
+ QWebEngineUrlScheme scheme(QBAL("localaccess"));
+ scheme.setFlags(QWebEngineUrlScheme::LocalAccessAllowed);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+ {
QWebEngineUrlScheme scheme(QBAL("local"));
+ scheme.setFlags(QWebEngineUrlScheme::LocalScheme);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+ {
+ QWebEngineUrlScheme scheme(QBAL("local-localaccess"));
scheme.setFlags(QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::LocalAccessAllowed);
QWebEngineUrlScheme::registerScheme(scheme);
}
@@ -151,7 +151,15 @@ void registerSchemes()
scheme.setFlags(QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::CorsEnabled);
QWebEngineUrlScheme::registerScheme(scheme);
}
-
+ {
+ QWebEngineUrlScheme scheme("fetchapi-allowed");
+ scheme.setFlags(QWebEngineUrlScheme::CorsEnabled | QWebEngineUrlScheme::FetchApiAllowed);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+ {
+ QWebEngineUrlScheme scheme("fetchapi-not-allowed");
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
}
Q_CONSTRUCTOR_FUNCTION(registerSchemes)
@@ -175,10 +183,14 @@ public:
profile->installUrlSchemeHandler(QBAL("HostSyntax-ContentSecurityPolicyIgnored"), this);
profile->installUrlSchemeHandler(QBAL("HostAndPortSyntax"), this);
profile->installUrlSchemeHandler(QBAL("HostPortAndUserInformationSyntax"), this);
- profile->installUrlSchemeHandler(QBAL("redirect1"), this);
- profile->installUrlSchemeHandler(QBAL("redirect2"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect-secure"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect-local"), this);
profile->installUrlSchemeHandler(QBAL("cors"), this);
+ profile->installUrlSchemeHandler(QBAL("secure-cors"), this);
+ profile->installUrlSchemeHandler(QBAL("localaccess"), this);
profile->installUrlSchemeHandler(QBAL("local"), this);
+ profile->installUrlSchemeHandler(QBAL("local-localaccess"), this);
profile->installUrlSchemeHandler(QBAL("local-cors"), this);
}
@@ -190,18 +202,24 @@ private:
QUrl url = job->requestUrl();
m_requests << url;
- if (url.scheme() == QBAL("redirect1")) {
- url.setScheme(QBAL("redirect2"));
- job->redirect(url);
- return;
+ if (url.scheme().startsWith("redirect")) {
+ QString path = url.path();
+ int idx = path.indexOf(QChar('/'));
+ if (idx > 0) {
+ url.setScheme(path.first(idx));
+ url.setPath(path.mid(idx, -1));
+ job->redirect(url);
+ return;
+ }
}
QString pathPrefix = QDir(QT_TESTCASE_SOURCEDIR).canonicalPath();
if (url.path().startsWith("/qtwebchannel/"))
pathPrefix = QSL(":");
QString pathSuffix = url.path();
- QFile *file = new QFile(pathPrefix + pathSuffix, job);
+ auto file = std::make_unique<QFile>(pathPrefix + pathSuffix, job);
if (!file->open(QIODevice::ReadOnly)) {
+ qWarning() << "Failed to read data for:" << url << file->errorString();
job->fail(QWebEngineUrlRequestJob::RequestFailed);
return;
}
@@ -210,12 +228,69 @@ private:
mimeType = QBAL("application/javascript");
else if (pathSuffix.endsWith(QSL(".css")))
mimeType = QBAL("text/css");
- job->reply(mimeType, file);
+ job->reply(mimeType, file.release());
}
QList<QUrl> m_requests;
};
+class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ TestRequestInterceptor() = default;
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ qCDebug(lc) << this << "Type:" << info.resourceType() << info.requestMethod() << "Navigation:" << info.navigationType()
+ << info.requestUrl() << "Initiator:" << info.initiator();
+
+ QUrl url = info.requestUrl();
+ requests << url;
+ if (url.scheme().startsWith("redirect")) {
+ QString path = url.path();
+ int idx = path.indexOf(QChar('/'));
+ if (idx > 0) {
+ url.setScheme(path.first(idx));
+ url.setPath(path.mid(idx, -1));
+ info.redirect(url);
+ }
+ }
+ }
+ QList<QUrl> requests;
+};
+
+class TestPage : public QWebEnginePage
+{
+public:
+ TestPage(QWebEngineProfile *profile) : QWebEnginePage(profile, nullptr)
+ {
+ }
+ void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,
+ const QString &message, int,
+ const QString &) override
+ {
+ messages << message;
+ qCDebug(lc) << message;
+ }
+
+ bool logContainsDoneMarker() const { return messages.contains("TEST:done"); }
+
+ QString findResultInLog() const
+ {
+ // make sure we do not have some extra logs from blink
+ for (auto message : messages) {
+ QStringList s = message.split(':');
+ if (s.size() > 1 && s[0] == "TEST")
+ return s[1];
+ }
+ return QString();
+ }
+
+ void clearLog() { messages.clear(); }
+
+private:
+ QStringList messages;
+};
+
class tst_Origins final : public QObject {
Q_OBJECT
@@ -232,10 +307,17 @@ private Q_SLOTS:
void subdirWithoutAccess();
void fileAccessRemoteUrl_data();
void fileAccessRemoteUrl();
+ void fileAccessLocalUrl_data();
+ void fileAccessLocalUrl();
+ void mixedSchemes_data();
void mixedSchemes();
void mixedSchemesWithCsp();
void mixedXHR_data();
void mixedXHR();
+ void mixedContent_data();
+ void mixedContent();
+ void localMediaBlock_data();
+ void localMediaBlock();
#if defined(WEBSOCKETS)
void webSocket();
#endif
@@ -244,7 +326,17 @@ private Q_SLOTS:
void serviceWorker();
void viewSource();
void createObjectURL();
- void redirect();
+ void redirectScheme();
+ void redirectSchemeLocal();
+ void redirectSchemeSecure();
+ void redirectInterceptor();
+ void redirectInterceptorLocal();
+ void redirectInterceptorSecure();
+ void redirectInterceptorFile();
+ void redirectInterceptorHttp();
+ void fetchApiCustomUrl_data();
+ void fetchApiCustomUrl();
+ void fetchApiHttpUrl();
private:
bool verifyLoad(const QUrl &url)
@@ -261,7 +353,7 @@ private:
}
QWebEngineProfile m_profile;
- QWebEnginePage *m_page = nullptr;
+ TestPage *m_page = nullptr;
TstUrlSchemeHandler *m_handler = nullptr;
};
@@ -282,7 +374,7 @@ void tst_Origins::cleanupTestCase()
void tst_Origins::init()
{
- m_page = new QWebEnginePage(&m_profile, nullptr);
+ m_page = new TestPage(&m_profile);
}
void tst_Origins::cleanup()
@@ -382,8 +474,8 @@ void tst_Origins::jsUrlRelative()
// URLs even without an initial slash.
QCOMPARE(eval(QSL("new URL('bar', 'qrc:foo').href")), QVariant(QSL("qrc:bar")));
QCOMPARE(eval(QSL("new URL('baz', 'qrc:foo/bar').href")), QVariant(QSL("qrc:foo/baz")));
- QCOMPARE(eval(QSL("new URL('bar', 'qrc://foo').href")), QVariant());
- QCOMPARE(eval(QSL("new URL('bar', 'qrc:///foo').href")), QVariant());
+ QCOMPARE(eval(QSL("new URL('bar', 'qrc://foo').href")), QVariant(QSL("qrc://bar")));
+ QCOMPARE(eval(QSL("new URL('bar', 'qrc:///foo').href")), QVariant(QSL("qrc:///bar")));
// With a slash it works the same as http except 'foo' is part of the path and not the host.
QCOMPARE(eval(QSL("new URL('bar', 'qrc:/foo').href")), QVariant(QSL("qrc:/bar")));
@@ -500,8 +592,6 @@ void tst_Origins::subdirWithoutAccess()
{
ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, false);
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ "/resources/subdir/index.html"));
QCOMPARE(eval(QSL("msg[0]")), QVariant());
@@ -519,27 +609,112 @@ void tst_Origins::subdirWithoutAccess()
void tst_Origins::fileAccessRemoteUrl_data()
{
QTest::addColumn<bool>("EnableAccess");
- QTest::addRow("enabled") << true;
- QTest::addRow("disabled") << false;
+ QTest::addColumn<bool>("UserGesture");
+ QTest::addRow("enabled, XHR") << true << false;
+ QTest::addRow("enabled, link click") << true << true;
+ QTest::addRow("disabled, XHR") << false << false;
+ QTest::addRow("disabled, link click") << false << true;
}
void tst_Origins::fileAccessRemoteUrl()
{
QFETCH(bool, EnableAccess);
+ QFETCH(bool, UserGesture);
+
+ QWebEngineView view;
+ view.setPage(m_page);
+ view.resize(800, 600);
+ view.show();
HttpServer server;
server.setResourceDirs({ QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() + "/resources" });
QVERIFY(server.start());
- ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessRemoteUrls, EnableAccess);
- if (!EnableAccess)
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("blocked by CORS policy")));
+ ScopedAttribute sa1(m_page->settings(), QWebEngineSettings::LocalContentCanAccessRemoteUrls, EnableAccess);
+ ScopedAttribute sa2(m_page->settings(), QWebEngineSettings::ErrorPageEnabled, false);
- QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + "/resources/mixedXHR.html"));
+ if (UserGesture) {
+ QString remoteUrl(server.url("/link.html").toString());
+#ifdef Q_OS_WIN
+ QString localUrl("file:///" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/link.html?linkLocation=" + remoteUrl);
+#else
+ QString localUrl("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/link.html?linkLocation=" + remoteUrl);
+#endif
+
+ QVERIFY(verifyLoad(localUrl));
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
+ // Succeed independently of EnableAccess == false
+ QTRY_COMPARE(m_page->url(), remoteUrl);
+
+ // Back/forward navigation is also allowed, however they are not user gesture
+ m_page->triggerAction(QWebEnginePage::Back);
+ QTRY_COMPARE(m_page->url(), localUrl);
+ m_page->triggerAction(QWebEnginePage::Forward);
+ QTRY_COMPARE(m_page->url(), remoteUrl);
+ } else {
+ QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/mixedXHR.html"));
+ eval("sendXHR('" + server.url("/mixedXHR.txt").toString() + "')");
+ QTRY_COMPARE(eval("result"), (EnableAccess ? QString("ok") : QString("error")));
+ }
+}
+
+void tst_Origins::fileAccessLocalUrl_data()
+{
+ QTest::addColumn<bool>("EnableAccess");
+ QTest::addColumn<bool>("UserGesture");
+ QTest::addRow("enabled, XHR") << true << false;
+ QTest::addRow("enabled, link click") << true << true;
+ QTest::addRow("disabled, XHR") << false << false;
+ QTest::addRow("disabled, link click") << false << true;
+}
+
+void tst_Origins::fileAccessLocalUrl()
+{
+ QFETCH(bool, EnableAccess);
+ QFETCH(bool, UserGesture);
+
+ QWebEngineView view;
+ view.setPage(m_page);
+ view.resize(800, 600);
+ view.show();
+
+ ScopedAttribute sa1(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, EnableAccess);
+ ScopedAttribute sa2(m_page->settings(), QWebEngineSettings::ErrorPageEnabled, false);
+
+ if (UserGesture) {
+#ifdef Q_OS_WIN
+ QString localUrl1("file:///" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/link.html?linkLocation=link.html");
+ QString localUrl2("file:///" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/link.html");
+#else
+ QString localUrl1("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/link.html?linkLocation=link.html");
+ QString localUrl2("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/link.html");
+#endif
- eval("sendXHR('" + server.url("/mixedXHR.txt").toString() + "')");
- QTRY_COMPARE(eval("result"), (EnableAccess ? QString("ok") : QString("error")));
+ QVERIFY(verifyLoad(localUrl1));
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
+ // Succeed independently of EnableAccess == false
+ QTRY_COMPARE(m_page->url(), localUrl2);
+
+ // Back/forward navigation is also allowed, however they are not user gesture
+ m_page->triggerAction(QWebEnginePage::Back);
+ QTRY_COMPARE(m_page->url(), localUrl1);
+ m_page->triggerAction(QWebEnginePage::Forward);
+ QTRY_COMPARE(m_page->url(), localUrl2);
+ } else {
+ QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/mixedXHR.html"));
+ eval("sendXHR('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/mixedXHR.txt" + "')");
+ QTRY_COMPARE(eval("result"), (EnableAccess ? QString("ok") : QString("error")));
+ }
}
// Load the main page over one scheme with an iframe over another scheme.
@@ -550,105 +725,149 @@ void tst_Origins::fileAccessRemoteUrl()
// Additionally for unregistered custom schemes and custom schemes without
// LocalAccessAllowed it should not be possible to load an iframe over the
// file: scheme.
-void tst_Origins::mixedSchemes()
+void tst_Origins::mixedSchemes_data()
{
- QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + "/resources/mixedSchemes.html"));
- eval("setIFrameUrl('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + "/resources/mixedSchemes_frame.html')");
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::addColumn<QString>("schemeFrom");
+ QTest::addColumn<QVariantMap>("testPairs");
- QVERIFY(verifyLoad(QSL("qrc:/resources/mixedSchemes.html")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
- eval("setIFrameUrl('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + "/resources/mixedSchemes_frame.html')");
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
- eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QVariant SLF = QVariant(QSL("canLoadAndAccess")), OK = QVariant(QSL("canLoadButNotAccess")),
+ ERR = QVariant(QSL("cannotLoad"));
+ std::vector<std::pair<const char *, std::vector<std::pair<const char *, QVariant>>>> data = {
+ { "file",
+ {
+ { "file", SLF },
+ { "qrc", OK },
+ { "tst", ERR },
+ } },
+ { "qrc",
+ {
+ { "file", ERR },
+ { "qrc", SLF },
+ { "tst", OK },
+ } },
+ { "tst",
+ {
+ { "file", ERR },
+ { "qrc", OK },
+ { "tst", SLF },
+ } },
+ { "PathSyntax",
+ {
+ { "PathSyntax", SLF },
+ { "PathSyntax-Local", ERR },
+ { "PathSyntax-LocalAccessAllowed", OK },
+ { "PathSyntax-NoAccessAllowed", OK },
+ } },
+ { "PathSyntax-LocalAccessAllowed",
+ {
+ { "PathSyntax", OK },
+ { "PathSyntax-Local", OK },
+ { "PathSyntax-LocalAccessAllowed", SLF },
+ { "PathSyntax-NoAccessAllowed", OK },
+ } },
+ { "PathSyntax-NoAccessAllowed",
+ {
+ { "PathSyntax", OK },
+ { "PathSyntax-Local", ERR },
+ { "PathSyntax-LocalAccessAllowed", OK },
+ { "PathSyntax-NoAccessAllowed", OK },
+ } },
+ { "HostSyntax://a",
+ {
+ { "HostSyntax://a", SLF },
+ { "HostSyntax://b", OK },
+ } },
+ { "local-localaccess",
+ {
+ { "local-cors", OK },
+ { "local-localaccess", SLF },
+ { "local", OK },
+ } },
+ { "local-cors",
+ {
+ { "local", OK },
+ { "local-cors", SLF },
+ } },
+ };
- QVERIFY(verifyLoad(QSL("tst:/resources/mixedSchemes.html")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
- eval("setIFrameUrl('file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
- + "/resources/mixedSchemes_frame.html')");
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ for (auto &&d : data) {
+ auto schemeFrom = d.first;
+ QVariantMap testPairs;
+ for (auto &&destSchemes : d.second) {
+ auto &&destScheme = destSchemes.first;
+ testPairs[destScheme] = destSchemes.second;
+ }
+ QTest::addRow("%s", schemeFrom) << schemeFrom << testPairs;
+ }
+}
- QVERIFY(verifyLoad(QSL("PathSyntax:/resources/mixedSchemes.html")));
- eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
- eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
- eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')"));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+static QStringList protocolAndHost(const QString scheme)
+{
+ static QString srcDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath());
+ QStringList result;
+ if (scheme == QSL("file")) {
+ return QStringList{ scheme, srcDir };
+ }
+ if (scheme.contains(QSL("HostSyntax:"))) {
+ const QStringList &res = scheme.split(':');
+ Q_ASSERT(res.size() == 2);
+ return res;
+ }
+ return QStringList{ scheme, "" };
+}
- QVERIFY(verifyLoad(QSL("PathSyntax-LocalAccessAllowed:/resources/mixedSchemes.html")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+void tst_Origins::mixedSchemes()
+{
+ QFETCH(QString, schemeFrom);
+ QFETCH(QVariantMap, testPairs);
- QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/mixedSchemes.html")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
- eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ ScopedAttribute sa(m_page->settings(), QWebEngineSettings::ErrorPageEnabled, false);
+ QString srcDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath());
+ QString host;
+ auto pah = protocolAndHost(schemeFrom);
+ auto loadUrl = QString("%1:%2/resources/mixedSchemes.html").arg(pah[0]).arg(pah[1]);
+ QVERIFY(verifyLoad(loadUrl));
- QVERIFY(verifyLoad(QSL("HostSyntax://a/resources/mixedSchemes.html")));
- eval(QSL("setIFrameUrl('HostSyntax://a/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
- eval(QSL("setIFrameUrl('HostSyntax://b/resources/mixedSchemes_frame.html')"));
- QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QStringList schemesTo, expected, results;
+ for (auto it = testPairs.begin(), end = testPairs.end(); it != end; ++it) {
+
+ auto schemeTo = it.key();
+ auto pah = protocolAndHost(schemeTo);
+ auto expectedResult = it.value().toString();
+ auto frameUrl = QString("%1:%2/resources/mixedSchemes_frame.html").arg(pah[0]).arg(pah[1]);
+ auto imgUrl = QString("%1:%2/resources/red.png").arg(pah[0]).arg(pah[1]);
+
+ eval(QString("setIFrameUrl('%1','%2')").arg(frameUrl).arg(imgUrl));
+
+ // wait for token in the log
+ QTRY_VERIFY(m_page->logContainsDoneMarker());
+ const QString result = m_page->findResultInLog();
+ m_page->clearLog();
+ schemesTo.append(schemeTo.rightJustified(20));
+ results.append(result.rightJustified(20));
+ expected.append(expectedResult.rightJustified(20));
+ }
+
+ QVERIFY2(results == expected,
+ qPrintable(QString("\nFrom '%1' to:\n\tScheme: %2\n\tActual: %3\n\tExpect: %4")
+ .arg(schemeFrom)
+ .arg(schemesTo.join(' '))
+ .arg(results.join(' '))
+ .arg(expected.join(' '))));
}
// Like mixedSchemes but adds a Content-Security-Policy: frame-src 'none' header.
void tst_Origins::mixedSchemesWithCsp()
{
QVERIFY(verifyLoad(QSL("HostSyntax://a/resources/mixedSchemesWithCsp.html")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("violates the following Content Security Policy")));
eval(QSL("setIFrameUrl('HostSyntax://a/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("violates the following Content Security Policy")));
eval(QSL("setIFrameUrl('HostSyntax://b/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("HostSyntax-ContentSecurityPolicyIgnored://a/resources/mixedSchemesWithCsp.html")));
eval(QSL("setIFrameUrl('HostSyntax-ContentSecurityPolicyIgnored://a/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
- QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('HostSyntax-ContentSecurityPolicyIgnored://b/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
}
@@ -682,55 +901,90 @@ void tst_Origins::mixedXHR_data()
std::pair<const char *, std::vector<
std::pair<const char *, std::vector<QVariant>>>>> data = {
{ "file", {
- { "file", { OK, OK, ERR, OK } },
- { "qrc", { ERR, ERR, ERR, ERR } },
- { "tst", { ERR, ERR, ERR, ERR } },
- { "data", { OK, OK, OK, OK } },
- { "cors", { ERR, OK, ERR, OK } },
- { "local", { ERR, ERR, ERR, ERR } },
- { "local-cors", { OK, OK, OK, OK } }, } },
+ { "file", { OK, OK, ERR, ERR } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, ERR, ERR } },
+ { "local-cors", { OK, OK, ERR, ERR } }, } },
{ "qrc", {
- { "file", { ERR, ERR, ERR, ERR } },
- { "qrc", { OK, OK, OK, OK } },
- { "tst", { ERR, ERR, ERR, ERR } },
- { "data", { OK, OK, OK, OK } },
- { "cors", { OK, OK, OK, OK } },
- { "local", { ERR, ERR, ERR, ERR } },
- { "local-cors", { ERR, ERR, ERR, ERR } }, } },
+ { "file", { ERR, ERR, ERR, ERR } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { ERR, ERR, ERR, ERR } },
+ { "local-cors", { ERR, ERR, ERR, ERR } }, } },
{ "tst", {
- { "file", { ERR, ERR, ERR, ERR } },
- { "qrc", { ERR, ERR, ERR, ERR } },
- { "tst", { OK, OK, OK, OK } },
- { "data", { OK, OK, OK, OK } },
- { "cors", { OK, OK, OK, OK } },
- { "local", { ERR, ERR, ERR, ERR } },
- { "local-cors", { ERR, ERR, ERR, ERR } }, } },
-
- { "local", {
- { "file", { ERR, ERR, ERR, ERR } },
- { "qrc", { ERR, ERR, ERR, ERR } },
- { "tst", { ERR, ERR, ERR, ERR } },
- { "data", { OK, OK, OK, OK } },
- { "cors", { ERR, OK, ERR, OK } },
- { "local", { OK, OK, ERR, OK } },
- { "local-cors", { OK, OK, OK, OK } }, } },
+ { "file", { ERR, ERR, ERR, ERR } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { OK, OK, OK, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { ERR, ERR, ERR, ERR } },
+ { "local-cors", { ERR, ERR, ERR, ERR } }, } },
+
+ { "cors", { // -local +cors -local-access
+ { "file", { ERR, ERR, ERR, ERR } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { ERR, ERR, ERR, ERR } },
+ { "local-cors", { ERR, ERR, ERR, ERR } }, } },
+
+ { "local", { // +local -cors -local-access
+ { "file", { OK, OK, ERR, ERR } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, ERR, ERR } },
+ { "local-cors", { OK, OK, ERR, ERR } }, } },
+
+ { "local-cors", { // +local +cors -local-access
+ { "file", { OK, OK, ERR, ERR } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, ERR, ERR } },
+ { "local-cors", { OK, OK, ERR, ERR } }, } },
+
+ { "local-localaccess", { // +local -cors +local-access
+ { "file", { OK, OK, OK, OK } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, OK, OK } },
+ { "local-cors", { OK, OK, OK, OK } }, } },
+
+ { "localaccess", { // -local -cors +local-access
+ { "file", { OK, OK, OK, OK } },
+ { "qrc", { ERR, ERR, ERR, ERR } },
+ { "tst", { ERR, ERR, ERR, ERR } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { OK, OK, OK, OK } },
+ { "local-cors", { OK, OK, OK, OK } }, } },
};
for (auto &&d : data) {
auto schemeFrom = d.first;
for (int i = 0; i < 4; ++i) {
- auto it = settingCombinations.begin() + i;
- bool canAccessFileUrls = it->first, canAccessRemoteUrl = it->second;
+ const auto &it = settingCombinations[i];
+ bool canAccessFileUrls = it.first, canAccessRemoteUrl = it.second;
QVariantMap testPairs;
for (auto &&destSchemes : d.second) {
auto &&destScheme = destSchemes.first;
auto &&expectedResults = destSchemes.second;
- auto rit = expectedResults.begin() + i;
- testPairs[destScheme] = *rit;
+ testPairs[destScheme] = expectedResults[i];
}
QTest::addRow("%s_%s_%s", schemeFrom, (canAccessFileUrls ? "local" : "nolocal"), (canAccessRemoteUrl ? "remote" : "noremote"))
@@ -779,6 +1033,174 @@ void tst_Origins::mixedXHR()
.arg(schemeFrom).arg(schemesTo.join(' ')).arg(results.join(' ')).arg(expected.join(' '))));
}
+// Load the main page over one scheme, then load an iframe over a different scheme. This load is not considered CORS.
+void tst_Origins::mixedContent_data()
+{
+ QTest::addColumn<QString>("schemeFrom");
+ QTest::addColumn<bool>("canAccessFileUrls");
+ QTest::addColumn<bool>("canAccessRemoteUrl");
+ QTest::addColumn<QVariantMap>("testPairs");
+
+ bool defaultFileAccess = true;
+ bool defaultRemoteAccess = false;
+ std::vector<std::pair<bool, bool>> settingCombinations = {
+ { defaultFileAccess, defaultRemoteAccess }, // tag: *schemeFrom*_local_noremote
+ { defaultFileAccess, !defaultRemoteAccess }, // tag: *schemeFrom*_local_remote
+ { !defaultFileAccess, defaultRemoteAccess }, // tag: *schemeFrom*_nolocal_noremote
+ { !defaultFileAccess, !defaultRemoteAccess } // tag: *schemeFrom*_nolocal_remote
+ };
+
+ QVariant SLF = QVariant(QSL("canLoadAndAccess")), OK = QVariant(QSL("canLoadButNotAccess")), ERR = QVariant(QSL("cannotLoad"));
+ std::vector<
+ std::pair<const char *, std::vector<
+ std::pair<const char *, std::vector<QVariant>>>>> data = {
+ { "file", {
+ { "file", { SLF, SLF, ERR, ERR } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { ERR, OK, ERR, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, ERR, ERR } },
+ { "local-cors", { OK, OK, ERR, ERR } },
+ } },
+
+ { "qrc", {
+ { "file", { ERR, ERR, ERR, ERR } },
+ { "qrc", { SLF, SLF, SLF, SLF } },
+ { "tst", { OK, OK, OK, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { ERR, ERR, ERR, ERR } },
+ { "local-cors", { ERR, ERR, ERR, ERR } }, } },
+
+ { "tst", {
+ { "file", { ERR, ERR, ERR, ERR } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { SLF, SLF, SLF, SLF } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { ERR, ERR, ERR, ERR } },
+ { "local-cors", { ERR, ERR, ERR, ERR } }, } },
+
+ { "cors", { // -local +cors -local-access
+ { "file", { ERR, ERR, ERR, ERR } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { OK, OK, OK, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { SLF, SLF, SLF, SLF } },
+ { "local-localaccess", { ERR, ERR, ERR, ERR } },
+ { "local-cors", { ERR, ERR, ERR, ERR } }, } },
+
+ { "local", { // +local -cors -local-access
+ { "file", { OK, OK, ERR, ERR } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { ERR, OK, ERR, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, ERR, ERR } },
+ { "local-cors", { OK, OK, ERR, ERR } },
+ } },
+
+ { "local-cors", { // +local +cors -local-access
+ { "file", { OK, OK, ERR, ERR } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { ERR, OK, ERR, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { OK, OK, ERR, ERR } },
+ { "local-cors", { SLF, SLF, ERR, ERR } },
+ } },
+
+ { "local-localaccess", { // +local -cors + OK-access
+ { "file", { OK, OK, OK, OK } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { ERR, OK, ERR, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { ERR, OK, ERR, OK } },
+ { "local-localaccess", { SLF, SLF, OK, OK } }, // ### should probably be: SLF, SLF, SLF, SLF
+ { "local-cors", { OK, OK, OK, OK } },
+ } },
+
+ { "localaccess", { // -local -cors +local-access
+ { "file", { OK, OK, OK, OK } },
+ { "qrc", { OK, OK, OK, OK } },
+ { "tst", { OK, OK, OK, OK } },
+ { "data", { OK, OK, OK, OK } },
+ { "cors", { OK, OK, OK, OK } },
+ { "local-localaccess", { OK, OK, OK, OK } },
+ { "local-cors", { OK, OK, OK, OK } }, } },
+ };
+
+ for (auto &&d : data) {
+ auto schemeFrom = d.first;
+
+ for (int i = 0; i < 4; ++i) {
+ const auto &it = settingCombinations[i];
+ bool canAccessFileUrls = it.first, canAccessRemoteUrl = it.second;
+
+ QVariantMap testPairs;
+ for (auto &&destSchemes : d.second) {
+ auto &&destScheme = destSchemes.first;
+ auto &&expectedResults = destSchemes.second;
+ testPairs[destScheme] = expectedResults[i];
+ }
+
+ QTest::addRow("%s_%s_%s", schemeFrom, (canAccessFileUrls ? "local" : "nolocal"), (canAccessRemoteUrl ? "remote" : "noremote"))
+ << schemeFrom << canAccessFileUrls << canAccessRemoteUrl << testPairs;
+ }
+ }
+}
+
+void tst_Origins::mixedContent()
+{
+ QFETCH(QString, schemeFrom);
+ QFETCH(bool, canAccessFileUrls);
+ QFETCH(bool, canAccessRemoteUrl);
+ QFETCH(QVariantMap, testPairs);
+
+ QString srcDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath());
+ auto loadUrl = QString("%1:%2/resources/mixedSchemes.html").arg(schemeFrom).arg(schemeFrom == "file" ? srcDir : "");
+
+ QCOMPARE(testPairs.size(), 7);
+ ScopedAttribute sa2(m_page->settings(), QWebEngineSettings::ErrorPageEnabled, false);
+ ScopedAttribute sa0(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, canAccessFileUrls);
+ ScopedAttribute sa1(m_page->settings(), QWebEngineSettings::LocalContentCanAccessRemoteUrls, canAccessRemoteUrl);
+ QVERIFY(verifyLoad(loadUrl));
+
+ auto setIFrameUrl = [&] (const QString &scheme) {
+ if (scheme == "data")
+ return QString("setIFrameUrl('data:,<script>var canary = true; parent.canary = "
+ "true</script>','data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA"
+ "AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/"
+ "w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==')");
+ auto frameUrl = QString("%1:%2/resources/mixedSchemes_frame.html").arg(scheme).arg(scheme == "file" ? srcDir : "");
+ auto imgUrl =
+ QString("%1:%2/resources/red.png").arg(scheme).arg(scheme == "file" ? srcDir : "");
+ return QString("setIFrameUrl('%1','%2')").arg(frameUrl).arg(imgUrl);
+ };
+
+ m_page->clearLog();
+ QStringList schemesTo, expected, results;
+ for (auto it = testPairs.begin(), end = testPairs.end(); it != end; ++it) {
+
+ auto schemeTo = it.key();
+ auto expectedResult = it.value().toString();
+
+ eval(setIFrameUrl(schemeTo));
+
+ // wait for token in the log
+ QTRY_VERIFY(m_page->logContainsDoneMarker());
+ const QString result = m_page->findResultInLog();
+ m_page->clearLog();
+ schemesTo.append(schemeTo.rightJustified(20));
+ results.append(result.rightJustified(20));
+ expected.append(expectedResult.rightJustified(20));
+ }
+ QVERIFY2(results == expected,
+ qPrintable(QString("\nFrom '%1' to:\n\tScheme: %2\n\tActual: %3\n\tExpect: %4")
+ .arg(schemeFrom).arg(schemesTo.join(' ')).arg(results.join(' ')).arg(expected.join(' '))));
+}
+
#if defined(WEBSOCKETS)
class EchoServer : public QObject {
Q_OBJECT
@@ -932,12 +1354,12 @@ void tst_Origins::serviceWorker()
QVERIFY(verifyLoad(QSL("tst:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("Cannot read property 'register' of undefined")));
+ .contains(QSL("Cannot read properties of undefined")));
QVERIFY(verifyLoad(QSL("PathSyntax:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("Cannot read property 'register' of undefined")));
+ .contains(QSL("Cannot read properties of undefined")));
QVERIFY(verifyLoad(QSL("PathSyntax-Secure:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
@@ -947,7 +1369,7 @@ void tst_Origins::serviceWorker()
QVERIFY(verifyLoad(QSL("PathSyntax-ServiceWorkersAllowed:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("Cannot read property 'register' of undefined")));
+ .contains(QSL("Cannot read properties of undefined")));
QVERIFY(verifyLoad(QSL("PathSyntax-Secure-ServiceWorkersAllowed:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
@@ -956,7 +1378,7 @@ void tst_Origins::serviceWorker()
QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("Cannot read property 'register' of undefined")));
+ .contains(QSL("Cannot read properties of undefined")));
}
// Support for view-source must be enabled explicitly.
@@ -998,17 +1420,310 @@ void tst_Origins::createObjectURL()
QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:")));
}
-void tst_Origins::redirect()
+void tst_Origins::redirectScheme()
+{
+ QVERIFY(verifyLoad(QSL("redirect:cors/resources/redirect.html")));
+ eval("addStylesheetLink('redirect:cors/resources/redirect.css')");
+ QTRY_COMPARE(m_handler->requests().size(), 4);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect:cors/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("cors:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect:cors/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("cors:/resources/redirect.css")));
+
+ QVERIFY(!verifyLoad(QSL("redirect:file/resources/redirect.html")));
+ QVERIFY(!verifyLoad(QSL("redirect:local/resources/redirect.html")));
+ QVERIFY(!verifyLoad(QSL("redirect:local-cors/resources/redirect.html")));
+}
+
+void tst_Origins::redirectSchemeLocal()
+{
+ QVERIFY(verifyLoad(QSL("redirect-local:local/resources/redirect.html")));
+ eval("addStylesheetLink('redirect-local:local/resources/redirect.css')");
+ QTRY_COMPARE(m_handler->requests().size(), 4);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect-local:local/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("local:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect-local:local/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("local:/resources/redirect.css")));
+}
+
+void tst_Origins::redirectSchemeSecure()
+{
+ QVERIFY(verifyLoad(QSL("redirect-secure:secure-cors/resources/redirect.html")));
+ eval("addStylesheetLink('redirect-secure:secure-cors/resources/redirect.css')");
+ QTRY_COMPARE(m_handler->requests().size(), 4);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect-secure:secure-cors/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("secure-cors:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect-secure:secure-cors/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("secure-cors:/resources/redirect.css")));
+}
+
+void tst_Origins::redirectInterceptor()
+{
+ TestRequestInterceptor interceptor;
+ m_profile.setUrlRequestInterceptor(&interceptor);
+
+ QVERIFY(verifyLoad(QSL("redirect:cors/resources/redirect.html")));
+ eval("addStylesheetLink('redirect:cors/resources/redirect.css')");
+
+ QTRY_COMPARE(interceptor.requests.size(), 4);
+ QTRY_COMPARE(m_handler->requests().size(), 2);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("cors:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("cors:/resources/redirect.css")));
+
+ QCOMPARE(interceptor.requests[0], QUrl(QStringLiteral("redirect:cors/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[1], QUrl(QStringLiteral("cors:/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[2], QUrl(QStringLiteral("redirect:cors/resources/redirect.css")));
+ QCOMPARE(interceptor.requests[3], QUrl(QStringLiteral("cors:/resources/redirect.css")));
+
+ QVERIFY(!verifyLoad(QSL("redirect:file/resources/redirect.html")));
+ QVERIFY(!verifyLoad(QSL("redirect:local/resources/redirect.html")));
+ QVERIFY(!verifyLoad(QSL("redirect:local-cors/resources/redirect.html")));
+}
+
+void tst_Origins::redirectInterceptorLocal()
+{
+ TestRequestInterceptor interceptor;
+ m_profile.setUrlRequestInterceptor(&interceptor);
+
+ QVERIFY(verifyLoad(QSL("redirect-local:local/resources/redirect.html")));
+ eval("addStylesheetLink('redirect-local:local/resources/redirect.css')");
+
+ QTRY_COMPARE(interceptor.requests.size(), 4);
+ QTRY_COMPARE(m_handler->requests().size(), 2);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("local:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("local:/resources/redirect.css")));
+
+ QCOMPARE(interceptor.requests[0], QUrl(QStringLiteral("redirect-local:local/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[1], QUrl(QStringLiteral("local:/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[2], QUrl(QStringLiteral("redirect-local:local/resources/redirect.css")));
+ QCOMPARE(interceptor.requests[3], QUrl(QStringLiteral("local:/resources/redirect.css")));
+}
+
+void tst_Origins::redirectInterceptorSecure()
{
- QVERIFY(verifyLoad(QSL("redirect1:/resources/redirect.html")));
- QTRY_COMPARE(m_handler->requests().size(), 7);
- QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect1:/resources/redirect.html")));
- QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("redirect2:/resources/redirect.html")));
- QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect1:/resources/redirect.css")));
- QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("redirect2:/resources/redirect.css")));
- QCOMPARE(m_handler->requests()[4], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2")));
- QCOMPARE(m_handler->requests()[5], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2")));
- QCOMPARE(m_handler->requests()[6], QUrl(QStringLiteral("redirect2:/resources/Akronim-Regular.woff2")));
+ TestRequestInterceptor interceptor;
+ m_profile.setUrlRequestInterceptor(&interceptor);
+
+ QVERIFY(verifyLoad(QSL("redirect-secure:secure-cors/resources/redirect.html")));
+ eval("addStylesheetLink('redirect-secure:secure-cors/resources/redirect.css')");
+
+ QTRY_COMPARE(interceptor.requests.size(), 4);
+ QTRY_COMPARE(m_handler->requests().size(), 2);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("secure-cors:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("secure-cors:/resources/redirect.css")));
+
+ QCOMPARE(interceptor.requests[0], QUrl(QStringLiteral("redirect-secure:secure-cors/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[1], QUrl(QStringLiteral("secure-cors:/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[2], QUrl(QStringLiteral("redirect-secure:secure-cors/resources/redirect.css")));
+ QCOMPARE(interceptor.requests[3], QUrl(QStringLiteral("secure-cors:/resources/redirect.css")));
+}
+
+class TestRedirectInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ TestRedirectInterceptor() = default;
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ qCDebug(lc) << this << "Type:" << info.resourceType() << info.requestMethod() << "Navigation:" << info.navigationType()
+ << info.requestUrl() << "Initiator:" << info.initiator();
+
+ QUrl url = info.requestUrl();
+ requests << url;
+ if (url.path().startsWith("/redirect")) {
+ QString path = url.path();
+ int idx = path.indexOf(QChar('/'), 10);
+ if (idx > 0) {
+ url.setScheme(path.mid(10, idx - 10));
+ url.setPath(path.mid(idx, -1));
+ url.setHost({});
+ info.redirect(url);
+ }
+ }
+ }
+ QList<QUrl> requests;
+};
+
+void tst_Origins::redirectInterceptorFile()
+{
+ TestRedirectInterceptor interceptor;
+ m_profile.setUrlRequestInterceptor(&interceptor);
+
+ QVERIFY(verifyLoad(QSL("file:///redirect/local-cors/resources/redirect.html")));
+ eval("addStylesheetLink('file:///redirect/local-cors/resources/redirect.css')");
+
+ QTRY_COMPARE(interceptor.requests.size(), 4);
+ QTRY_COMPARE(m_handler->requests().size(), 2);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("local-cors:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("local-cors:/resources/redirect.css")));
+
+ QCOMPARE(interceptor.requests[0], QUrl(QStringLiteral("file:///redirect/local-cors/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[1], QUrl(QStringLiteral("local-cors:/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[2], QUrl(QStringLiteral("file:///redirect/local-cors/resources/redirect.css")));
+ QCOMPARE(interceptor.requests[3], QUrl(QStringLiteral("local-cors:/resources/redirect.css")));
+}
+
+void tst_Origins::redirectInterceptorHttp()
+{
+ TestRedirectInterceptor interceptor;
+ m_profile.setUrlRequestInterceptor(&interceptor);
+
+ QVERIFY(verifyLoad(QSL("http://hallo/redirect/cors/resources/redirect.html")));
+ eval("addStylesheetLink('http://hallo/redirect/cors/resources/redirect.css')");
+
+ QTRY_COMPARE(interceptor.requests.size(), 4);
+ QTRY_COMPARE(m_handler->requests().size(), 2);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("cors:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("cors:/resources/redirect.css")));
+
+ QCOMPARE(interceptor.requests[0], QUrl(QStringLiteral("http://hallo/redirect/cors/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[1], QUrl(QStringLiteral("cors:/resources/redirect.html")));
+ QCOMPARE(interceptor.requests[2], QUrl(QStringLiteral("http://hallo/redirect/cors/resources/redirect.css")));
+ QCOMPARE(interceptor.requests[3], QUrl(QStringLiteral("cors:/resources/redirect.css")));
+}
+
+void tst_Origins::localMediaBlock_data()
+{
+ QTest::addColumn<bool>("enableAccess");
+ QTest::addRow("enabled") << true;
+ QTest::addRow("disabled") << false;
+}
+
+void tst_Origins::localMediaBlock()
+{
+ QFETCH(bool, enableAccess);
+
+ std::atomic<bool> accessed = false;
+ HttpServer server;
+ server.setResourceDirs({ QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() + "/resources" });
+ connect(&server, &HttpServer::newRequest, [&](HttpReqRep *) { accessed.store(true); });
+ QVERIFY(server.start());
+
+ ScopedAttribute sa1(m_page->settings(), QWebEngineSettings::LocalContentCanAccessRemoteUrls, enableAccess);
+
+ QVERIFY(verifyLoad("file:" + QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + "/resources/media.html"));
+ eval("addAudio('" + server.url("/mixedXHR.txt").toString() + "')");
+
+ // Give it a chance to avoid a false positive on the default value of accessed.
+ if (!enableAccess)
+ QTest::qSleep(500);
+ QTRY_COMPARE(accessed.load(), enableAccess);
+
+}
+
+class FetchApiHandler : public QWebEngineUrlSchemeHandler
+{
+ Q_OBJECT
+public:
+ FetchApiHandler(QByteArray schemeName, QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent), m_schemeName(schemeName)
+ {
+ }
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QCOMPARE(job->requestUrl(), QUrl(m_schemeName + ":about"));
+ fetchWasAllowed = true;
+ }
+
+ bool fetchWasAllowed = false;
+
+private:
+ QByteArray m_schemeName;
+};
+
+class FetchApiPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+signals:
+ void jsCalled();
+
+public:
+ FetchApiPage(QWebEngineProfile *profile, QObject *parent = nullptr)
+ : QWebEnginePage(profile, parent)
+ {
+ }
+
+protected:
+ void javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel,
+ const QString &message, int, const QString &) override
+ {
+ qCritical() << "js:" << message;
+ emit jsCalled();
+ }
+};
+
+void tst_Origins::fetchApiCustomUrl_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QByteArray>("fetchApiScheme");
+ QTest::addColumn<bool>("expectedFetchWasAllowed");
+
+ QTest::newRow("custom url with fetch allowed flag")
+ << QUrl("qrc:///resources/fetchApi.html?printRes=false&url=fetchapi-allowed:about")
+ << QBAL("fetchapi-allowed") << true;
+ QTest::newRow("custom url without fetch allowed flag")
+ << QUrl("qrc:///resources/fetchApi.html?printRes=false&url=fetchapi-not-allowed:about")
+ << QBAL("fetchapi-not-allowed") << false;
+}
+
+void tst_Origins::fetchApiCustomUrl()
+{
+ QFETCH(QUrl, url);
+ QFETCH(QByteArray, fetchApiScheme);
+ QFETCH(bool, expectedFetchWasAllowed);
+
+ QWebEngineProfile profile;
+ FetchApiHandler handler(fetchApiScheme);
+
+ profile.installUrlSchemeHandler(fetchApiScheme, &handler);
+
+ FetchApiPage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy jsSpy(&page, SIGNAL(jsCalled()));
+
+ if (fetchApiScheme == "fetchapi-not-allowed") {
+ QTest::ignoreMessage(QtCriticalMsg, QRegularExpression("Failed to fetch"));
+ QTest::ignoreMessage(
+ QtCriticalMsg,
+ QRegularExpression("Fetch API cannot load fetchapi-not-allowed:about."));
+ }
+
+ page.load(url);
+ QTRY_VERIFY(loadSpy.count() > 0);
+ QTRY_COMPARE(handler.fetchWasAllowed, expectedFetchWasAllowed);
+
+ if (fetchApiScheme == "fetchapi-not-allowed") {
+ QTRY_VERIFY(jsSpy.count() > 0);
+ }
+}
+
+void tst_Origins::fetchApiHttpUrl()
+{
+ HttpServer httpServer;
+ QObject::connect(&httpServer, &HttpServer::newRequest, this, [](HttpReqRep *rr) {
+ rr->setResponseBody(QBAL("Fetch Was Allowed"));
+ rr->setResponseHeader(QBAL("Access-Control-Allow-Origin"), QBAL("*"));
+ rr->sendResponse();
+ });
+ QVERIFY(httpServer.start());
+
+ QWebEngineProfile profile;
+ FetchApiPage page(&profile);
+
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy jsSpy(&page, SIGNAL(jsCalled()));
+
+ QTest::ignoreMessage(QtCriticalMsg, QRegularExpression("Fetch Was Allowed"));
+
+ const QByteArray fullUrl = QByteArray("qrc:///resources/fetchApi.html?printRes=true&url=")
+ + httpServer.url("/somepage.html").toEncoded();
+ page.load(QUrl(fullUrl));
+
+ QTRY_VERIFY(loadSpy.count() > 0);
+ QTRY_VERIFY(jsSpy.count() > 0);
+ QVERIFY(httpServer.stop());
}
QTEST_MAIN(tst_Origins)
diff --git a/tests/auto/core/qtversion/CMakeLists.txt b/tests/auto/core/qtversion/CMakeLists.txt
new file mode 100644
index 000000000..9a5e89266
--- /dev/null
+++ b/tests/auto/core/qtversion/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_test(tst_qtversion
+ SOURCES
+ tst_qtversion.cpp
+ LIBRARIES
+ Qt::WebEngineCore
+)
+
diff --git a/tests/auto/core/qtversion/tst_qtversion.cpp b/tests/auto/core/qtversion/tst_qtversion.cpp
new file mode 100644
index 000000000..44c2d4e5c
--- /dev/null
+++ b/tests/auto/core/qtversion/tst_qtversion.cpp
@@ -0,0 +1,34 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebenginepage.h>
+
+class tst_QtVersion : public QObject
+{
+ Q_OBJECT
+signals:
+ void done();
+private Q_SLOTS:
+ void checkVersion();
+};
+
+void tst_QtVersion::checkVersion()
+{
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy doneSpy(this, &tst_QtVersion::done);
+ page.load(QUrl("chrome://qt"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 12000);
+ page.toPlainText([this](const QString &result) {
+ QVERIFY(result.contains(qWebEngineVersion()));
+ QVERIFY(result.contains(qWebEngineChromiumVersion()));
+ QVERIFY(result.contains(qWebEngineChromiumSecurityPatchVersion()));
+ emit done();
+ });
+ QTRY_VERIFY(doneSpy.size());
+}
+
+QTEST_MAIN(tst_QtVersion)
+
+#include "tst_qtversion.moc"
diff --git a/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt b/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt
index fa2d5e538..8cee7f630 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt
+++ b/tests/auto/core/qwebengineclientcertificatestore/CMakeLists.txt
@@ -1,8 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../httpserver/httpserver.cmake)
+include(../../util/util.cmake)
+
qt_internal_add_test(tst_qwebengineclientcertificatestore
SOURCES
tst_qwebengineclientcertificatestore.cpp
LIBRARIES
Qt::WebEngineCore
+ Test::HttpServer
+ Test::Util
)
set(tst_qwebengineclientcertificatestore_resource_files
@@ -10,6 +18,13 @@ set(tst_qwebengineclientcertificatestore_resource_files
"resources/certificate1.crt"
"resources/privatekey.key"
"resources/privatekey1.key"
+ "resources/server.pem"
+ "resources/server.key"
+ "resources/client.pem"
+ "resources/client.key"
+ "resources/client2.pem"
+ "resources/client2.key"
+ "resources/ca.pem"
)
qt_internal_add_resource(tst_qwebengineclientcertificatestore "tst_qwebengineclientcertificatestore"
@@ -19,3 +34,47 @@ qt_internal_add_resource(tst_qwebengineclientcertificatestore "tst_qwebenginecli
${tst_qwebengineclientcertificatestore_resource_files}
)
+if(LINUX AND NOT CMAKE_CROSSCOMPILING)
+
+ get_filename_component(homePath $ENV{HOME} ABSOLUTE)
+
+ find_program(pk12util_EXECUTABLE NAMES pk12util)
+ find_program(certutil_EXECUTABLE NAMES certutil)
+
+ if(pk12util_EXECUTABLE AND certutil_EXECUTABLE)
+ add_custom_command(
+ DEPENDS resources/client2.p12
+ COMMAND test -e "${homePath}/.pki/nssdb" || ${CMAKE_COMMAND} -E make_directory
+ "${homePath}/.pki/nssdb"
+ COMMAND test -e "${homePath}/.pki/nssdb/cert9.db" || ${certutil_EXECUTABLE}
+ -N --empty-password -d sql:${homePath}/.pki/nssdb
+ COMMAND test -e "${homePath}/.pki/nssdb/cert9.db" && ${pk12util_EXECUTABLE}
+ -d sql:${homePath}/.pki/nssdb
+ -i "${CMAKE_CURRENT_LIST_DIR}/resources/client2.p12"
+ -W ""
+ COMMAND ${CMAKE_COMMAND} -E touch pk12util.stamp
+ OUTPUT pk12util.stamp
+ VERBATIM
+ USES_TERMINAL
+ )
+ add_custom_target(
+ add-user-personal-certificate
+ DEPENDS pk12util.stamp
+ )
+ qt_internal_extend_target(tst_qwebengineclientcertificatestore DEFINES TEST_NSS)
+ add_dependencies(tst_qwebengineclientcertificatestore add-user-personal-certificate)
+ endif()
+
+ find_program(certutil_EXECUTABLE NAMES certutil)
+
+ if(certutil_EXECUTABLE)
+ add_custom_target(remove-user-personal-certificate
+ COMMAND ${CMAKE_COMMAND} -E remove pk12util.stamp
+ COMMAND ${certutil_EXECUTABLE}
+ -d sql:"${homePath}/.pki/nssdb"
+ -D
+ -n qwebengineclientcertificatestore
+ )
+ endif()
+endif()
+
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/ca.pem b/tests/auto/core/qwebengineclientcertificatestore/resources/ca.pem
new file mode 100644
index 000000000..cb62ad62c
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/ca.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECzCCAvOgAwIBAgIUdhDW1WgGxF313LYA0JjEQpKbanQwDQYJKoZIhvcNAQEL
+BQAwgZQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl
+cmxpbjEXMBUGA1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5n
+aW5lMRIwEAYDVQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5n
+aW5lQHF0LmlvMB4XDTIyMTExNjExMDQxNFoXDTMyMTExMzExMDQxNFowgZQxCzAJ
+BgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEXMBUG
+A1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5naW5lMRIwEAYD
+VQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5naW5lQHF0Lmlv
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxyNLLwAA+FgNQavVJ19n
+gdoy+NKLHQyhzcRFykKSp9aAbpAR6e4ukxwG7mWNBcuR7zv1Zw/JqLFE0gmVztVw
+FeQWdw1cvTN/OlVEuM+0ShTDHHsCqRpx7/XJT6ytMKVU8jdZN4Vl1m7MubWv4aPy
+0WYYd3zIAicciYgy/RHaRhPTKpPzWIPYhmHsM5w2cebL8I0aZXUkC0OeklJArnp9
+007Fr6SXXK0xQ3RO20n7X193gCfd5U70lug0ks/ZZqxtzPHmzIO1WGAOBura50HR
+hxUKAu7qQHzBiW5Qwdn0af4FPLJR/SX8ADKTLCSWlMOo1FLYO5w6D8hB4K6/b9VQ
+RwIDAQABo1MwUTAdBgNVHQ4EFgQUXuTuB85/iBgwJpLdOc+8TB0KESIwHwYDVR0j
+BBgwFoAUXuTuB85/iBgwJpLdOc+8TB0KESIwDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQsFAAOCAQEAvtucUJa0IECltWv8U6R+LQuZ1Q+ubbmstojO/h8tg6Wf
+v6FZ5bH3oboSyGEcytRr6INf4G6znUNAypbodehAEW6/PETdzGM9CJyv2JPJAWzV
+rxb1H5VTyiEs8924QOqcNATD+oe7G0vwnDkvprcqaWBA6yvQkWpCXoqMc+F95KnY
+8VFt2VQw17l4L4nhaX3Us6hJLMiKV+dLeF0pN+pkCPRP9G5WKgW3mT2U6Gig+rLz
+6L7rBbb5KWAttdAbuHCrMa65PgXoVD1P/GteFxUnghDd0PWgUaign8c/DyHGsrbA
+uvJqSym0kmQQXptryRaKFsGcCrizdbE6FfrH2iE7vQ==
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/client.key b/tests/auto/core/qwebengineclientcertificatestore/resources/client.key
new file mode 100644
index 000000000..21c8e3183
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/client.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAqnHbq38y1VprEaV2xXzv2nAPyjqCuIfuick8qETkzEsNWPQi
+dsBlLfcyf+15wEMhpRIwILXCrUM7Sb7WCGtg1XC00JZvCh2xPBMSD2fiQyHn4men
+Fwh9vVbTf1v7w21ZT/pXQrwlgLgNWYZHE3JrcEAwlThQRIdQfzSE6/QeHfYZoGB9
+WfvbREsOWiUlZze/yrblS9vnAVhYwVurelc7lXyHA0dHmkcZ0HwMxVJZ/vLuCyIw
+lNGT/ytnA9p1l8uFkAgTcbWZKoyJAsAZG9faZp46hk8+e3KAyKQ78aoUSbjAqnNQ
+tBM3bnHeHanf3ddCxyej+k9PfSIY27a9FZxHpQIDAQABAoIBAFsomA8p8ZsQR9Fh
+SJupDXMrmhZTotRkxxxkR4/LgP8OaO4ZbFFM5xBldFndPc+pV9Y8WwczjxIxsgTo
+Dvrjyx98rwgcXPjxFniFzpP0wJudB7McMs5r2SwpwuYL4SQNWMYgowjrLbehOGqY
+GW16NaIMgq9cNfng0RmnkivMHUtyE5GGdK+C6cyK+fIE+cNtQtHPRKfEnwbE9VHz
+3EY/nCXGZvMFyj5uHaU4EeZFCzo19TUqhh8H7b0EA44pBtb5U/CxsH4xphZ7rpjt
+iVjMfRSMR4qalQNIs6ZEj57We+M/zca/Qq1yhjW+0NYbZifcYo1Oj6e4lC9YlIgn
+kGkcuUECgYEA1j0iVFjgBXS8pJP3jBgmbrbBBTNEUv27yjnJCAQx5TbplJkvBM4/
+qzum1uH2o6uRrFtrYJFiAhDHARtg+70rMeYqZp8WFvzJT5c5s+FOmGQPfFjgrD6e
+wfnCwFzS7nohJ8TM2mPGJ88pBv0eBYW6D0f7fvcJmEk8hnGktdLRCrECgYEAy6tU
+YFZDzGhbgrG2wWzBvAKVngUNhrYZHMiF1WVN8zZdCm7Z8b1S/NMe0rPA5orhAkSX
+8fxlDfKOm+U2fKp43aiN0NDiP0TlGRbypAXe7FSnvDxNHbV+Ie0UbwuiJ4s3vJuc
+6cdzgKqAs5/rjPXPdUpM8C7344HV7azgSzHIYTUCgYAtVmCmcuxtmye0uG+BoTa4
+5UnxvMivu2x7PkFRxfl9JWLHBKfTn4YPyZ7kCIu2VT+NtwcBN6MDBuPmUxHyFDVI
+6Ql+EBqPoM1FX55hd8O3Mi2oxfI94T6dlCpnpP0qZIQRs28apFSx5gArr3Mj/gnC
+5BvP4Z2RMaZyWShfJg8A8QKBgQClZEhswyDjiYtmorJqeMsKxn6BiFDnqFDUUvJ7
+zHx0mR0NL9/Es54Eud059ccccIMwuEs7s17M6MBuUMDik/z647nmbPqNroDs0vnP
+wQS6njRoY/+rtIrtOf1x/9x6iE+G1keigNmHDu7c72z1V1hVQzUfhsS+99yl2dF6
+vr6eUQKBgF/OHW1bE3FruZ+53Arcb94N/IKnpH9VWoB3elIzr0w6pLtL4HHhmQ58
+TayEpq6YguUAjTvCBbaHuYuKPHiXCAy5DhtrXvP4YdMNH9X1nHc7jVEbGltVbnQU
+bG/p5YfZSrDmsjf8w0z7feFOcovC6vF1YCXc8OHK/LQ6JFJ/gtO1
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/client.pem b/tests/auto/core/qwebengineclientcertificatestore/resources/client.pem
new file mode 100644
index 000000000..dd1f898f7
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/client.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApcCFFNQAgGBu5nr81tUMdXXLGkm8Li+MA0GCSqGSIb3DQEBCwUAMIGU
+MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
+FzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTES
+MBAGA1UEAwwJd3d3LnF0LmlvMSAwHgYJKoZIhvcNAQkBFhFxdHdlYmVuZ2luZUBx
+dC5pbzAeFw0yMjExMTYxMjExMDFaFw0zMjExMTMxMjExMDFaMIGSMQswCQYDVQQG
+EwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAoM
+DlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTEVMBMGA1UEAwwM
+Y2xpZW50LnF0LmlvMRswGQYJKoZIhvcNAQkBFgxjbGllbnRAcXQuaW8wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqcdurfzLVWmsRpXbFfO/acA/KOoK4
+h+6JyTyoROTMSw1Y9CJ2wGUt9zJ/7XnAQyGlEjAgtcKtQztJvtYIa2DVcLTQlm8K
+HbE8ExIPZ+JDIefiZ6cXCH29VtN/W/vDbVlP+ldCvCWAuA1ZhkcTcmtwQDCVOFBE
+h1B/NITr9B4d9hmgYH1Z+9tESw5aJSVnN7/KtuVL2+cBWFjBW6t6VzuVfIcDR0ea
+RxnQfAzFUln+8u4LIjCU0ZP/K2cD2nWXy4WQCBNxtZkqjIkCwBkb19pmnjqGTz57
+coDIpDvxqhRJuMCqc1C0Ezducd4dqd/d10LHJ6P6T099Ihjbtr0VnEelAgMBAAEw
+DQYJKoZIhvcNAQELBQADggEBALE75ZQxmEXJA16cNAxxmxCKHkaqAE6Ulim1vXNH
+jCFfNCDGYn/R28F3BVtMe+bIMoomaTh3h5eOd/9uc2nm8IiT5FUz9epJWPeRG/cl
+I+hQ3fvaE7oJ3m3EwfGq1mdqUf1zi+DFjtkimNbn9ZRDocZfpO5VN0u23ptEuk0P
+5cH4+Dst0giRMv5W0kXG6QD13H/eVH3jDZCtZa/8T4oxGGskHEa4yDr8s976lVOV
+XLI1r7oN4a/KXKow8WN3oHFeKn4QJx86z1uecuZLtT8xjABKSWpZqgsIlmGTGE1a
+9W06C+uPVamwn5ND3gnf93YQqn6PwrjlHdrQOTG/vngJLPw=
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/client2.key b/tests/auto/core/qwebengineclientcertificatestore/resources/client2.key
new file mode 100644
index 000000000..3c1346519
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/client2.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAv0vrzULGwDJBoZgnGXdkMFxCvkTqqQYCE/LlNtStLJfJH7Fo
+CgenVFcJ8RIFHdkL7HeFAIZjDLSjIp2Ud41fd+VsaGgB/+j1/UeEN8nkArvYB9ol
+OnKGq6CbSrCocrLo2o2X+6eyLtrtLG6RLr8/UiqB2OWNAdnw70S5RCvnbV6phr8z
+bgYqPdPSBaedfZk5Kj6yM6XvIKSK6IjgZuo+Z5SyabJqk2VhaBlB7mjCf3Mj4zPD
+XvQXsAq0ZNQXQVwKRfJ2I9uAeNAZiQP5i00pBqe2kIJEKnk8qbP4/Jho2Tp8XSBC
+jHMn0oWrAZyO9vw3W940qmqmdRftyt+J8DO9xwIDAQABAoIBAGBpXTCYRR88tQNC
+cgJNv/r3pNPMXBBP7OAs/QUDbzwYS89jVDIp5VWGgIY1NMr0RyQooKnBEU6oA8hA
+b0FJySHeSSLduJRHzyKV1rdfU0Fldt2OPlEUw3bgfSPJoTwdm2n7DuxQemdPA1Xv
+a9CJpto8fjDYkJasRtfwZQdMsVjXCfQ/cCzkOkblUDZcc7yTx3uiBKF8Jy8C+0qc
+98btotYU88KWoE9A0ucWt/ik68MjYmccO6PYXKerNW2Ijgd1kik35G3TbEWxOFWW
+y3zLFtfoD+21SdUgTMzM06owDVfSt/MER4tOxFyUPRuze7BJXrBofGQfuPiGiPuK
+f5QZP8ECgYEA+x1PkClsqtRnjrzmRfi3OFez1Kbbzneucg5ssWR+Hd4EUFhhO42q
+te1ZYoydy09tEqd002U7e5hob0/o+rVK9jldpZszMCBfVDYCDqdtw5rNI89bL1Uz
+8krn6nk3BBx42lgAFU4C1JEaur4r14OOUtoFfRTAwjogQHcDmpyPNjcCgYEAwwSv
+FJAKRjw1oOXKlGotoeYEAREVxH9HFnfM5IcVwcwMt+KUFEyrMtXeH1gk7jo+2ev4
+87njQ8hU3VPObCUcnTJHi2a6D9JIY+zA9bKTJjc8drcBathipmwtak14TsX2qe14
+JBIKlC3V0h1FqM3ep76p4dnt7sTmVc7ZOqBR7PECgYEA1HQE94wEkzdnch0hmbuG
+kBWrYNPXDgS1w2uuzBqglPZcoflUMkV2U7s+r6EWc4d8WZbxwVRZkgTs/pgWHd66
+UD1SnKUFFsecv6t97BX9SMu0mYJ6vD4S2ABF3Fu3jzPjj596WowI2vz1J19zyj9U
+b4ZjtGKVfv4cgU3v76RbidsCgYAx4CvKzX/jMJjimoJx7KnZAxO5Fh6ED60loOQE
++ktlMgN6r/cBLg6GxM23JHrldn4Gi+QyqTLnbf/OTxW28NLdnTNRAqfJThV3gOBk
+thQOLQhIsEsrgUXRnE8NJd0EAHsyQGp+hyKvfP13bEcZgfVU311hRrQkYbUq8uj5
+pnDtcQKBgEFIpP7EzdJWrVOUjnjMQloqBhW8KVVtNwI5bmlcsUvVYjfZph016SiF
+UTfZss1KkBmQClAVtyZsrKIfObIJ9KJ4hPAzzk+ca1D6XTLsYjxPwtB/U0ewB2Dm
+yMxkXpT1kAiJ2Tdr1hZ8OcQhvnGWmrhtz+AkjyLXiYgST7Hubrxt
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/client2.p12 b/tests/auto/core/qwebengineclientcertificatestore/resources/client2.p12
new file mode 100644
index 000000000..81e7eb624
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/client2.p12
Binary files differ
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/client2.pem b/tests/auto/core/qwebengineclientcertificatestore/resources/client2.pem
new file mode 100644
index 000000000..39c0b3f09
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/client2.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDsTCCApkCFFNQAgGBu5nr81tUMdXXLGkm8LjBMA0GCSqGSIb3DQEBCwUAMIGU
+MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
+FzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTES
+MBAGA1UEAwwJd3d3LnF0LmlvMSAwHgYJKoZIhvcNAQkBFhFxdHdlYmVuZ2luZUBx
+dC5pbzAeFw0yMjExMTYxOTIwMzBaFw0zMjExMTMxOTIwMzBaMIGUMQswCQYDVQQG
+EwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAoM
+DlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTEWMBQGA1UEAwwN
+Y2xpZW50Mi5xdC5pbzEcMBoGCSqGSIb3DQEJARYNY2xpZW50MkBxdC5pbzCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9L681CxsAyQaGYJxl3ZDBcQr5E
+6qkGAhPy5TbUrSyXyR+xaAoHp1RXCfESBR3ZC+x3hQCGYwy0oyKdlHeNX3flbGho
+Af/o9f1HhDfJ5AK72AfaJTpyhqugm0qwqHKy6NqNl/unsi7a7SxukS6/P1Iqgdjl
+jQHZ8O9EuUQr521eqYa/M24GKj3T0gWnnX2ZOSo+sjOl7yCkiuiI4GbqPmeUsmmy
+apNlYWgZQe5own9zI+Mzw170F7AKtGTUF0FcCkXydiPbgHjQGYkD+YtNKQantpCC
+RCp5PKmz+PyYaNk6fF0gQoxzJ9KFqwGcjvb8N1veNKpqpnUX7crfifAzvccCAwEA
+ATANBgkqhkiG9w0BAQsFAAOCAQEAic8F8q1TpP2ufnBRbrBp54Jgddl/zdVb7O3M
+AAK67KiEpEr9xPPVcIowfns1ZTIsIB8D4VS4NQGJXBrwvGWL08SpSmi76I1E156x
+9Hql0PHXCjqsJTOSEvljIgQ4sp33zs0DTmlyejSSGnG9sw2FtcYAGZNV+ImAhTO2
+DNxw3BnF++ilHsQbiWIKD5z14bOXb77SJrimup0YBzfwBWJO013k8g8lkiRRs5Ng
+XYVr3NoTLcIJQ7BTFu4W1Wegxwrw3fQZ98BBlCVh0htrOcLpWKelJeI16MgZA/7T
+P4MwvN5tkyjqrcsrDORldR6JKdX8i+GLF49MgRW4QispcZzoYA==
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/server.key b/tests/auto/core/qwebengineclientcertificatestore/resources/server.key
new file mode 100644
index 000000000..632cc4d2e
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/server.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA5gQoJryenjmvzy4RbqHdNXHK8Gk/8Lto1SwT8+Wbh5EyYRTt
+hFdioT1JYcIe3XMwOmx3TjADY1jAXAPfeRcjTkMcnZwF76AXUK2XqBANhaG1wjsi
+b7ISGU/U5/Jarm2iwQJ5zjKsNm8pZYqpmKsYAVFMErtfcpdLdSp6BG54SrbItcXh
+WHfsUs5cuVEi9nCeugLkDzoPLlj/TeouKWOdzhyvLXkPvPmD4/hD0dULTXpCDZhf
+73AuQBWTGsWeUnJQiQhDRwuXWhGRX8qFJQ4rzY8rIbaKhge+BQ6BL+pij2uzHKNQ
+j12ZLFZgLihLDJogGp08y9Ud6Ru/3WGoFkY38wIDAQABAoIBABM/TczQA8XhteB0
+Tmkfik8qknzDkeInDIKqCZFjKTyS3dBZ2/YzCcHMSxOvFr4ZIXQCF4mnYuExUAdj
+G5QaZ43o98AIikae8tSBcitSDI+eFIOIRz1pfTI5B+vQz93AttnHx0GF4/s6GhCx
+JbfsuTmDAAahPz9rgZjwUP2F8PLvaAZqJrXBPY+QLWz0SN2zh6vWAHPbJA0sO/4E
+oWUhRPXJDf33YCFxnwtbUBie5313suAfNspODcyH+AxBH2FFh63pe0ZGOhX7XFMJ
+yxJqujeZrQdfwFZNPXAPVLJGbd7AIOrVE+O8/bYUB/uuj6pPJBqr+Ob/JhY48pRb
+VG2qL4ECgYEA9n3PuL13F9XFcLeergGH7fUcSQeD1T6Z1qaI2Wth0Umfmer/fFZh
+IKSCSwEGMTLsalFdlTj8jsSAasjuSorQTeSgHjzvzik1Ll2P6syputjsD1RX/nkl
+8L50Pwdeey57Y9dgow7Cw/heGYs6dkXLe9H6qM7eoB8Vrk7/TAFuqNECgYEA7uOl
+oKyOxeLn005cenc5enY2IxDhXTaAjTGHE64C0lmicD2OZB7/b+ZIb8M5R7GnCNox
+4TxLSRhZYOMO/QcTrnSND5PXbX/HLd3nyQRIN1XtBbg7pJooxP/MQ/Ne5XTTMjCg
+qPudkOe0ZgUHEcuH8m/YAFY3DDJC50uiXqYtxYMCgYBHfL+ExbZHfGExyp9Duf/x
+PHhCmeJbMzessEnaPLF24FJgcm48YlTzAaMkG5zvIeS9BPIOOCPPSCAyWCn8BnxZ
+SuhBPM0TzpG067+0ijzjiswTuhN3Iy2kv6e5K+rz8MwqbamCQOKtsVehMub2rFFS
+jNiUosKgT8Oa9SBHq9arMQKBgQCE3EVEnFP3iOAILH/QeLiV/GLVk9DTR7mtTUtj
+zZayKLnoFMQ5uOe182x8BCa6UfqlOL0fGKqCZ7Fl6kJuxV3T2+yMKlxZAQTk5JLB
+wMjtRbPCR5mcTUS5c87GR/eSRCwlsNfZw775VXSGfOtWoUzlsACBB3IsLVP6UZ1n
+aKLyQwKBgC61BvKiyGBEYIchqMI4dSF+zCJbSjNUtjwVobcgC6yERZtX2OeLFCoh
+NEf9CcL2Eqb+RzwAD3OV65AiZcrThQNXZ8poBxvwWK8I6E6zB+LX7POAvNu/AV/5
+ANnxwHGGLqi+wTcdMZal2iXkdsrno1Ek/nGMCdA7IVs7l5k7fEpG
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/resources/server.pem b/tests/auto/core/qwebengineclientcertificatestore/resources/server.pem
new file mode 100644
index 000000000..4706fa73e
--- /dev/null
+++ b/tests/auto/core/qwebengineclientcertificatestore/resources/server.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApcCFFNQAgGBu5nr81tUMdXXLGkm8Li/MA0GCSqGSIb3DQEBCwUAMIGU
+MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4x
+FzAVBgNVBAoMDlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTES
+MBAGA1UEAwwJd3d3LnF0LmlvMSAwHgYJKoZIhvcNAQkBFhFxdHdlYmVuZ2luZUBx
+dC5pbzAeFw0yMjExMTYxMjExMTRaFw0zMjExMTMxMjExMTRaMIGSMQswCQYDVQQG
+EwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xFzAVBgNVBAoM
+DlRoZSBRdCBDb21wYW55MRQwEgYDVQQLDAtRdFdlYkVuZ2luZTEVMBMGA1UEAwwM
+c2VydmVyLnF0LmlvMRswGQYJKoZIhvcNAQkBFgxzZXJ2ZXJAcXQuaW8wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmBCgmvJ6eOa/PLhFuod01ccrwaT/w
+u2jVLBPz5ZuHkTJhFO2EV2KhPUlhwh7dczA6bHdOMANjWMBcA995FyNOQxydnAXv
+oBdQrZeoEA2FobXCOyJvshIZT9Tn8lqubaLBAnnOMqw2bylliqmYqxgBUUwSu19y
+l0t1KnoEbnhKtsi1xeFYd+xSzly5USL2cJ66AuQPOg8uWP9N6i4pY53OHK8teQ+8
++YPj+EPR1QtNekINmF/vcC5AFZMaxZ5SclCJCENHC5daEZFfyoUlDivNjyshtoqG
+B74FDoEv6mKPa7Mco1CPXZksVmAuKEsMmiAanTzL1R3pG7/dYagWRjfzAgMBAAEw
+DQYJKoZIhvcNAQELBQADggEBAHotgaBbqIlG4EqjzSpX8kQnZnGJUsA51dbY3K5C
+4tNCd+JquQfPmCIKDHkRsmmEU6pcU+LT8m+toJ8Gx0XG4nrdUIDt0Nlf/QrykbPj
+hN8z+aSfP9J5tg4NsT7qMWmqUHOa3BcsgWcC4IwWVkbOMz/XbczEQqdBJMbE0+PC
+32ihTKPZBPC2QlIvXyuwupvQtcXgEjw1r2FQeYcmItk3CKbJPE/Rk4/aXSCo4b0F
+iXPphh8BJPZVvQ2cLpPaGvcse5qjIhF9ODb2HEK3myMwuJVi7teURy8mPlS23Li/
+8gRCNu/stjMlkic7d3dqV0LwaG8+Df1W2wzxsT7IkxN/Z+o=
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
index f288a2c75..7d82a5640 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -1,34 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+#include <httpsserver.h>
+#include <util.h>
#include <QtTest/QtTest>
#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
+#include <QtWebEngineCore/qwebenginepage.h>
#include <QtWebEngineCore/qwebengineprofile.h>
+#include <QtWebEngineCore/qwebenginecertificateerror.h>
+#include <QtWebEngineCore/qwebenginesettings.h>
class tst_QWebEngineClientCertificateStore : public QObject
{
@@ -39,8 +19,12 @@ public:
~tst_QWebEngineClientCertificateStore();
private Q_SLOTS:
+ void init();
+ void cleanup();
void addAndListCertificates();
void removeAndClearCertificates();
+ void clientAuthentication_data();
+ void clientAuthentication();
};
tst_QWebEngineClientCertificateStore::tst_QWebEngineClientCertificateStore()
@@ -51,6 +35,19 @@ tst_QWebEngineClientCertificateStore::~tst_QWebEngineClientCertificateStore()
{
}
+void tst_QWebEngineClientCertificateStore::init()
+{
+ QCOMPARE(0,
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().size());
+}
+
+void tst_QWebEngineClientCertificateStore::cleanup()
+{
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->clear();
+ QCOMPARE(0,
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().size());
+}
+
void tst_QWebEngineClientCertificateStore::addAndListCertificates()
{
// Load QSslCertificate
@@ -77,21 +74,93 @@ void tst_QWebEngineClientCertificateStore::addAndListCertificates()
QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(certSecond, sslKeySecond);
- QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().size());
}
void tst_QWebEngineClientCertificateStore::removeAndClearCertificates()
{
- QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+ addAndListCertificates();
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().size());
// Remove one certificate from in-memory store
auto list = QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates();
QWebEngineProfile::defaultProfile()->clientCertificateStore()->remove(list[0]);
- QCOMPARE(1, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+ QCOMPARE(1, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().size());
// Remove all certificates in-memory store
QWebEngineProfile::defaultProfile()->clientCertificateStore()->clear();
- QCOMPARE(0, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().length());
+ QCOMPARE(0, QWebEngineProfile::defaultProfile()->clientCertificateStore()->certificates().size());
+}
+
+void tst_QWebEngineClientCertificateStore::clientAuthentication_data()
+{
+ QTest::addColumn<QString>("client_certificate");
+ QTest::addColumn<QString>("client_key");
+ QTest::addColumn<bool>("in_memory");
+ QTest::addColumn<bool>("add_more_in_memory_certificates");
+ QTest::newRow("in_memory") << ":/resources/client.pem"
+ << ":/resources/client.key" << true << false;
+#if defined(TEST_NSS)
+ QTest::newRow("nss") << ":/resources/client2.pem"
+ << ":/resources/client2.key" << false << false;
+ QTest::newRow("in_memory + nss") << ":/resources/client2.pem"
+ << ":/resources/client2.key" << false << true;
+#endif
+}
+
+void tst_QWebEngineClientCertificateStore::clientAuthentication()
+{
+ QFETCH(QString, client_certificate);
+ QFETCH(QString, client_key);
+ QFETCH(bool, in_memory);
+ QFETCH(bool, add_more_in_memory_certificates);
+
+ HttpsServer server(":/resources/server.pem", ":/resources/server.key", ":resources/ca.pem");
+ server.setExpectError(false);
+ QVERIFY(server.start());
+
+ connect(&server, &HttpsServer::newRequest, [&](HttpReqRep *rr) {
+ rr->setResponseBody(QByteArrayLiteral("<html><body>TEST</body></html>"));
+ rr->sendResponse();
+ });
+
+ QFile certFile(client_certificate);
+ certFile.open(QIODevice::ReadOnly);
+ const QSslCertificate cert(certFile.readAll(), QSsl::Pem);
+
+ QFile keyFile(client_key);
+ keyFile.open(QIODevice::ReadOnly);
+ const QSslKey sslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ if (in_memory)
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
+
+ if (add_more_in_memory_certificates)
+ addAndListCertificates();
+
+ QWebEnginePage page;
+ connect(&page, &QWebEnginePage::certificateError, [](QWebEngineCertificateError e) {
+ // ca is self signed in this test simply accept the certificate error
+ e.acceptCertificate();
+ });
+ connect(&page, &QWebEnginePage::selectClientCertificate, &page,
+ [&cert](QWebEngineClientCertificateSelection selection) {
+ QVERIFY(!selection.certificates().isEmpty());
+ for (const QSslCertificate &sCert : selection.certificates()) {
+ if (cert == sCert) {
+ selection.select(sCert);
+ return;
+ }
+ }
+ QFAIL("No certificate found.");
+ });
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ page.setUrl(server.url());
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size() > 0, true, 20000);
+ QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), true);
+ QCOMPARE(toPlainTextSync(&page), QStringLiteral("TEST"));
+ QVERIFY(server.stop());
}
QTEST_MAIN(tst_QWebEngineClientCertificateStore)
diff --git a/tests/auto/core/qwebenginecookiestore/CMakeLists.txt b/tests/auto/core/qwebenginecookiestore/CMakeLists.txt
index 33ba5ff1a..cc14940f1 100644
--- a/tests/auto/core/qwebenginecookiestore/CMakeLists.txt
+++ b/tests/auto/core/qwebenginecookiestore/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index a712fb288..3fff2cd45 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <util.h>
#include <QtTest/QtTest>
@@ -35,6 +10,10 @@
#include "httpserver.h"
#include "httpreqrep.h"
+// locally overwrite the default timeout of QTY_(COMPARE|VERIFY)
+#define QWE_TRY_COMPARE(x, y) QTRY_COMPARE_WITH_TIMEOUT(x, y, 30000)
+#define QWE_TRY_VERIFY(x) QTRY_VERIFY_WITH_TIMEOUT(x, 30000)
+
class tst_QWebEngineCookieStore : public QObject
{
Q_OBJECT
@@ -55,6 +34,7 @@ private Q_SLOTS:
// as it checks storage manipulation without navigation
void setAndDeleteCookie();
+ void setInvalidCookie();
void cookieSignals();
void batchCookieTasks();
void basicFilter();
@@ -104,22 +84,22 @@ void tst_QWebEngineCookieStore::cookieSignals()
page.load(QUrl("qrc:///resources/index.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVariant success = loadSpy.takeFirst().takeFirst();
QVERIFY(success.toBool());
- QTRY_COMPARE(cookieAddedSpy.count(), 2);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 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);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 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);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 1);
}
void tst_QWebEngineCookieStore::setAndDeleteCookie()
@@ -140,33 +120,64 @@ void tst_QWebEngineCookieStore::setAndDeleteCookie()
client->loadAllCookies();
// /* FIXME remove 'blank' navigation once loadAllCookies api is fixed
page.load(QUrl("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
// */
// check if pending cookies are set and removed
client->setCookie(cookie1);
client->setCookie(cookie2);
- QTRY_COMPARE(cookieAddedSpy.count(), 2);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 2);
client->deleteCookie(cookie1);
- QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 1);
page.load(QUrl("qrc:///resources/content.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 2);
QVariant success = loadSpy.takeFirst().takeFirst();
QVERIFY(success.toBool());
- QTRY_COMPARE(cookieAddedSpy.count(), 2);
- QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 2);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 1);
cookieAddedSpy.clear();
cookieRemovedSpy.clear();
client->setCookie(cookie3);
- QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 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);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 1);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 2);
+}
+
+void tst_QWebEngineCookieStore::setInvalidCookie()
+{
+ QWebEnginePage page(m_profile);
+ QWebEngineCookieStore *client = m_profile->cookieStore();
+
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
+ QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+
+ QNetworkCookie goodCookie(
+ QNetworkCookie::parseCookies(
+ QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs"))
+ .first());
+ QNetworkCookie badCookie(
+ QNetworkCookie::parseCookies(QByteArrayLiteral("TestCookie=foo\tbar;")).first());
+
+ // force to init storage as it's done lazily upon first navigation
+ client->loadAllCookies();
+ // /* FIXME remove 'blank' navigation once loadAllCookies api is fixed
+ page.load(QUrl("about:blank"));
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
+ // */
+
+ client->setCookie(badCookie);
+ client->setCookie(goodCookie);
+ client->deleteCookie(goodCookie);
+ // by the time the second cookie is removed, only one cookie should have been added
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 1);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 1);
}
void tst_QWebEngineCookieStore::batchCookieTasks()
@@ -185,29 +196,29 @@ void tst_QWebEngineCookieStore::batchCookieTasks()
client->loadAllCookies();
// /* FIXME remove 'blank' navigation once loadAllCookies api is fixed
page.load(QUrl("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
// */
client->setCookie(cookie1);
client->setCookie(cookie2);
- QTRY_COMPARE(cookieAddedSpy.count(), 2);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 2);
page.load(QUrl("qrc:///resources/index.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 2);
QVariant success = loadSpy.takeFirst().takeFirst();
QVERIFY(success.toBool());
- QTRY_COMPARE(cookieAddedSpy.count(), 4);
- QTRY_COMPARE(cookieRemovedSpy.count(), 0);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 4);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 0);
cookieAddedSpy.clear();
cookieRemovedSpy.clear();
client->deleteSessionCookies();
- QTRY_COMPARE(cookieRemovedSpy.count(), 3);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 3);
client->deleteAllCookies();
- QTRY_COMPARE(cookieRemovedSpy.count(), 4);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 4);
}
void tst_QWebEngineCookieStore::basicFilter()
@@ -224,22 +235,22 @@ void tst_QWebEngineCookieStore::basicFilter()
page.load(QUrl("qrc:///resources/index.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QTRY_COMPARE(cookieAddedSpy.count(), 2);
- QTRY_COMPARE(accessTested.loadAcquire(), 2); // FIXME?
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 2);
+ QWE_TRY_COMPARE(accessTested.loadAcquire(), 2); // FIXME?
client->deleteAllCookies();
- QTRY_COMPARE(cookieRemovedSpy.count(), 2);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 2);
client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &){ ++accessTested; return false; });
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QTRY_COMPARE(accessTested.loadAcquire(), 4); // FIXME?
+ QWE_TRY_COMPARE(accessTested.loadAcquire(), 4); // FIXME?
// Test cookies are NOT added:
QTest::qWait(100);
- QCOMPARE(cookieAddedSpy.count(), 2);
+ QCOMPARE(cookieAddedSpy.size(), 2);
}
void tst_QWebEngineCookieStore::basicFilterOverHTTP()
@@ -280,25 +291,25 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
QUrl firstPartyUrl = httpServer.url("/test.html");
page.load(firstPartyUrl);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
- QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 4);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 1);
+ QWE_TRY_COMPARE(accessTested.loadAcquire(), 4);
QVERIFY(cookieRequestHeader.isEmpty());
- QTRY_COMPARE(serverSpy.count(), 3);
+ QWE_TRY_COMPARE(serverSpy.size(), 3);
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QVERIFY(!cookieRequestHeader.isEmpty());
- QTRY_COMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 6);
+ QWE_TRY_COMPARE(cookieAddedSpy.size(), 1);
+ QWE_TRY_COMPARE(accessTested.loadAcquire(), 6);
- QTRY_COMPARE(serverSpy.count(), 5);
+ QWE_TRY_COMPARE(serverSpy.size(), 5);
client->deleteAllCookies();
- QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+ QWE_TRY_COMPARE(cookieRemovedSpy.size(), 1);
client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) {
resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl));
@@ -306,28 +317,28 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP()
return false;
});
page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QVERIFY(cookieRequestHeader.isEmpty());
// Test cookies are NOT added:
QTest::qWait(100);
- QCOMPARE(cookieAddedSpy.count(), 1);
- QTRY_COMPARE(accessTested.loadAcquire(), 9);
+ QCOMPARE(cookieAddedSpy.size(), 1);
+ QWE_TRY_COMPARE(accessTested.loadAcquire(), 9);
- QTRY_COMPARE(serverSpy.count(), 7);
+ QWE_TRY_COMPARE(serverSpy.size(), 7);
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QVERIFY(cookieRequestHeader.isEmpty());
- QCOMPARE(cookieAddedSpy.count(), 1);
+ QCOMPARE(cookieAddedSpy.size(), 1);
// Wait for last GET /favicon.ico
- QTRY_COMPARE(serverSpy.count(), 9);
+ QWE_TRY_COMPARE(serverSpy.size(), 9);
(void) httpServer.stop();
QCOMPARE(resourceFirstParty.size(), accessTested.loadAcquire());
- for (auto &&p : qAsConst(resourceFirstParty))
+ for (auto &&p : std::as_const(resourceFirstParty))
QVERIFY2(p.second == firstPartyUrl,
qPrintable(QString("Resource [%1] has wrong firstPartyUrl: %2").arg(p.first.toString(), p.second.toString())));
}
@@ -344,17 +355,17 @@ void tst_QWebEngineCookieStore::html5featureFilter()
page.load(QUrl("qrc:///resources/content.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QWE_TRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
QCOMPARE(accessTested.loadAcquire(), 0); // FIXME?
QTest::ignoreMessage(QtCriticalMsg, QRegularExpression(".*Uncaught SecurityError.*sessionStorage.*"));
page.runJavaScript("sessionStorage.test = 5;");
- QTRY_COMPARE(accessTested.loadAcquire(), 1);
+ QWE_TRY_COMPARE(accessTested.loadAcquire(), 1);
QTest::ignoreMessage(QtCriticalMsg, QRegularExpression(".*Uncaught SecurityError.*sessionStorage.*"));
QAtomicInt callbackTriggered = 0;
page.runJavaScript("sessionStorage.test", [&](const QVariant &v) { QVERIFY(!v.isValid()); callbackTriggered = 1; });
- QTRY_VERIFY(callbackTriggered);
+ QWE_TRY_VERIFY(callbackTriggered);
}
QTEST_MAIN(tst_QWebEngineCookieStore)
diff --git a/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt b/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt
new file mode 100644
index 000000000..fa81ba8df
--- /dev/null
+++ b/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../httpserver/httpserver.cmake)
+include(../../util/util.cmake)
+
+qt_internal_add_test(tst_qwebengineglobalsettings
+ SOURCES
+ tst_qwebengineglobalsettings.cpp
+ LIBRARIES
+ Qt::WebEngineCore
+ Test::HttpServer
+ Qt::WebEngineWidgets
+ Test::Util
+)
+
+# Resources:
+set(tst_qwebengineglobalsettings_resource_files
+ "cert/localhost.crt"
+ "cert/localhost.key"
+ "cert/RootCA.pem"
+)
+
+qt_add_resources(tst_qwebengineglobalsettings "tst_qwebengineglobalsettings"
+ PREFIX
+ "/"
+ FILES
+ ${tst_qwebengineglobalsettings_resource_files}
+)
diff --git a/tests/auto/core/qwebengineglobalsettings/cert/RootCA.pem b/tests/auto/core/qwebengineglobalsettings/cert/RootCA.pem
new file mode 100644
index 000000000..16be384bb
--- /dev/null
+++ b/tests/auto/core/qwebengineglobalsettings/cert/RootCA.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDTzCCAjegAwIBAgIUNYpmREIW67Fh7WNzCwPL6nnSgRMwDQYJKoZIhvcNAQEL
+BQAwNzELMAkGA1UEBhMCREUxKDAmBgNVBAMMH1dlYkVuZ2luZUdsb2JhbFNldHRp
+bmdzLVRlc3QtQ0EwHhcNMjMwMzI5MTYwMzMzWhcNMjYwMTE2MTYwMzMzWjA3MQsw
+CQYDVQQGEwJERTEoMCYGA1UEAwwfV2ViRW5naW5lR2xvYmFsU2V0dGluZ3MtVGVz
+dC1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJhZ9DwcdbVBzMyY
+/nEqt5KUi74LFwEnS0G2ne8IYco9+Pbkpb8wV5u6n43IsQ2c3u8D/KVtu1Vy3tf2
+G3aKOwhFzaj7GWLE9FweZyMoL6ASOtWEa55myT5zAysVQtHAkePu0smAPP0gVq3E
+vjSTwV1W1mVXv4wMwffR8AvNGhKrJIa3L2/uYKGbzEmaCk2kt0vIqfrx8095RlXC
+lUcwTMJ6/d/e/DMDtqQ1ypUuz5QYQybIVKwuqkhojT2DXbitv0rE4HLQub8CxOZ+
+9GcQjeAt8Tzrlp1UP6c9OtlsMoo37gJYzb/XDE6OPnk42chQXDxGQjtVRs+60kcT
+Dx/YHG0CAwEAAaNTMFEwHQYDVR0OBBYEFP1FK1U9CUHQEp7coaab7IdR18zDMB8G
+A1UdIwQYMBaAFP1FK1U9CUHQEp7coaab7IdR18zDMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAGTlcxmRsuwBeRW0CsjX/qbdcB0OWkIC857Jn8RU
+6yGa7P9i6EQb1O/DEF+Z7dkASx5zfN6LPIrph6J56/mmcNBeqArovWJwxQUTNO9i
+1kOU3xoH5n/ya+gdBr3reA90bAMKWXwa6uI3smPJKy+2hOkdDaSBa5KECYWhniH0
+yRxL7YdhQhuCc7Ijf+S6WzeHRwdLkdiV8c2vAGWdunDFuGT2iYVOZ1qbp6O/tmjv
+TxWAnvP4+0ykFIlMor0vYWD8xbnq28263VmNh7mrFwkBYnHJiY/nTDwxaL+g6Uji
+9n6+VuxUDgfQWX1YRHC4a89zI/Zvnn2z/92To7zRmNd73RQ=
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineglobalsettings/cert/localhost.crt b/tests/auto/core/qwebengineglobalsettings/cert/localhost.crt
new file mode 100644
index 000000000..c063bf268
--- /dev/null
+++ b/tests/auto/core/qwebengineglobalsettings/cert/localhost.crt
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDtDCCApygAwIBAgIURotPFTfDJxwaqhZsr0IpAahl2EMwDQYJKoZIhvcNAQEL
+BQAwNzELMAkGA1UEBhMCREUxKDAmBgNVBAMMH1dlYkVuZ2luZUdsb2JhbFNldHRp
+bmdzLVRlc3QtQ0EwHhcNMjMwMzI5MTYwNDI1WhcNMjYwMTE2MTYwNDI1WjB0MQsw
+CQYDVQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xKTAn
+BgNVBAoMIFFXZWJFbmdpbmVHbG9iYWxTZXR0aW5ncy1FeGFtcGxlMRgwFgYDVQQD
+DA9sb2NhbGhvc3QubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCY9FX/8YetuJKSFSoYPxMKPvjt2zJ5g13DywqZtbDzLAIASCxn4iad3qgxaoWB
+uI0g4ykzrhUa98YHU8fDH4T4Vwhwu72SRYW4+MgT9ohc1oCKBX05b+BWSuTSeuHy
+leqdL78bj3bu5TtFs2dJt2t8eA6SNR9lDa5g4v7oA4xVp93gMo2YqZwaLONmxIKY
+cI4lcETnHHsvc6+dB2UqWHJEN75UkdC/XnDLM/VbL3/4zxU+9x34nvvfSJwCHVnE
+u+zYwrZXkbiDVDovT855phVC/K5skVgBL2miz3eygljuw1tIwnmVix/e/xHZyqMg
+Lje/LZN53v5G61Wut6bbdkeVAgMBAAGjezB5MB8GA1UdIwQYMBaAFP1FK1U9CUHQ
+Ep7coaab7IdR18zDMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMB8GA1UdEQQYMBaC
+CWxvY2FsaG9zdIIJMTI3LjAuMC4xMB0GA1UdDgQWBBQv20ImViFtvMm5gHqTeML6
+pi5BtTANBgkqhkiG9w0BAQsFAAOCAQEAGsL7eOms30+IPdKQZ2pjtX22GfM6EiUs
+xsQfsX/Q3bus30B2m9GJ6AVIwVUJimOGiMauDCLjDeXWCMZpihzodExhC0D/X1B+
+FsCLagcjlgfWwekKEo8sUWUZp0DNCyacPtTPxqoS2RA7foEzQhRLViLSvf+UXU8g
+jZAwWGB/5V849zcbbNBcWKzRsPvNOqeENWEn1ByGcsWhas2V0KzRcUODuA9UHv1x
++eDlLZYsWV9c1MuL8a1VDEluIR19eR/Gl9axjPZY2oiPvlp2b7I4z1bY+wV2i6vh
+NeDCAxAxJ42tXeb86vtnVXfSDbzedDbLv0l2kEhcywVN3MwhsEpmpg==
+-----END CERTIFICATE-----
diff --git a/tests/auto/core/qwebengineglobalsettings/cert/localhost.key b/tests/auto/core/qwebengineglobalsettings/cert/localhost.key
new file mode 100644
index 000000000..49502ab9a
--- /dev/null
+++ b/tests/auto/core/qwebengineglobalsettings/cert/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCY9FX/8YetuJKS
+FSoYPxMKPvjt2zJ5g13DywqZtbDzLAIASCxn4iad3qgxaoWBuI0g4ykzrhUa98YH
+U8fDH4T4Vwhwu72SRYW4+MgT9ohc1oCKBX05b+BWSuTSeuHyleqdL78bj3bu5TtF
+s2dJt2t8eA6SNR9lDa5g4v7oA4xVp93gMo2YqZwaLONmxIKYcI4lcETnHHsvc6+d
+B2UqWHJEN75UkdC/XnDLM/VbL3/4zxU+9x34nvvfSJwCHVnEu+zYwrZXkbiDVDov
+T855phVC/K5skVgBL2miz3eygljuw1tIwnmVix/e/xHZyqMgLje/LZN53v5G61Wu
+t6bbdkeVAgMBAAECggEAF7ADX5NivUsv29LORZoDE1ukRoXjX8Ex9MANoLdsM4S1
+vKBwzBfQfjN83cZO7cOMi7LSby//EcGcmAboEXZgq+siof7ZQX1l07snlTvha2tG
+1dk6xvnmBscrf9NLCbwg7P33fUevFhlHICjEDr0KtuiK7Sav+YDwaA3Ph1QBWERd
+GO3sVlnuGsDpf/0GijlwqEGuDKUePEEANOhXcByh693VmvlKVf9SbrimYeunKW1O
+FvvcAiBMzqurhZotb9/juiq+fIMID29OULCCxlZZSySRYw0REpnAAxgWvaSZqyWd
+tGosSKEgc4SptPTmC8DzRDDfN/zqvXmkmYnN9o4qMwKBgQC3tVYdEPn3fHX973Df
+Ukp55cRpZFuNxjOiV3Qo1aTAKqpbmJ4/x8tUL7rhsmJXSxlW7xdNQ/WIHM1PJlZx
+UAIr5eBq1MUVd5OENP8PuVIdAIumHXICB5FioJR/WnXRXLJEbGxSRr5gwaTw3sXd
+ObPRQEUOrJtK+W0aeBKePRtIiwKBgQDVJN7A26vy8PMcE4TcDp75vAY/qasZl6ES
+oksaHf3c4/jsnr70wRoOXi3fPo/DpWmVFylttMSEnzh3nfnOkDXZD3mQx3sdVw8l
+12++t59733hllJZlwqk5OAc990kE1X44UW/gPA+5Vb9kpo6ahpFtqwhDmqa4RjtZ
+0R/1H/KUXwKBgGjR7Qq0rwwJVgHIZ2zlNV2MPp+sBZlFaBzPLZZHILQNJBsTX+gg
+heHJQiaZdAc+8Hxr+624gxZg6LyqsVQCRNrrVTtfn/x5uBANdSNxqGqn7wafcne5
+/bh6y4BHC0akT4s/Gidv+hyXIRfW5Ksvy2wv8bdHwWvsGdaqgGUNlM21AoGAe9Vc
+BbibAh6zYBCHFEL6YiW3i61L1yadUnIwKBBcucVJjk/8qb63ILne9OEoLYcg/Jnk
+W/S2aEcJS5Xg2P44CtBO1KrRAI7gIiA0sB2G7zU6gen+J0kdgDzpGDtflQtktdu6
+oBDFIeyLsjKCj4y3WXwQ5RYo3s8PFHPHmWbiTQkCgYBViqAHaAaPJQZG7Q6/Xqhf
+rFosC0DeZk5PHrEDbpAnuJbySafGZ4LxY5Oq05+aM8BeR+IuGopciBBDWXoh7msO
+N8WItu7WI86lIu7JZRbeju2w59tgj0EA+GyU1udPjTjseP5qpB27X1JEGV6TYBNs
+LMmQSgdGWqwteKsc50UrkA==
+-----END PRIVATE KEY-----
diff --git a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
new file mode 100644
index 000000000..0af85a711
--- /dev/null
+++ b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp
@@ -0,0 +1,121 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest>
+#include <widgetutil.h>
+#include <QWebEngineProfile>
+#include <QWebEnginePage>
+#include <QWebEngineGlobalSettings>
+#include <QWebEngineLoadingInfo>
+
+#include "httpsserver.h"
+#include "httpreqrep.h"
+
+class tst_QWebEngineGlobalSettings : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineGlobalSettings() { }
+ ~tst_QWebEngineGlobalSettings() { }
+
+public Q_SLOTS:
+ void init() { }
+ void cleanup() { }
+
+private Q_SLOTS:
+ void initTestCase() { }
+ void cleanupTestCase() { }
+ void dnsOverHttps_data();
+ void dnsOverHttps();
+};
+
+Q_LOGGING_CATEGORY(lc, "qt.webengine.tests")
+
+void tst_QWebEngineGlobalSettings::dnsOverHttps_data()
+{
+ QTest::addColumn<QWebEngineGlobalSettings::SecureDnsMode>("dnsMode");
+ QTest::addColumn<QString>("uriTemplate");
+ QTest::addColumn<bool>("isMockDnsServerCalledExpected");
+ QTest::addColumn<bool>("isDnsResolutionSuccessExpected");
+ QTest::addColumn<bool>("isConfigurationSuccessExpected");
+ QTest::newRow("DnsMode::SystemOnly (no DoH server)")
+ << QWebEngineGlobalSettings::SecureDnsMode::SystemOnly << QStringLiteral("") << false
+ << true << true;
+ QTest::newRow("DnsMode::SecureOnly (mock DoH server)")
+ << QWebEngineGlobalSettings::SecureDnsMode::SecureOnly
+ << QStringLiteral("https://127.0.0.1:3000/dns-query{?dns}") << true << false << true;
+ QTest::newRow("DnsMode::SecureOnly (real DoH server)")
+ << QWebEngineGlobalSettings::SecureDnsMode::SecureOnly
+ << QStringLiteral("https://dns.google/dns-query{?dns}") << false << true << true;
+ QTest::newRow("DnsMode::SecureOnly (Empty URI Templates)")
+ << QWebEngineGlobalSettings::SecureDnsMode::SecureOnly << QStringLiteral("") << false
+ << false << false;
+ // Note: In the following test, we can't verify that the DoH server is called first and
+ // afterwards insecure DNS is tried, because for the DoH server to ever be used when the DNS
+ // mode is set to DnsMode::WithFallback, Chromium starts an asynchronous DoH server DnsProbe and
+ // requires that the connection is successful. That is, we'd have to implement a correct
+ // DNS response, which in turn requires that certificate errors aren't ignored and
+ // non-self-signed certificates are used for correct encryption. Instead of implementing
+ // all of that, this test verifies that Chromium tries probing the configured DoH server only.
+ QTest::newRow("DnsMode::SecureWithFallback (mock DoH server)")
+ << QWebEngineGlobalSettings::SecureDnsMode::SecureWithFallback
+ << QStringLiteral("https://127.0.0.1:3000/dns-query{?dns}") << true << true << true;
+ QTest::newRow("DnsMode::SecureWithFallback (Empty URI Templates)")
+ << QWebEngineGlobalSettings::SecureDnsMode::SecureWithFallback << QStringLiteral("")
+ << false << false << false;
+}
+
+void tst_QWebEngineGlobalSettings::dnsOverHttps()
+{
+ QFETCH(QWebEngineGlobalSettings::SecureDnsMode, dnsMode);
+ QFETCH(QString, uriTemplate);
+ QFETCH(bool, isMockDnsServerCalledExpected);
+ QFETCH(bool, isDnsResolutionSuccessExpected);
+ QFETCH(bool, isConfigurationSuccessExpected);
+ bool isMockDnsServerCalled = false;
+ bool isLoadSuccessful = false;
+
+ bool configurationSuccess =
+ QWebEngineGlobalSettings::setDnsMode({ dnsMode, QStringList{ uriTemplate } });
+ QCOMPARE(configurationSuccess, isConfigurationSuccessExpected);
+
+ if (!configurationSuccess) {
+ // In this case, DNS has invalid configuration, so the DNS change transaction is not
+ // triggered and the result of the DNS resolution depends on the current DNS mode, which is
+ // set by the previous run of this function.
+ return;
+ }
+ HttpsServer httpsServer(":/cert/localhost.crt", ":/cert/localhost.key", ":/cert/RootCA.pem",
+ 3000, this);
+ QObject::connect(&httpsServer, &HttpsServer::newRequest, this,
+ [&isMockDnsServerCalled](HttpReqRep *rr) {
+ QVERIFY(rr->requestPath().contains(QByteArrayLiteral("/dns-query?dns=")));
+ isMockDnsServerCalled = true;
+ rr->close();
+ });
+ QVERIFY(httpsServer.start());
+ httpsServer.setExpectError(isMockDnsServerCalledExpected);
+ httpsServer.setVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ connect(&page, &QWebEnginePage::loadFinished, this,
+ [&isLoadSuccessful](bool ok) { isLoadSuccessful = ok; });
+
+ page.load(QUrl("https://google.com/"));
+ if (!loadSpy.wait(20000)) {
+ QSKIP("Couldn't load page from network, skipping test.");
+ }
+
+ QTRY_COMPARE(isMockDnsServerCalled, isMockDnsServerCalledExpected);
+ QCOMPARE(isLoadSuccessful, isDnsResolutionSuccessExpected);
+ QVERIFY(httpsServer.stop());
+}
+
+static QByteArrayList params = QByteArrayList() << "--ignore-certificate-errors";
+
+W_QTEST_MAIN(tst_QWebEngineGlobalSettings, params)
+#include "tst_qwebengineglobalsettings.moc"
diff --git a/tests/auto/core/qwebengineloadinginfo/CMakeLists.txt b/tests/auto/core/qwebengineloadinginfo/CMakeLists.txt
new file mode 100644
index 000000000..09d9c30f5
--- /dev/null
+++ b/tests/auto/core/qwebengineloadinginfo/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_test(tst_qwebengineloadinginfo
+ SOURCES
+ tst_qwebengineloadinginfo.cpp
+ LIBRARIES
+ Qt::WebEngineCore
+ Test::HttpServer
+)
diff --git a/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp b/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp
new file mode 100644
index 000000000..ccae7436b
--- /dev/null
+++ b/tests/auto/core/qwebengineloadinginfo/tst_qwebengineloadinginfo.cpp
@@ -0,0 +1,93 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineprofile.h>
+#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineCore/qwebengineloadinginfo.h>
+#include <QtWebEngineCore/qwebenginehttprequest.h>
+#include <QtWebEngineCore/qwebenginesettings.h>
+
+#include <httpserver.h>
+#include <httpreqrep.h>
+
+typedef QMultiMap<QByteArray, QByteArray> Map;
+
+class tst_QWebEngineLoadingInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineLoadingInfo() { }
+
+public slots:
+ void loadingInfoChanged(QWebEngineLoadingInfo loadingInfo)
+ {
+ const auto responseHeaders = loadingInfo.responseHeaders();
+ QFETCH(Map, expected);
+
+ if (loadingInfo.status() == QWebEngineLoadingInfo::LoadSucceededStatus
+ || loadingInfo.status() == QWebEngineLoadingInfo::LoadFailedStatus) {
+ if (!expected.empty())
+ QCOMPARE(responseHeaders, expected);
+ } else {
+ QVERIFY(responseHeaders.size() == 0);
+ }
+ }
+
+private Q_SLOTS:
+ void responseHeaders_data()
+ {
+ QTest::addColumn<int>("responseCode");
+ QTest::addColumn<Map>("input");
+ QTest::addColumn<Map>("expected");
+
+ const Map empty;
+ const Map input {
+ std::make_pair("header1", "value1"),
+ std::make_pair("header2", "value2")
+ };
+ const Map expected {
+ std::make_pair("header1", "value1"),
+ std::make_pair("header2", "value2"),
+ std::make_pair("Connection", "close")
+ };
+
+
+ QTest::newRow("with headers HTTP 200") << 200 << input << expected;
+ QTest::newRow("with headers HTTP 500") << 500 << input << expected;
+ QTest::newRow("without headers HTTP 200") << 200 << empty << empty;
+ QTest::newRow("without headers HTTP 500") << 500 << empty << empty;
+ }
+
+ void responseHeaders()
+ {
+ HttpServer httpServer;
+
+ QFETCH(Map, input);
+ QFETCH(int, responseCode);
+ QObject::connect(&httpServer, &HttpServer::newRequest, this, [&](HttpReqRep *rr) {
+ for (auto it = input.cbegin(); it != input.cend(); ++it)
+ rr->setResponseHeader(it.key(), it.value());
+
+ rr->sendResponse(responseCode);
+ });
+ QVERIFY(httpServer.start());
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+ QObject::connect(&page, &QWebEnginePage::loadingChanged, this, &tst_QWebEngineLoadingInfo::loadingInfoChanged);
+
+
+ QWebEngineHttpRequest request(httpServer.url("/somepage.html"));
+ page.load(request);
+
+ QTRY_VERIFY(spy.count() > 0);
+ QVERIFY(httpServer.stop());
+ }
+};
+
+QTEST_MAIN(tst_QWebEngineLoadingInfo)
+#include "tst_qwebengineloadinginfo.moc"
diff --git a/tests/auto/core/qwebenginesettings/CMakeLists.txt b/tests/auto/core/qwebenginesettings/CMakeLists.txt
index 7f8b49d1b..756b99bbb 100644
--- a/tests/auto/core/qwebenginesettings/CMakeLists.txt
+++ b/tests/auto/core/qwebenginesettings/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebenginesettings
@@ -5,5 +8,6 @@ qt_internal_add_test(tst_qwebenginesettings
tst_qwebenginesettings.cpp
LIBRARIES
Qt::WebEngineCore
+ Qt::WebEngineWidgets
Test::Util
)
diff --git a/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
index 4220f496b..e856dd094 100644
--- a/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
+++ b/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
@@ -27,6 +27,7 @@
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
class tst_QWebEngineSettings: public QObject {
Q_OBJECT
@@ -38,6 +39,10 @@ private Q_SLOTS:
void javascriptClipboard_data();
void javascriptClipboard();
void setInAcceptNavigationRequest();
+ void disableReadingFromCanvas_data();
+ void disableReadingFromCanvas();
+ void forceDarkMode();
+ void forceDarkModeMultiView();
};
void tst_QWebEngineSettings::resetAttributes()
@@ -143,7 +148,7 @@ void tst_QWebEngineSettings::javascriptClipboard()
// - return value of queryCommandEnabled and
// - return value of execCommand
// - comparing the clipboard / input field
- QGuiApplication::clipboard()->clear();
+ QGuiApplication::clipboard()->setText(QString());
QCOMPARE(evaluateJavaScriptSync(&page, "document.queryCommandEnabled('copy')").toBool(),
copyResult);
QCOMPARE(evaluateJavaScriptSync(&page, "document.execCommand('copy')").toBool(), copyResult);
@@ -193,6 +198,110 @@ void tst_QWebEngineSettings::setInAcceptNavigationRequest()
QCOMPARE(toPlainTextSync(&page), QStringLiteral("PASS"));
}
+void tst_QWebEngineSettings::disableReadingFromCanvas_data()
+{
+ QTest::addColumn<bool>("disableReadingFromCanvas");
+ QTest::addColumn<bool>("result");
+ QTest::newRow("disabled") << false << true;
+ QTest::newRow("enabled") << true << false;
+}
+
+void tst_QWebEngineSettings::disableReadingFromCanvas()
+{
+ QFETCH(bool, disableReadingFromCanvas);
+ QFETCH(bool, result);
+
+ QWebEnginePage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::ReadingFromCanvasEnabled,
+ !disableReadingFromCanvas);
+ page.setHtml("<html><body>"
+ "<canvas id='myCanvas' width='200' height='40' style='border:1px solid "
+ "#000000;'></canvas>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(page.settings()->testAttribute(QWebEngineSettings::ReadingFromCanvasEnabled),
+ !disableReadingFromCanvas);
+
+ const QString jsCode("(function(){"
+ " var canvas = document.getElementById(\"myCanvas\");"
+ " var ctx = canvas.getContext(\"2d\");"
+ " ctx.fillStyle = \"rgb(255,0,255)\";"
+ " ctx.fillRect(0, 0, 200, 40);"
+ " try {"
+ " src = canvas.toDataURL();"
+ " }"
+ " catch(err) {"
+ " src = \"\";"
+ " }"
+ " return src.length ? true : false;"
+ "})();");
+ QCOMPARE(evaluateJavaScriptSync(&page, jsCode).toBool(), result);
+}
+
+void tst_QWebEngineSettings::forceDarkMode()
+{
+ QWebEnginePage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+
+ // based on: https://developer.chrome.com/blog/auto-dark-theme/#detecting-auto-dark-theme
+ page.setHtml("<html><body>"
+ "<div id=\"detection\", style=\"display: none; background-color: canvas; color-scheme: light\"</div>"
+ "</body></html>");
+
+ const QString isAutoDark("(() => {"
+ " const detectionDiv = document.querySelector('#detection');"
+ " return getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';"
+ "})()");
+
+ QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, isAutoDark).toBool(), false);
+ page.settings()->setAttribute(QWebEngineSettings::ForceDarkMode, true);
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, isAutoDark).toBool(), true);
+}
+
+void tst_QWebEngineSettings::forceDarkModeMultiView()
+{
+ QWebEngineView view1;
+ QWebEngineView view2;
+ QWebEnginePage *page1 = view1.page();
+ QWebEnginePage *page2 = view2.page();
+ page1->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ page2->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ view1.resize(300,300);
+ view2.resize(300,300);
+ view1.show();
+ view2.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view1));
+ QVERIFY(QTest::qWaitForWindowExposed(&view2));
+
+ QSignalSpy loadFinishedSpy(page1, SIGNAL(loadFinished(bool)));
+ QSignalSpy loadFinishedSpy2(page2, SIGNAL(loadFinished(bool)));
+ QString html("<html><body>"
+ "<div id=\"detection\", style=\"display: none; background-color: canvas; color-scheme: light\"</div>"
+ "</body></html>");
+
+ const QString isAutoDark("(() => {"
+ " const detectionDiv = document.querySelector('#detection');"
+ " return getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';"
+ "})()");
+
+ view1.setHtml(html);
+ QVERIFY(loadFinishedSpy.wait());
+ view2.setHtml(html);
+ QVERIFY(loadFinishedSpy2.wait());
+
+ // both views has light color-scheme
+ QTRY_COMPARE(evaluateJavaScriptSync(page1, isAutoDark).toBool(), false);
+ QTRY_COMPARE(evaluateJavaScriptSync(page2, isAutoDark).toBool(), false);
+ view1.settings()->setAttribute(QWebEngineSettings::ForceDarkMode, true);
+ // dark mode should apply only for view1
+ QTRY_COMPARE(evaluateJavaScriptSync(page1, isAutoDark).toBool(), true);
+ QTRY_COMPARE(evaluateJavaScriptSync(page2, isAutoDark).toBool(), false);
+}
+
QTEST_MAIN(tst_QWebEngineSettings)
#include "tst_qwebenginesettings.moc"
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt b/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt
index 0f8d90a08..c12c0c45c 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
include(../../httpserver/httpserver.cmake)
@@ -6,12 +9,16 @@ qt_internal_add_test(tst_qwebengineurlrequestinterceptor
tst_qwebengineurlrequestinterceptor.cpp
LIBRARIES
Qt::WebEngineCore
+ Qt::WebEngineCorePrivate
+ Qt::CorePrivate
Test::HttpServer
Test::Util
)
set(tst_qwebengineurlrequestinterceptor_resource_files
"resources/content.html"
+ "resources/content2.html"
+ "resources/content3.html"
"resources/favicon.html"
"resources/firstparty.html"
"resources/fontawesome.woff"
@@ -31,6 +38,7 @@ set(tst_qwebengineurlrequestinterceptor_resource_files
"resources/style.css"
"resources/sw.html"
"resources/sw.js"
+ "resources/postBodyFile.txt"
)
qt_internal_add_resource(tst_qwebengineurlrequestinterceptor "tst_qwebengineurlrequestinterceptor"
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html
new file mode 100644
index 000000000..84bf55036
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html
@@ -0,0 +1,6 @@
+<html>
+<head><link rel="icon" href="data:,"></head>
+<body>
+<a>Simple test page without favicon (meaning no separate request from http server)</a>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/postBodyFile.txt b/tests/auto/core/qwebengineurlrequestinterceptor/resources/postBodyFile.txt
new file mode 100644
index 000000000..7729c4e0a
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/postBodyFile.txt
@@ -0,0 +1,3 @@
+{
+"test": "1234"
+}
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html
index af44b45a2..fc3d9ded4 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html
@@ -2,13 +2,40 @@
<html>
<body>
<script>
+ function logState(state) {
+ console.log("Service worker " + state)
+ }
+
+ const registerServiceWorker = async () => {
+ try {
+ var serviceWorker;
+ const registration = await navigator.serviceWorker.register('/sw.js');
+ if (registration.installing) {
+ serviceWorker = registration.installing;
+ } else if (registration.waiting) {
+ serviceWorker = registration.waiting;
+ } else if (registration.active) {
+ serviceWorker = registration.active;
+ }
+ } catch (error) {
+ console.error("Service worker registration error: ${error}");
+ }
+ if (serviceWorker) {
+ logState(serviceWorker.state);
+ serviceWorker.addEventListener('statechange', function(e) {
+ logState(e.target.state);
+ });
+ }
+ };
if ('serviceWorker' in navigator) {
- window.addEventListener('load', function() {
- navigator.serviceWorker.register('/sw.js').then(function(registration) {
- console.log('ServiceWorker registration successful with scope: ', registration.scope);
- }, function(err) {
- console.error('ServiceWorker registration failed: ', err);
- });
+ registerServiceWorker();
+ navigator.serviceWorker.ready.then((registration) => {
+ navigator.serviceWorker.onmessage = (event) => {
+ if (event.data && event.data.type === 'PONG') {
+ console.log("Service worker done");
+ }
+ };
+ registration.active.postMessage({type: 'PING'});
});
}
</script>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js
index 2216e2a07..196a9ad67 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js
@@ -1,3 +1,16 @@
self.addEventListener('install', function(event) {
- console.log('ServiceWorker installed');
+ event.waitUntil(self.skipWaiting());
+});
+
+self.addEventListener('activate', function(event) {
+ event.waitUntil(self.clients.claim());
+});
+self.addEventListener('message', (event) => {
+ if (event.data && event.data.type === 'PING') {
+ self.clients.matchAll({includeUncontrolled: true, type: 'window'}).then((clients) => {
+ if (clients && clients.length) {
+ clients[0].postMessage({type: 'PONG'});
+ }
+ });
+ }
});
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 94669c4ca..7cea14c0c 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -1,38 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#include <util.h>
#include <QtTest/QtTest>
#include <QtWebEngineCore/qwebengineurlrequestinfo.h>
+#include <QtWebEngineCore/private/qwebengineurlrequestinfo_p.h>
#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h>
#include <QtWebEngineCore/qwebenginesettings.h>
#include <QtWebEngineCore/qwebengineprofile.h>
#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineCore/qwebenginehttprequest.h>
#include <httpserver.h>
#include <httpreqrep.h>
@@ -64,12 +43,18 @@ private Q_SLOTS:
void requestInterceptorByResourceType_data();
void requestInterceptorByResourceType();
void firstPartyUrlHttp();
+ void headers();
void customHeaders();
void initiator();
void jsServiceWorker();
void replaceInterceptor_data();
void replaceInterceptor();
void replaceOnIntercept();
+ void multipleRedirects();
+ void postWithBody_data();
+ void postWithBody();
+ void profilePreventsPageInterception_data();
+ void profilePreventsPageInterception();
};
tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
@@ -102,12 +87,14 @@ struct RequestInfo {
, firstPartyUrl(info.firstPartyUrl())
, initiator(info.initiator())
, resourceType(info.resourceType())
+ , headers(info.httpHeaders())
{}
QUrl requestUrl;
QUrl firstPartyUrl;
QUrl initiator;
int resourceType;
+ QHash<QByteArray, QByteArray> headers;
};
static const QUrl kRedirectUrl = QUrl("qrc:///resources/content.html");
@@ -154,7 +141,7 @@ public:
// MEMO avoid unintentionally changing request when it is not needed for test logic
// since api behavior depends on 'changed' state of the info object
- Q_ASSERT(info.changed() == (block || redirect || !headers.empty()));
+ Q_ASSERT(info.changed() == (block || redirect));
}
bool shouldSkipRequest(const RequestInfo &requestInfo)
@@ -202,6 +189,29 @@ public:
}
};
+class TestMultipleRedirectsInterceptor : public QWebEngineUrlRequestInterceptor {
+public:
+ QList<RequestInfo> requestInfos;
+ QMap<QUrl, QUrl> redirectPairs;
+ int redirectCount = 0;
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ QVERIFY(QThread::currentThread() == QCoreApplication::instance()->thread());
+ qCDebug(lc) << this << "Type:" << info.resourceType() << info.requestMethod() << "Navigation:" << info.navigationType()
+ << info.requestUrl() << "Initiator:" << info.initiator();
+ auto redirectUrl = redirectPairs.constFind(info.requestUrl());
+ if (redirectUrl != redirectPairs.constEnd()) {
+ info.redirect(redirectUrl.value());
+ requestInfos.append(info);
+ redirectCount++;
+ }
+ }
+
+ TestMultipleRedirectsInterceptor()
+ {
+ }
+};
+
class ConsolePage : public QWebEnginePage {
Q_OBJECT
public:
@@ -231,7 +241,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl("qrc:///resources/index.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
QVariant success = loadSpy.takeFirst().takeFirst();
QVERIFY(success.toBool());
loadSpy.clear();
@@ -239,7 +249,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
page.runJavaScript("post();", [&ok](const QVariant result){ ok = result; });
QTRY_VERIFY(ok.toBool());
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
success = loadSpy.takeFirst().takeFirst();
// We block non-GET requests, so this should not succeed.
QVERIFY(!success.toBool());
@@ -247,22 +257,22 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
interceptor.shouldRedirect = true;
page.load(QUrl("qrc:///resources/__placeholder__"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
success = loadSpy.takeFirst().takeFirst();
// The redirection for __placeholder__ should succeed.
QVERIFY(success.toBool());
loadSpy.clear();
- QCOMPARE(interceptor.requestInfos.count(), 4);
+ QCOMPARE(interceptor.requestInfos.size(), 4);
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
profile.setUrlRequestInterceptor(&observer);
page.load(QUrl("qrc:///resources/__placeholder__"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
success = loadSpy.takeFirst().takeFirst();
// Since we do not intercept, loading an invalid path should not succeed.
QVERIFY(!success.toBool());
- QCOMPARE(observer.requestInfos.count(), 1);
+ QCOMPARE(observer.requestInfos.size(), 1);
}
class LocalhostContentProvider : public QWebEngineUrlRequestInterceptor
@@ -295,15 +305,15 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));
page.setHtml("<p>Hi", QUrl::fromEncoded("http://[::1]/index.html"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QCOMPARE(contentProvider.requestedUrls.count(), 0);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
+ QCOMPARE(contentProvider.requestedUrls.size(), 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.size(), 1);
QCOMPARE(contentProvider.requestedUrls.at(0), QUrl::fromEncoded("http://[::1]/test.xml"));
}
@@ -331,8 +341,8 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
- QTRY_COMPARE(spy.count(), 1);
- QVERIFY(interceptor.requestInfos.count() >= 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
+ QVERIFY(interceptor.requestInfos.size() >= 1);
QCOMPARE(interceptor.requestInfos.at(0).requestUrl, QUrl("qrc:///resources/content.html"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
@@ -340,15 +350,15 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
interceptor.shouldRedirect = false;
page.setUrl(QUrl("qrc:/non-existent.html"));
- QTRY_COMPARE(spy.count(), 2);
- QVERIFY(interceptor.requestInfos.count() >= 3);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
+ QVERIFY(interceptor.requestInfos.size() >= 3);
QCOMPARE(interceptor.requestInfos.at(2).requestUrl, 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"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 3, 15000);
- QVERIFY(interceptor.requestInfos.count() >= 4);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 3, 20000);
+ QVERIFY(interceptor.requestInfos.size() >= 4);
QCOMPARE(interceptor.requestInfos.at(3).requestUrl, QUrl("http://abcdef.abcdef/"));
QCOMPARE(page.requestedUrl(), QUrl("qrc:///resources/__placeholder__"));
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
@@ -376,23 +386,23 @@ void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
// Now a case without redirect.
page.setUrl(QUrl("qrc:///resources/content.html"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
QVERIFY(spy.wait());
QCOMPARE(page.url(), QUrl("qrc:///resources/content.html"));
- QCOMPARE(spy.count(), 4);
+ QCOMPARE(spy.size(), 4);
}
void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
@@ -406,12 +416,12 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
page.setUrl(QUrl("qrc:///resources/firstparty.html"));
QVERIFY(spy.wait());
- QVERIFY(interceptor.requestInfos.count() >= 2);
+ QVERIFY(interceptor.requestInfos.size() >= 2);
QCOMPARE(interceptor.requestInfos.at(0).requestUrl, QUrl("qrc:///resources/firstparty.html"));
QCOMPARE(interceptor.requestInfos.at(1).requestUrl, QUrl("qrc:///resources/content.html"));
QCOMPARE(interceptor.requestInfos.at(0).firstPartyUrl, QUrl("qrc:///resources/firstparty.html"));
QCOMPARE(interceptor.requestInfos.at(1).firstPartyUrl, QUrl("qrc:///resources/firstparty.html"));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes_data()
@@ -444,21 +454,21 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes()
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(requestUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
- QVERIFY(interceptor.requestInfos.count() >= 1);
+ QVERIFY(interceptor.requestInfos.size() >= 1);
RequestInfo info = interceptor.requestInfos.at(0);
QCOMPARE(info.requestUrl, requestUrl);
QCOMPARE(info.firstPartyUrl, requestUrl);
QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeMainFrame);
- QVERIFY(interceptor.requestInfos.count() >= 2);
+ QVERIFY(interceptor.requestInfos.size() >= 2);
info = interceptor.requestInfos.at(1);
QCOMPARE(info.requestUrl, QUrl(adjustedUrl + "iframe2.html"));
QCOMPARE(info.firstPartyUrl, requestUrl);
QCOMPARE(info.resourceType, QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
- QVERIFY(interceptor.requestInfos.count() >= 3);
+ QVERIFY(interceptor.requestInfos.size() >= 3);
info = interceptor.requestInfos.at(2);
QCOMPARE(info.requestUrl, QUrl(adjustedUrl + "iframe3.html"));
QCOMPARE(info.firstPartyUrl, requestUrl);
@@ -534,11 +544,11 @@ void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType()
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(firstPartyUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
- QTRY_COMPARE(interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)).count(), 1);
+ QTRY_COMPARE(interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)).size(), 1);
QList<RequestInfo> infos = interceptor.getUrlRequestForType(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType));
- QVERIFY(infos.count() >= 1);
+ QVERIFY(infos.size() >= 1);
QCOMPARE(infos.at(0).requestUrl, requestUrl);
QCOMPARE(infos.at(0).firstPartyUrl, firstPartyUrl);
QCOMPARE(infos.at(0).resourceType, resourceType);
@@ -602,6 +612,40 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
QCOMPARE(info.firstPartyUrl, firstPartyUrl);
}
+void tst_QWebEngineUrlRequestInterceptor::headers()
+{
+ HttpServer httpServer;
+ httpServer.setResourceDirs({ QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() + "/resources" });
+ QVERIFY(httpServer.start());
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(false);
+ profile.setUrlRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ QWebEngineHttpRequest request(httpServer.url("/content.html"));
+ request.setHeader("X-HEADERNAME", "HEADERVALUE");
+ page.load(request);
+ QVERIFY(spy.wait());
+ QVERIFY(interceptor.requestInfos.last().headers.contains("X-HEADERNAME"));
+ QCOMPARE(interceptor.requestInfos.last().headers.value("X-HEADERNAME"),
+ QByteArray("HEADERVALUE"));
+
+ bool jsFinished = false;
+
+ page.runJavaScript(R"(
+var request = new XMLHttpRequest();
+request.open('GET', 'resource.html', /* async = */ false);
+request.setRequestHeader('X-FOO', 'BAR');
+request.send();
+)",
+ [&](const QVariant &) { jsFinished = true; });
+ QTRY_VERIFY(jsFinished);
+ QVERIFY(interceptor.requestInfos.last().headers.contains("X-FOO"));
+ QCOMPARE(interceptor.requestInfos.last().headers.value("X-FOO"), QByteArray("BAR"));
+}
+
void tst_QWebEngineUrlRequestInterceptor::customHeaders()
{
// Create HTTP Server to parse the request.
@@ -726,8 +770,7 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
HttpServer server;
server.setResourceDirs({ QDir(QT_TESTCASE_SOURCEDIR).canonicalPath() + "/resources" });
QVERIFY(server.start());
-
- QWebEngineProfile profile(QStringLiteral("Test"));
+ QWebEngineProfile profile;
std::unique_ptr<ConsolePage> page;
page.reset(new ConsolePage(&profile));
TestRequestInterceptor interceptor(/* intercept */ false);
@@ -735,10 +778,17 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
QVERIFY(loadSync(page.get(), server.url("/sw.html")));
// We expect only one message here, because logging of services workers is not exposed in our API.
- QTRY_COMPARE(page->messages.count(), 1);
- QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel);
+ // Note this is very fragile setup , you need fresh profile otherwise install event might not get triggered
+ // and this in turn can lead to incorrect intercepted requests, therefore we should keep this off the record.
+ QTRY_COMPARE_WITH_TIMEOUT(page->messages.size(), 5, 20000);
- QUrl firstPartyUrl = QUrl(server.url().toString() + "sw.js");
+ QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel);
+ QCOMPARE(page->messages.at(0),QLatin1String("Service worker installing"));
+ QCOMPARE(page->messages.at(1),QLatin1String("Service worker installed"));
+ QCOMPARE(page->messages.at(2),QLatin1String("Service worker activating"));
+ QCOMPARE(page->messages.at(3),QLatin1String("Service worker activated"));
+ QCOMPARE(page->messages.at(4),QLatin1String("Service worker done"));
+ QUrl firstPartyUrl = QUrl(server.url().toString() + "sw.html");
QList<RequestInfo> infos;
// Service Worker
QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker));
@@ -804,7 +854,7 @@ void tst_QWebEngineUrlRequestInterceptor::replaceInterceptor()
});
page.setUrl(server.url("/favicon.html"));
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
QTRY_VERIFY(fetchFinished);
QString s; QDebug d(&s);
@@ -848,7 +898,7 @@ void tst_QWebEngineUrlRequestInterceptor::replaceOnIntercept()
};
page.setUrl(server.url("/favicon.html"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QTRY_COMPARE(profileInterceptor.requestInfos.size(), 2);
// if interceptor for page was replaced on intercept call in profile then, since request first
@@ -869,5 +919,204 @@ void tst_QWebEngineUrlRequestInterceptor::replaceOnIntercept()
QCOMPARE(profileInterceptor.requestInfos.size(), pageInterceptor2.requestInfos.size());
}
+void tst_QWebEngineUrlRequestInterceptor::multipleRedirects()
+{
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ QVERIFY(server.start());
+
+ TestMultipleRedirectsInterceptor multiInterceptor;
+ multiInterceptor.redirectPairs.insert(QUrl(server.url("/content.html")), QUrl(server.url("/content2.html")));
+ multiInterceptor.redirectPairs.insert(QUrl(server.url("/content2.html")), QUrl(server.url("/content3.html")));
+
+ QWebEngineProfile profile;
+ profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ profile.setUrlRequestInterceptor(&multiInterceptor);
+ QWebEnginePage page(&profile);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setUrl(server.url("/content.html"));
+
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE(multiInterceptor.redirectCount, 2);
+ QTRY_COMPARE(multiInterceptor.requestInfos.size(), 2);
+}
+
+class TestPostRequestInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ TestPostRequestInterceptor(QString expected, bool isAppendFile, QObject *parent = nullptr)
+ : QWebEngineUrlRequestInterceptor(parent)
+ , m_expected(expected)
+ , m_isAppendFile(isAppendFile)
+ {};
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ info.block(true);
+ isCalled = true;
+
+ QIODevice *requestBodyDevice = info.requestBody();
+
+ if (m_isAppendFile) {
+ info.d_ptr->appendFileToResourceRequestBodyForTest(":/resources/postBodyFile.txt");
+ }
+
+ requestBodyDevice->open(QIODevice::ReadOnly);
+
+ const QString webKitBoundary = requestBodyDevice->read(40);
+ QVERIFY(webKitBoundary.contains("------WebKitFormBoundary"));
+
+ const QString fullBodyWithoutBoundaries = (webKitBoundary + requestBodyDevice->readAll())
+ .replace(webKitBoundary, "")
+ .replace("\r", "")
+ .replace("\n", "")
+ .replace(" ", "");
+
+ QCOMPARE(fullBodyWithoutBoundaries, m_expected);
+
+ requestBodyDevice->close();
+ }
+
+ bool isCalled = false;
+ QString m_expected;
+ bool m_isAppendFile;
+};
+
+void tst_QWebEngineUrlRequestInterceptor::postWithBody_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+ QTest::addColumn<bool>("isAppendFile");
+ QTest::addRow("FormData append (DataElementByte)")
+ << "fd.append('userId', 1);"
+ "fd.append('title',' Test123');"
+ "fd.append('completed', false);"
+ << "Content-Disposition:form-data;name=\"userId"
+ "\"1Content-Disposition:form-data"
+ ";name=\"title\"Test123Content-Di"
+ "sposition:form-data;name=\"completed\"f"
+ "alse--"
+ << false;
+ QTest::addRow("FormData blob (DataElementPipe)")
+ << "const blob1 = new Blob(['blob1thisisablob'],"
+ "{type: 'text/plain'});"
+ "fd.append('blob1', blob1);"
+ << "Content-Disposition:form-data;name=\"blob1"
+ "\";filename=\"blob\"Content-Type:text/plai"
+ "nblob1thisisablob--"
+ << false;
+ QTest::addRow("Append file (DataElementFile)") << ""
+ << "--{\"test\":\"1234\"}\"1234\"}" << true;
+ QTest::addRow("All combined") << "fd.append('userId', 1);"
+ "fd.append('title', 'Test123');"
+ "fd.append('completed', false);"
+ "const blob1 = new Blob(['blob1thisisablob'],"
+ "{type: 'text/plain'});"
+ "const blob2 = new Blob(['blob2thisisanotherblob'],"
+ "{type: 'text/plain'});"
+ "fd.append('blob1', blob1);"
+ "fd.append('userId', 2);"
+ "fd.append('title', 'Test456');"
+ "fd.append('completed', true);"
+ "fd.append('blob2', blob2);"
+ << "Content-Disposition:form-data;name=\"userId\""
+ "1Content-Disposition:form-data;na"
+ "me=\"title\"Test123Content-Disposit"
+ "ion:form-data;name=\"completed\"false"
+ "Content-Disposition:form-data;name=\"blob1\";"
+ "filename=\"blob\"Content-Type:text/plain"
+ "blob1thisisablobContent-Disposition:form-"
+ "data;name=\"userId\"2Content-Dispos"
+ "ition:form-data;name=\"title\"Test456"
+ "Content-Disposition:form-data;name=\"complete"
+ "d\"trueContent-Disposition:form-da"
+ "ta;name=\"blob2\";filename=\"blob\"Content-Ty"
+ "pe:text/plainblob2thisisanotherblob--"
+ "{\"test\":\"1234\"}\"1234\"}"
+ << true;
+}
+
+void tst_QWebEngineUrlRequestInterceptor::postWithBody()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+ QFETCH(bool, isAppendFile);
+
+ QString script;
+ script.append("const fd = new FormData();");
+ script.append(input);
+ script.append("fetch('http://127.0.0.1', {method: 'POST',body: fd});");
+
+ QWebEngineProfile profile;
+ profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ TestPostRequestInterceptor interceptor(output, isAppendFile);
+ profile.setUrlRequestInterceptor(&interceptor);
+ QWebEnginePage page(&profile);
+ bool ok = false;
+
+ page.runJavaScript(script, [&ok](const QVariant) { ok = true; });
+
+ QTRY_VERIFY(ok);
+ QVERIFY(interceptor.isCalled);
+}
+
+class PageOrProfileInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ PageOrProfileInterceptor(const QString &profileAction)
+ : profileAction(profileAction)
+ {
+ }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override
+ {
+ if (profileAction == "block")
+ info.block(true);
+ else if (profileAction == "redirect")
+ info.redirect(QUrl("data:text/html,<p>redirected"));
+ else if (profileAction == "add header")
+ info.setHttpHeader("Custom-Header", "Value");
+ else
+ QVERIFY(info.httpHeaders().contains("Custom-Header"));
+ ran = true;
+ }
+
+ QString profileAction;
+ bool ran = false;
+};
+
+void tst_QWebEngineUrlRequestInterceptor::profilePreventsPageInterception_data()
+{
+ QTest::addColumn<QString>("profileAction");
+ QTest::addColumn<bool>("interceptInProfile");
+ QTest::addColumn<bool>("interceptInPage");
+ QTest::newRow("block") << "block" << true << false;
+ QTest::newRow("redirect") << "redirect" << true << false;
+ QTest::newRow("add header") << "add header" << true << true;
+}
+
+void tst_QWebEngineUrlRequestInterceptor::profilePreventsPageInterception()
+{
+ QFETCH(QString, profileAction);
+ QFETCH(bool, interceptInProfile);
+ QFETCH(bool, interceptInPage);
+
+ QWebEngineProfile profile;
+ PageOrProfileInterceptor profileInterceptor(profileAction);
+ profile.setUrlRequestInterceptor(&profileInterceptor);
+ profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+
+ QWebEnginePage page(&profile);
+ PageOrProfileInterceptor pageInterceptor("");
+ page.setUrlRequestInterceptor(&pageInterceptor);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.load(QUrl("qrc:///resources/index.html"));
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QCOMPARE(profileInterceptor.ran, interceptInProfile);
+ QCOMPARE(pageInterceptor.ran, interceptInPage);
+}
+
QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/core/qwebengineurlrequestjob/CMakeLists.txt b/tests/auto/core/qwebengineurlrequestjob/CMakeLists.txt
new file mode 100644
index 000000000..02b668313
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestjob/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_test(tst_qwebengineurlrequestjob
+ SOURCES
+ tst_qwebengineurlrequestjob.cpp
+ LIBRARIES
+ Qt::WebEngineCore
+)
+
+# Resources:
+set(tst_qwebengineurlrequestjob_resource_files
+ "additionalResponseHeadersScript.html"
+ "requestBodyScript.html"
+)
+
+qt_add_resources(tst_qwebengineurlrequestjob "tst_qwebengineurlrequestjob"
+ PREFIX
+ "/"
+ FILES
+ ${tst_qwebengineurlrequestjob_resource_files}
+)
diff --git a/tests/auto/core/qwebengineurlrequestjob/additionalResponseHeadersScript.html b/tests/auto/core/qwebengineurlrequestjob/additionalResponseHeadersScript.html
new file mode 100644
index 000000000..a1b8a92d3
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestjob/additionalResponseHeadersScript.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<html>
+<body>
+ <script type="text/javascript">
+ var request = new XMLHttpRequest();
+ request.open('GET', 'additionalresponseheadershandler:about', /* async = */ false);
+ request.send();
+ var headers = request.getAllResponseHeaders();
+ console.log("TST_ADDITIONALRESPONSEHEADERS;" + headers);
+ </script>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestjob/requestBodyScript.html b/tests/auto/core/qwebengineurlrequestjob/requestBodyScript.html
new file mode 100644
index 000000000..95b7ff1bf
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestjob/requestBodyScript.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<html>
+<body>
+ <script type="text/javascript">
+ var request = new XMLHttpRequest();
+ request.open('POST', 'requestbodyhandler:about', /* async = */ false);
+ request.setRequestHeader('Content-Type', 'text/plain');
+ request.send('reading request body successful');
+ console.log("TST_REQUESTBODY;" + request.response);
+ </script>
+</body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp b/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
new file mode 100644
index 000000000..d48da2c44
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestjob/tst_qwebengineurlrequestjob.cpp
@@ -0,0 +1,187 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/QtTest>
+#include <QtWebEngineCore/qwebengineurlschemehandler.h>
+#include <QtWebEngineCore/qwebengineurlscheme.h>
+#include <QtWebEngineCore/qwebengineurlrequestjob.h>
+#include <QtWebEngineCore/qwebengineprofile.h>
+#include <QtWebEngineCore/qwebenginepage.h>
+
+class CustomPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ CustomPage(QWebEngineProfile *profile, QString compareStringPrefix, QString compareStringSuffix,
+ QObject *parent = nullptr)
+ : QWebEnginePage(profile, parent)
+ , m_compareStringPrefix(compareStringPrefix)
+ , m_compareStringSuffix(compareStringSuffix)
+ , m_comparedMessageCount(0)
+ {
+ }
+
+ int comparedMessageCount() const { return m_comparedMessageCount; }
+
+signals:
+ void receivedMessage();
+
+protected:
+ void javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level,
+ const QString &message, int lineNumber,
+ const QString &sourceID) override
+ {
+ Q_UNUSED(level);
+ Q_UNUSED(lineNumber);
+ Q_UNUSED(sourceID);
+
+ auto splitMessage = message.split(";");
+ if (splitMessage[0] == m_compareStringPrefix) {
+ QCOMPARE(splitMessage[1], m_compareStringSuffix);
+ m_comparedMessageCount++;
+ emit receivedMessage();
+ }
+ }
+
+private:
+ QString m_compareStringPrefix;
+ QString m_compareStringSuffix;
+ int m_comparedMessageCount;
+};
+
+class AdditionalResponseHeadersHandler : public QWebEngineUrlSchemeHandler
+{
+ Q_OBJECT
+public:
+ AdditionalResponseHeadersHandler(bool addAdditionalResponseHeaders, QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ , m_addAdditionalResponseHeaders(addAdditionalResponseHeaders)
+ {
+ }
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QCOMPARE(job->requestUrl(), QUrl(schemeName + ":about"));
+
+ QMultiMap<QByteArray, QByteArray> additionalResponseHeaders;
+ if (m_addAdditionalResponseHeaders) {
+ additionalResponseHeaders.insert(QByteArray::fromStdString("test1"),
+ QByteArray::fromStdString("test1VALUE"));
+ additionalResponseHeaders.insert(QByteArray::fromStdString("test2"),
+ QByteArray::fromStdString("test2VALUE"));
+ }
+ job->setAdditionalResponseHeaders(additionalResponseHeaders);
+
+ QFile *file = new QFile(QStringLiteral(":additionalResponseHeadersScript.html"), job);
+ file->open(QIODevice::ReadOnly);
+
+ job->reply(QByteArrayLiteral("text/html"), file);
+ }
+
+ static void registerUrlScheme()
+ {
+ QWebEngineUrlScheme webUiScheme(schemeName);
+ webUiScheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(webUiScheme);
+ }
+
+ const static inline QByteArray schemeName =
+ QByteArrayLiteral("additionalresponseheadershandler");
+
+private:
+ bool m_addAdditionalResponseHeaders;
+};
+
+class RequestBodyHandler : public QWebEngineUrlSchemeHandler
+{
+ Q_OBJECT
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QCOMPARE(job->requestUrl(), QUrl(schemeName + ":about"));
+ QCOMPARE(job->requestMethod(), QByteArrayLiteral("POST"));
+
+ QIODevice *requestBodyDevice = job->requestBody();
+ requestBodyDevice->open(QIODevice::ReadOnly);
+ QByteArray requestBody = requestBodyDevice->readAll();
+ requestBodyDevice->close();
+
+ QBuffer *buf = new QBuffer(job);
+ buf->open(QBuffer::ReadWrite);
+ buf->write(requestBody);
+ job->reply(QByteArrayLiteral("text/plain"), buf);
+ buf->close();
+ }
+
+ static void registerUrlScheme()
+ {
+ QWebEngineUrlScheme webUiScheme(schemeName);
+ webUiScheme.setFlags(QWebEngineUrlScheme::CorsEnabled
+ | QWebEngineUrlScheme::FetchApiAllowed);
+ QWebEngineUrlScheme::registerScheme(webUiScheme);
+ }
+
+ const static inline QByteArray schemeName = QByteArrayLiteral("requestbodyhandler");
+};
+
+class tst_QWebEngineUrlRequestJob : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebEngineUrlRequestJob() { }
+
+private Q_SLOTS:
+ void initTestCase()
+ {
+ AdditionalResponseHeadersHandler::registerUrlScheme();
+ RequestBodyHandler::registerUrlScheme();
+ }
+
+ void withAdditionalResponseHeaders_data()
+ {
+ QTest::addColumn<bool>("withHeaders");
+ QTest::addColumn<QString>("expectedHeaders");
+ QTest::newRow("headers enabled")
+ << true << "content-type: text/html\r\ntest1: test1value\r\ntest2: test2value\r\n";
+ QTest::newRow("headers disabled") << false << "content-type: text/html\r\n";
+ }
+
+ void withAdditionalResponseHeaders()
+ {
+ QFETCH(bool, withHeaders);
+ QFETCH(QString, expectedHeaders);
+
+ QWebEngineProfile profile;
+
+ AdditionalResponseHeadersHandler handler(withHeaders);
+ profile.installUrlSchemeHandler(AdditionalResponseHeadersHandler::schemeName, &handler);
+
+ CustomPage page(&profile, "TST_ADDITIONALRESPONSEHEADERS", expectedHeaders);
+ QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
+
+ page.load(QUrl("qrc:///additionalResponseHeadersScript.html"));
+ QVERIFY(spy.wait());
+ QCOMPARE(page.comparedMessageCount(), 1);
+ }
+
+ void requestBody()
+ {
+ QWebEngineProfile profile;
+
+ RequestBodyHandler handler;
+ profile.installUrlSchemeHandler(RequestBodyHandler::schemeName, &handler);
+
+ const QString expected = "reading request body successful";
+ CustomPage page(&profile, "TST_REQUESTBODY", expected);
+ QSignalSpy spy(&page, SIGNAL(receivedMessage()));
+
+ page.load(QUrl("qrc:///requestBodyScript.html"));
+ QVERIFY(spy.wait());
+ QCOMPARE(page.comparedMessageCount(), 1);
+ }
+};
+
+QTEST_MAIN(tst_QWebEngineUrlRequestJob)
+#include "tst_qwebengineurlrequestjob.moc"
diff --git a/tests/auto/core/webenginedriver/CMakeLists.txt b/tests/auto/core/webenginedriver/CMakeLists.txt
new file mode 100644
index 000000000..c8cf8b3ab
--- /dev/null
+++ b/tests/auto/core/webenginedriver/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_webenginedriver LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(test)
+add_subdirectory(browser)
+
+add_dependencies(tst_webenginedriver
+ testbrowser
+)
diff --git a/tests/auto/core/webenginedriver/browser/CMakeLists.txt b/tests/auto/core/webenginedriver/browser/CMakeLists.txt
new file mode 100644
index 000000000..25e162e7b
--- /dev/null
+++ b/tests/auto/core/webenginedriver/browser/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_executable(testbrowser
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+ OUTPUT_DIRECTORY
+ ${CMAKE_CURRENT_BINARY_DIR}/..
+)
diff --git a/tests/auto/core/webenginedriver/browser/main.cpp b/tests/auto/core/webenginedriver/browser/main.cpp
new file mode 100644
index 000000000..4b8f3513f
--- /dev/null
+++ b/tests/auto/core/webenginedriver/browser/main.cpp
@@ -0,0 +1,21 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
+#include <QtWidgets/qapplication.h>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QWebEngineView view;
+ QObject::connect(view.page(), &QWebEnginePage::windowCloseRequested, &app, &QApplication::quit);
+ QObject::connect(&app, &QApplication::aboutToQuit,
+ []() { fprintf(stderr, "Test browser is about to quit.\n"); });
+
+ view.resize(100, 100);
+ view.show();
+
+ return app.exec();
+}
diff --git a/tests/auto/core/webenginedriver/resources/input.html b/tests/auto/core/webenginedriver/resources/input.html
new file mode 100644
index 000000000..c21458350
--- /dev/null
+++ b/tests/auto/core/webenginedriver/resources/input.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+ <input type="text" id="text_input">
+</body>
+</html>
diff --git a/tests/auto/core/webenginedriver/test/CMakeLists.txt b/tests/auto/core/webenginedriver/test/CMakeLists.txt
new file mode 100644
index 000000000..041bf955b
--- /dev/null
+++ b/tests/auto/core/webenginedriver/test/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../../util/util.cmake)
+
+qt_internal_add_test(tst_webenginedriver
+ SOURCES
+ ../tst_webenginedriver.cpp
+ LIBRARIES
+ Qt::Network
+ Qt::WebEngineCore
+ Qt::WebEngineWidgets
+ Test::Util
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.."
+)
+
+set(tst_webenginedriver_resource_files
+ "../resources/input.html"
+)
+
+qt_internal_add_resource(tst_webenginedriver "tst_webenginedriver"
+ PREFIX
+ "/"
+ FILES
+ ${tst_webenginedriver_resource_files}
+)
diff --git a/tests/auto/core/webenginedriver/tst_webenginedriver.cpp b/tests/auto/core/webenginedriver/tst_webenginedriver.cpp
new file mode 100644
index 000000000..cd3098b25
--- /dev/null
+++ b/tests/auto/core/webenginedriver/tst_webenginedriver.cpp
@@ -0,0 +1,631 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/QtTest>
+
+#include <QtCore/qjsondocument.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qprocess.h>
+#include <QtGui/qimage.h>
+#include <QtNetwork/qnetworkaccessmanager.h>
+#include <QtNetwork/qnetworkreply.h>
+#include <QtNetwork/qnetworkrequest.h>
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/qwebenginepage.h>
+#include <QtWebEngineCore/qwebengineprofile.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
+
+#include <widgetutil.h>
+
+#define REMOTE_DEBUGGING_PORT 12345
+#define WEBENGINEDRIVER_PORT 9515
+
+class DriverServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ DriverServer(QProcessEnvironment processEnvironment = {}, QStringList processArguments = {})
+ : m_serverURL(QUrl(
+ QLatin1String("http://localhost:%1").arg(QString::number(WEBENGINEDRIVER_PORT))))
+ {
+ QString driverPath = QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath)
+ + QLatin1String("/webenginedriver");
+#if defined(Q_OS_WIN)
+ driverPath += QLatin1String(".exe");
+#endif
+ m_process.setProgram(driverPath);
+
+ if (processArguments.isEmpty())
+ processArguments
+ << QLatin1String("--port=%1").arg(QString::number(WEBENGINEDRIVER_PORT));
+ m_process.setArguments(processArguments);
+
+ if (!processEnvironment.isEmpty())
+ m_process.setProcessEnvironment(processEnvironment);
+
+ connect(&m_process, &QProcess::errorOccurred, [this](QProcess::ProcessError error) {
+ qWarning() << "WebEngineDriver error occurred:" << error;
+ dumpConsoleMessages();
+ });
+
+ connect(&m_process, &QProcess::readyReadStandardError, [this]() {
+ QProcess::ProcessChannel tmp = m_process.readChannel();
+ m_process.setReadChannel(QProcess::StandardError);
+ while (m_process.canReadLine()) {
+ QString line = QString::fromUtf8(m_process.readLine());
+ if (line.endsWith(QLatin1Char('\n')))
+ line.truncate(line.size() - 1);
+ m_stderr << line;
+ }
+ m_process.setReadChannel(tmp);
+ });
+
+ connect(&m_process, &QProcess::readyReadStandardOutput, [this]() {
+ QProcess::ProcessChannel tmp = m_process.readChannel();
+ m_process.setReadChannel(QProcess::StandardOutput);
+ while (m_process.canReadLine()) {
+ QString line = QString::fromUtf8(m_process.readLine());
+ if (line.endsWith(QLatin1Char('\n')))
+ line.truncate(line.size() - 1);
+ m_stdout << line;
+ }
+ m_process.setReadChannel(tmp);
+ });
+ }
+
+ ~DriverServer()
+ {
+ if (m_process.state() != QProcess::Running)
+ return;
+
+ if (!m_sessionId.isEmpty())
+ deleteSession();
+
+ shutdown();
+ }
+
+ bool start()
+ {
+ if (!QFileInfo::exists(m_process.program())) {
+ qWarning() << "WebEngineDriver executable not found:" << m_process.program();
+ return false;
+ }
+
+ connect(&m_process, &QProcess::finished,
+ [this](int exitCode, QProcess::ExitStatus exitStatus) {
+ qWarning().nospace()
+ << "WebEngineDriver exited unexpectedly (exitCode: " << exitCode
+ << " exitStatus: " << exitStatus << "):";
+ dumpConsoleMessages();
+ });
+
+ m_process.start();
+
+ bool started = m_process.waitForStarted();
+ if (!started) {
+ qWarning() << "Failed to start WebEngineDriver:" << m_process.errorString();
+ return false;
+ }
+
+ bool ready = QTest::qWaitFor(
+ [this]() {
+ if (m_process.state() != QProcess::Running)
+ return true;
+
+ for (QString line : m_stdout) {
+ if (line.contains(
+ QLatin1String("WebEngineDriver was started successfully.")))
+ return true;
+ }
+
+ return false;
+ },
+ 10000);
+
+ if (ready && m_process.state() != QProcess::Running) {
+ // Warning is already reported by handler of QProcess::finished() signal.
+ return false;
+ }
+
+ if (!ready) {
+ if (m_stdout.empty())
+ qWarning("Starting WebEngineDriver timed out.");
+ else
+ qWarning("Something went wrong while starting WebEngineDriver:");
+
+ dumpConsoleMessages();
+ return false;
+ }
+
+ return true;
+ }
+
+ bool shutdown()
+ {
+ // Do not warn about unexpected exit.
+ disconnect(&m_process, &QProcess::finished, nullptr, nullptr);
+
+ bool sent = sendCommand(QLatin1String("/shutdown"));
+
+ bool finished = (m_process.state() == QProcess::NotRunning) || m_process.waitForFinished();
+ if (!finished || !sent)
+ qWarning() << "Failed to properly shutdown WebEngineDriver:" << m_process.errorString();
+
+ return finished;
+ }
+
+ bool sendCommand(QString command, const QJsonDocument &params = {},
+ QJsonDocument *result = nullptr)
+ {
+ if (command.contains(QLatin1String(":sessionId"))) {
+ if (m_sessionId.isEmpty()) {
+ qWarning("Unable to execute session command without session.");
+ return false;
+ }
+
+ QStringList commandList = command.split(QLatin1Char('/'));
+ for (int i = 0; i < commandList.size(); ++i) {
+ if (commandList[i] == QLatin1String(":sessionId")) {
+ commandList[i] = m_sessionId;
+ break;
+ }
+ }
+
+ command = commandList.join(QLatin1Char('/'));
+ }
+
+ QNetworkReply::NetworkError replyError = QNetworkReply::NoError;
+ QString replyString;
+
+ connect(
+ &m_qnam, &QNetworkAccessManager::finished, this,
+ [&replyError, &replyString](QNetworkReply *reply) {
+ replyError = reply->error();
+ replyString = QString::fromUtf8(reply->readAll());
+ },
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+
+ QNetworkRequest request;
+ QUrl requestURL = m_serverURL;
+
+ requestURL.setPath(command);
+ request.setUrl(requestURL);
+
+ if (params.isEmpty()) {
+ m_qnam.get(request);
+ } else {
+ request.setHeader(QNetworkRequest::ContentTypeHeader,
+ QVariant::fromValue(QStringLiteral("application/json")));
+ m_qnam.post(request, params.toJson(QJsonDocument::Compact));
+ }
+
+ bool ready = QTest::qWaitFor(
+ [&replyError, &replyString]() {
+ return replyError != QNetworkReply::NoError || !replyString.isEmpty();
+ },
+ 10000);
+
+ if (!ready) {
+ qWarning() << "Command" << command << "timed out.";
+ dumpConsoleMessages();
+ return false;
+ }
+
+ if (replyError != QNetworkReply::NoError) {
+ qWarning() << "Network error:" << replyError;
+ if (!replyString.isEmpty()) {
+ QJsonDocument errorReply = QJsonDocument::fromJson(replyString.toLatin1());
+ if (!errorReply.isNull()) {
+ QString error = errorReply["value"]["error"].toString();
+ QString message = errorReply["value"]["message"].toString();
+ if (!error.isEmpty() || message.isEmpty()) {
+ qWarning() << "error:" << error;
+ qWarning() << "message:" << message;
+ return false;
+ }
+ }
+
+ qWarning() << replyString;
+ return false;
+ }
+
+ dumpConsoleMessages();
+ return false;
+ }
+
+ if (result) {
+ if (replyString.isEmpty()) {
+ qWarning("Network reply is empty.");
+ return false;
+ }
+
+ QJsonParseError jsonError;
+ *result = QJsonDocument::fromJson(replyString.toLatin1(), &jsonError);
+
+ if (jsonError.error != QJsonParseError::NoError) {
+ qWarning() << "Unable to parse reply:" << jsonError.errorString();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool createSession(QJsonObject chromeOptions = {}, QString *sessionId = nullptr)
+ {
+ if (!m_sessionId.isEmpty()) {
+ qWarning("A session already exists.");
+ return false;
+ }
+
+ QJsonObject root;
+
+ if (chromeOptions.isEmpty()) {
+ // Connect to the test by default.
+ chromeOptions.insert(
+ QLatin1String("debuggerAddress"),
+ QLatin1String("localhost:%1").arg(QString::number(REMOTE_DEBUGGING_PORT)));
+ chromeOptions.insert(QLatin1String("w3c"), true);
+ }
+
+ QJsonObject alwaysMatch;
+ alwaysMatch.insert(QLatin1String("goog:chromeOptions"), chromeOptions);
+
+ QJsonObject seOptions;
+ seOptions.insert(QLatin1String("loggingPrefs"), QJsonObject());
+ alwaysMatch.insert(QLatin1String("se:options"), seOptions);
+
+ QJsonObject capabilities;
+ capabilities.insert(QLatin1String("alwaysMatch"), alwaysMatch);
+ root.insert(QLatin1String("capabilities"), capabilities);
+
+ QJsonDocument params;
+ params.setObject(root);
+
+ QJsonDocument sessionReply;
+ bool sent = sendCommand(QLatin1String("/session"), params, &sessionReply);
+ if (sent) {
+ m_sessionId = sessionReply["value"]["sessionId"].toString();
+ if (sessionId)
+ *sessionId = m_sessionId;
+ }
+
+ return sent;
+ }
+
+ bool deleteSession()
+ {
+ if (m_sessionId.isEmpty()) {
+ qWarning("There is no active session.");
+ return false;
+ }
+
+ QNetworkReply::NetworkError replyError = QNetworkReply::NoError;
+ QString replyString;
+
+ connect(
+ &m_qnam, &QNetworkAccessManager::finished, this,
+ [&replyError, &replyString](QNetworkReply *reply) {
+ replyError = reply->error();
+ replyString = QString::fromUtf8(reply->readAll());
+ },
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+
+ QNetworkRequest request;
+ QUrl requestURL = m_serverURL;
+ requestURL.setPath(QLatin1String("/session/%1").arg(m_sessionId));
+ request.setUrl(requestURL);
+ m_qnam.deleteResource(request);
+
+ bool ready = QTest::qWaitFor(
+ [&replyError, &replyString]() {
+ return replyError != QNetworkReply::NoError || !replyString.isEmpty();
+ },
+ 10000);
+
+ if (!ready) {
+ qWarning("Deleting session timed out.");
+ return false;
+ }
+
+ if (replyError != QNetworkReply::NoError) {
+ qWarning() << "Network error:" << replyError;
+ return false;
+ }
+
+ return true;
+ }
+
+ QStringList stderrLines() const { return m_stderr; }
+
+ bool waitForMessageOnStderr(const QRegularExpression &re, QString *message = nullptr) const
+ {
+ return QTest::qWaitFor(
+ [this, &re, message]() {
+ for (QString line : m_stderr) {
+ if (line.contains(re)) {
+ if (message)
+ *message = line;
+ return true;
+ }
+ }
+
+ return false;
+ },
+ 10000);
+ }
+
+private:
+ void dumpConsoleMessages()
+ {
+ auto dumpLines = [](QStringList *lines) {
+ if (lines->empty())
+ return;
+
+ for (QString line : *lines)
+ qWarning() << qPrintable(line);
+
+ lines->clear();
+ };
+
+ dumpLines(&m_stdout);
+ dumpLines(&m_stderr);
+ }
+
+ QProcess m_process;
+ QStringList m_stdout;
+ QStringList m_stderr;
+
+ QUrl m_serverURL;
+ QString m_sessionId;
+
+ QNetworkAccessManager m_qnam;
+};
+
+class tst_WebEngineDriver : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void status();
+ void startBrowser();
+ void navigate();
+ void typeElement();
+ void executeScript();
+ void screenshot();
+};
+
+void tst_WebEngineDriver::status()
+{
+ DriverServer driverServer;
+ QVERIFY(driverServer.start());
+
+ QJsonDocument statusReply;
+ QVERIFY(driverServer.sendCommand(QLatin1String("/status"), {}, &statusReply));
+
+ QString versionString = statusReply["value"]["build"]["version"].toString();
+ QCOMPARE(qWebEngineChromiumVersion(), versionString.split(QLatin1Char(' '))[0]);
+
+ bool ready = statusReply["value"]["ready"].toBool();
+ QVERIFY(ready);
+}
+
+void tst_WebEngineDriver::startBrowser()
+{
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert(QLatin1String("QTWEBENGINE_REMOTE_DEBUGGING"),
+ QString::number(REMOTE_DEBUGGING_PORT));
+
+ QStringList args;
+ args << QLatin1String("--port=%1").arg(QString::number(WEBENGINEDRIVER_PORT));
+ args << QLatin1String("--log-level=ALL");
+
+ DriverServer driverServer(env, args);
+ QVERIFY(driverServer.start());
+
+ QString testBrowserPath =
+ QCoreApplication::applicationDirPath() + QLatin1String("/testbrowser");
+#if defined(Q_OS_WIN)
+ testBrowserPath += QLatin1String(".exe");
+#endif
+
+ QJsonArray chromeArgs;
+ chromeArgs.append(QLatin1String("enable-logging=stderr"));
+ chromeArgs.append(QLatin1String("v=1"));
+ // To force graceful shutdown.
+ chromeArgs.append(QLatin1String("log-net-log"));
+
+ QJsonObject chromeOptions;
+ chromeOptions.insert(QLatin1String("binary"), testBrowserPath);
+ chromeOptions.insert(QLatin1String("args"), chromeArgs);
+ chromeOptions.insert(QLatin1String("w3c"), true);
+ QString sessionId;
+ QVERIFY(driverServer.createSession(chromeOptions, &sessionId));
+
+ // Test if the browser is started.
+ QVERIFY(driverServer.waitForMessageOnStderr(QRegularExpression(
+ QLatin1String("^DevTools listening on ws://127.0.0.1:%1/devtools/browser/")
+ .arg(QString::number(REMOTE_DEBUGGING_PORT)))));
+ QVERIFY(driverServer.waitForMessageOnStderr(QRegularExpression(
+ QLatin1String("^Remote debugging server started successfully. "
+ "Try pointing a Chromium-based browser to http://127.0.0.1:%1")
+ .arg(QString::number(REMOTE_DEBUGGING_PORT)))));
+
+ // Check custom chromeArgs via logging.
+ QVERIFY(driverServer.waitForMessageOnStderr(QRegularExpression(QLatin1String("VERBOSE1"))));
+
+ QJsonDocument statusReply;
+ QVERIFY(driverServer.sendCommand(QLatin1String("/status"), {}, &statusReply));
+ bool ready = statusReply["value"]["ready"].toBool();
+ QVERIFY(ready);
+
+ QVERIFY(driverServer.deleteSession());
+
+ // Test if the browser is stopped.
+ QVERIFY(driverServer.waitForMessageOnStderr(
+ QRegularExpression(QLatin1String("Test browser is about to quit."))));
+ QVERIFY(driverServer.waitForMessageOnStderr(
+ QRegularExpression(QLatin1String("\\[%1\\] RESPONSE Quit").arg(sessionId))));
+}
+
+void tst_WebEngineDriver::navigate()
+{
+ DriverServer driverServer;
+ QVERIFY(driverServer.start());
+
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.load(QUrl(QLatin1String("about:blank")));
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ QVERIFY(driverServer.createSession());
+
+ QUrl url = QUrl(QLatin1String("qrc:///resources/input.html"));
+ QString paramsString = QLatin1String("{\"url\": \"%1\"}").arg(url.toString());
+ QJsonDocument params = QJsonDocument::fromJson(paramsString.toUtf8());
+ QVERIFY(driverServer.sendCommand(QLatin1String("/session/:sessionId/url"), params));
+ QTRY_COMPARE(loadSpy.size(), 2);
+ QVERIFY(loadSpy.at(1).at(0).toBool());
+ QCOMPARE(url, page.url());
+
+ QVERIFY(driverServer.deleteSession());
+}
+
+void tst_WebEngineDriver::typeElement()
+{
+ DriverServer driverServer;
+ QVERIFY(driverServer.start());
+
+ QWebEngineView view;
+ view.resize(300, 100);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QUrl url = QUrl(QLatin1String("qrc:///resources/input.html"));
+ QSignalSpy loadSpy(view.page(), &QWebEnginePage::loadFinished);
+ view.load(url);
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ QVERIFY(driverServer.createSession());
+
+ // Find <input id="text_input"> element and extract its id from the reply.
+ QString textInputId;
+ {
+ QString paramsString = QLatin1String(
+ "{\"using\": \"css selector\", \"value\": \"[id=\\\"text_input\\\"]\"}");
+ QJsonDocument params = QJsonDocument::fromJson(paramsString.toUtf8());
+ QJsonDocument elementReply;
+ QVERIFY(driverServer.sendCommand(QLatin1String("/session/:sessionId/element"), params,
+ &elementReply));
+
+ QVERIFY(!elementReply.isEmpty());
+ QJsonObject value = elementReply["value"].toObject();
+ QVERIFY(!value.isEmpty());
+ QStringList keys = value.keys();
+ QCOMPARE(keys.size(), 1);
+ textInputId = value[keys[0]].toString();
+ QVERIFY(!textInputId.isEmpty());
+ }
+
+ // Type text into the input field.
+ QString inputText = QLatin1String("WebEngineDriver");
+ {
+ QString command = QLatin1String("/session/:sessionId/element/%1/value").arg(textInputId);
+
+ QJsonObject root;
+ root.insert(QLatin1String("text"), inputText);
+ QJsonArray value;
+ for (QChar ch : inputText) {
+ value.append(QJsonValue(ch));
+ }
+ root.insert(QLatin1String("value"), value);
+ root.insert(QLatin1String("id"), textInputId);
+ QJsonDocument params;
+ params.setObject(root);
+
+ QVERIFY(driverServer.sendCommand(command, params));
+
+ QTRY_COMPARE(
+ evaluateJavaScriptSync(view.page(), "document.getElementById('text_input').value")
+ .toString(),
+ inputText);
+ }
+
+ QVERIFY(driverServer.deleteSession());
+}
+
+void tst_WebEngineDriver::executeScript()
+{
+ DriverServer driverServer;
+ QVERIFY(driverServer.start());
+
+ QUrl url = QUrl(QLatin1String("qrc:///resources/input.html"));
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.load(url);
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QCOMPARE(page.title(), url.toString());
+ QSignalSpy titleSpy(&page, &QWebEnginePage::titleChanged);
+
+ QString newTitle = QLatin1String("WebEngineDriver Test Page");
+ QString script = QLatin1String("document.title = '%1';"
+ "return document.title;")
+ .arg(newTitle);
+
+ QVERIFY(driverServer.createSession());
+ QString paramsString = QLatin1String("{\"script\": \"%1\", \"args\": []}").arg(script);
+ QJsonDocument params = QJsonDocument::fromJson(paramsString.toUtf8());
+ QJsonDocument executeReply;
+ QVERIFY(driverServer.sendCommand(QLatin1String("/session/:sessionId/execute/sync"), params,
+ &executeReply));
+
+ QTRY_COMPARE(titleSpy.size(), 1);
+ QCOMPARE(executeReply["value"].toString(), newTitle);
+ QCOMPARE(page.title(), newTitle);
+
+ QVERIFY(driverServer.deleteSession());
+}
+
+void tst_WebEngineDriver::screenshot()
+{
+ DriverServer driverServer;
+ QVERIFY(driverServer.start());
+
+ QWebEngineView view;
+ view.resize(300, 100);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadSpy(view.page(), &QWebEnginePage::loadFinished);
+
+ view.setHtml(QLatin1String("<html><head><style>"
+ "html {background-color:red;}"
+ "</style></head><body></body></html>"));
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ QVERIFY(driverServer.createSession());
+ QJsonDocument screenshotReply;
+ QVERIFY(driverServer.sendCommand(QLatin1String("/session/:sessionId/screenshot"), {},
+ &screenshotReply));
+
+ QByteArray base64 = screenshotReply["value"].toString().toLocal8Bit();
+ QVERIFY(!base64.isEmpty());
+ QImage screenshot;
+ screenshot.loadFromData(QByteArray::fromBase64(base64));
+ QVERIFY(!screenshot.isNull());
+ QCOMPARE(screenshot.pixel(screenshot.width() / 2, screenshot.height() / 2), 0xFFFF0000);
+
+ QVERIFY(driverServer.deleteSession());
+}
+
+#define STRINGIFY_LITERAL(x) #x
+#define STRINGIFY_EXPANDED(x) STRINGIFY_LITERAL(x)
+static QByteArrayList params = QByteArrayList()
+ << "--remote-debugging-port=" STRINGIFY_EXPANDED(REMOTE_DEBUGGING_PORT);
+W_QTEST_MAIN(tst_WebEngineDriver, params)
+
+#include "tst_webenginedriver.moc"
diff --git a/tests/auto/httpserver/CMakeLists.txt b/tests/auto/httpserver/CMakeLists.txt
index 7d4ddd030..0a1f881b9 100644
--- a/tests/auto/httpserver/CMakeLists.txt
+++ b/tests/auto/httpserver/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(minimal LANGUAGES CXX)
diff --git a/tests/auto/httpserver/httpreqrep.cpp b/tests/auto/httpserver/httpreqrep.cpp
index ee9dbbaa9..8b338ce4e 100644
--- a/tests/auto/httpserver/httpreqrep.cpp
+++ b/tests/auto/httpserver/httpreqrep.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "httpreqrep.h"
HttpReqRep::HttpReqRep(QTcpSocket *socket, QObject *parent)
@@ -82,6 +57,11 @@ QByteArray HttpReqRep::requestHeader(const QByteArray &key) const
return {};
}
+bool HttpReqRep::hasRequestHeader(const QByteArray &key) const
+{
+ return m_requestHeaders.find(key.toLower()) != m_requestHeaders.end();
+}
+
void HttpReqRep::handleReadyRead()
{
while (m_socket->canReadLine()) {
@@ -141,3 +121,5 @@ void HttpReqRep::handleDisconnected()
m_state = State::DISCONNECTED;
Q_EMIT closed();
}
+
+#include "moc_httpreqrep.cpp"
diff --git a/tests/auto/httpserver/httpreqrep.h b/tests/auto/httpserver/httpreqrep.h
index e1979e050..774c08eb1 100644
--- a/tests/auto/httpserver/httpreqrep.h
+++ b/tests/auto/httpserver/httpreqrep.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef HTTPREQREP_H
#define HTTPREQREP_H
@@ -50,6 +25,7 @@ public:
QByteArray requestMethod() const { return m_requestMethod; }
QByteArray requestPath() const { return m_requestPath; }
QByteArray requestHeader(const QByteArray &key) const;
+ bool hasRequestHeader(const QByteArray &key) const;
// Response parameters (can be set until sendResponse()/close()).
diff --git a/tests/auto/httpserver/httpserver.cmake b/tests/auto/httpserver/httpserver.cmake
index 84b350c0e..f98434e1a 100644
--- a/tests/auto/httpserver/httpserver.cmake
+++ b/tests/auto/httpserver/httpserver.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT TARGET Test::HttpServer)
add_library(httpserver STATIC
diff --git a/tests/auto/httpserver/httpserver.cpp b/tests/auto/httpserver/httpserver.cpp
index 10147ae6c..e08af77e7 100644
--- a/tests/auto/httpserver/httpserver.cpp
+++ b/tests/auto/httpserver/httpserver.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "httpserver.h"
#include <QFile>
@@ -49,7 +24,8 @@ HttpServer::HttpServer(QTcpServer *tcpServer, const QString &protocol,
{
m_url.setHost(hostAddress.toString());
m_url.setScheme(protocol);
- connect(tcpServer, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection);
+ connect(tcpServer, &QTcpServer::pendingConnectionAvailable, this,
+ &HttpServer::handleNewConnection);
}
HttpServer::~HttpServer()
@@ -104,12 +80,13 @@ void HttpServer::handleNewConnection()
// if request wasn't handled or purposely ignored for default behavior
// then try to serve htmls from resources dirs if set
if (rr->requestMethod() == "GET") {
- for (auto &&dir : qAsConst(m_dirs)) {
+ for (auto &&dir : std::as_const(m_dirs)) {
QFile f(dir + rr->requestPath());
if (f.exists()) {
if (f.open(QFile::ReadOnly)) {
QMimeType mime = QMimeDatabase().mimeTypeForFileNameAndData(f.fileName(), &f);
rr->setResponseHeader(QByteArrayLiteral("Content-Type"), mime.name().toUtf8());
+ rr->setResponseHeader(QByteArrayLiteral("Access-Control-Allow-Origin"), QByteArrayLiteral("*"));
rr->setResponseBody(f.readAll());
rr->sendResponse();
} else {
@@ -146,3 +123,5 @@ QString HttpServer::sharedDataDir() const
{
return SERVER_SOURCE_DIR + QLatin1String("/data");
}
+
+#include "moc_httpserver.cpp"
diff --git a/tests/auto/httpserver/httpserver.h b/tests/auto/httpserver/httpserver.h
index acc742775..201eef4c6 100644
--- a/tests/auto/httpserver/httpserver.h
+++ b/tests/auto/httpserver/httpserver.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef HTTPSERVER_H
#define HTTPSERVER_H
@@ -84,6 +59,8 @@ public:
Q_INVOKABLE void setHostDomain(const QString &host) { m_url.setHost(host); }
+ Q_INVOKABLE QTcpServer *getTcpServer() const { return m_tcpServer; }
+
Q_SIGNALS:
// Emitted after a HTTP request has been successfully parsed.
void newRequest(HttpReqRep *reqRep);
diff --git a/tests/auto/httpserver/httpsserver.h b/tests/auto/httpserver/httpsserver.h
index b257e69a7..d029851aa 100644
--- a/tests/auto/httpserver/httpsserver.h
+++ b/tests/auto/httpserver/httpsserver.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef HTTPSSERVER_H
#define HTTPSSERVER_H
@@ -32,54 +7,67 @@
#include "httpserver.h"
#include <QDebug>
-#include <QFile>
-#include <QSslKey>
-#include <QSslSocket>
-#include <QSslConfiguration>
-#include <QTcpServer>
+#include <QtCore/qfile.h>
+#include <QtNetwork/qsslkey.h>
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qsslconfiguration.h>
+#include <QtNetwork/qsslserver.h>
-struct SslTcpServer : QTcpServer
+static QSslServer *createServer(const QString &certificateFileName, const QString &keyFileName,
+ const QString &ca)
{
- SslTcpServer(const QString &certPath, const QString &keyPath) {
- sslconf.setLocalCertificateChain(QSslCertificate::fromPath(certPath));
- sslconf.setPrivateKey(readKey(keyPath));
- }
-
- void incomingConnection(qintptr d) override {
- auto socket = new QSslSocket(this);
- socket->setSslConfiguration(sslconf);
+ QSslConfiguration configuration(QSslConfiguration::defaultConfiguration());
- if (!socket->setSocketDescriptor(d)) {
- qWarning() << "Failed to setup ssl socket!";
- delete socket;
- return;
+ QFile keyFile(keyFileName);
+ if (keyFile.open(QIODevice::ReadOnly)) {
+ QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ if (!key.isNull()) {
+ configuration.setPrivateKey(key);
+ } else {
+ qCritical() << "Could not parse key: " << keyFileName;
}
+ } else {
+ qCritical() << "Could not find key: " << keyFileName;
+ }
- connect(socket, QOverload<QSslSocket::SocketError>::of(&QSslSocket::errorOccurred),
- [] (QSslSocket::SocketError e) { qWarning() << "! Socket Error:" << e; });
- connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
- [] (const QList<QSslError> &le) { qWarning() << "! SSL Errors:\n" << le; });
-
- addPendingConnection(socket);
- socket->startServerEncryption();
+ QList<QSslCertificate> localCerts = QSslCertificate::fromPath(certificateFileName);
+ if (!localCerts.isEmpty()) {
+ configuration.setLocalCertificateChain(localCerts);
+ } else {
+ qCritical() << "Could not find certificate: " << certificateFileName;
}
- QSslKey readKey(const QString &path) const {
- QFile file(path);
- file.open(QIODevice::ReadOnly);
- return QSslKey(file.readAll(), QSsl::Rsa, QSsl::Pem);
+ if (!ca.isEmpty()) {
+ QList<QSslCertificate> caCerts = QSslCertificate::fromPath(ca);
+ if (!caCerts.isEmpty()) {
+ configuration.addCaCertificates(caCerts);
+ configuration.setPeerVerifyMode(QSslSocket::VerifyPeer);
+ } else {
+ qCritical() << "Could not find certificate: " << certificateFileName;
+ }
}
- QSslConfiguration sslconf;
-};
+ QSslServer *server = new QSslServer();
+ server->setSslConfiguration(configuration);
+ return server;
+}
struct HttpsServer : HttpServer
{
- HttpsServer(const QString &certPath, const QString &keyPath, QObject *parent = nullptr)
- : HttpServer(new SslTcpServer(certPath, keyPath), "https", QHostAddress::LocalHost, 0,
+ HttpsServer(const QString &certPath, const QString &keyPath, const QString &ca,
+ quint16 port = 0, QObject *parent = nullptr)
+ : HttpServer(createServer(certPath, keyPath, ca), "https", QHostAddress::LocalHost, port,
parent)
{
}
+
+ void setVerifyMode(const QSslSocket::PeerVerifyMode verifyMode)
+ {
+ QSslServer *server = static_cast<QSslServer *>(getTcpServer());
+ QSslConfiguration config = server->sslConfiguration();
+ config.setPeerVerifyMode(verifyMode);
+ server->setSslConfiguration(config);
+ }
};
#endif
diff --git a/tests/auto/httpserver/proxy_server.cpp b/tests/auto/httpserver/proxy_server.cpp
index 3c5588603..338415311 100644
--- a/tests/auto/httpserver/proxy_server.cpp
+++ b/tests/auto/httpserver/proxy_server.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "proxy_server.h"
#include <QDataStream>
@@ -106,3 +81,5 @@ void ProxyServer::handleReadReady()
m_data.clear();
emit requestReceived();
}
+
+#include "moc_proxy_server.cpp"
diff --git a/tests/auto/httpserver/proxy_server.h b/tests/auto/httpserver/proxy_server.h
index 57e69efe7..6be0c4e1a 100644
--- a/tests/auto/httpserver/proxy_server.h
+++ b/tests/auto/httpserver/proxy_server.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PROXY_SERVER_H
#define PROXY_SERVER_H
diff --git a/tests/auto/pdf/CMakeLists.txt b/tests/auto/pdf/CMakeLists.txt
index 1220581ca..205bd24d0 100644
--- a/tests/auto/pdf/CMakeLists.txt
+++ b/tests/auto/pdf/CMakeLists.txt
@@ -1,6 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(qpdfbookmarkmodel)
-add_subdirectory(qpdfpagenavigation)
+if (TARGET Qt::PdfWidgets)
+ add_subdirectory(qpdfpagenavigator)
+endif()
add_subdirectory(qpdfpagerenderer)
+add_subdirectory(qpdfsearchmodel)
if(TARGET Qt::PrintSupport)
add_subdirectory(qpdfdocument)
endif()
diff --git a/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt b/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt
index f0300ce7b..729bc9138 100644
--- a/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfbookmarkmodel/CMakeLists.txt
@@ -1,9 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfbookmarkmodel
SOURCES
tst_qpdfbookmarkmodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::Pdf
+ TESTDATA
+ pdf-sample.bookmarks.pdf
+ pdf-sample.bookmarks_pages.pdf
)
diff --git a/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp b/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp
index fddc98011..a1804e179 100644
--- a/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp
+++ b/tests/auto/pdf/qpdfbookmarkmodel/tst_qpdfbookmarkmodel.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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:LGPL3$
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -57,8 +24,8 @@ private slots:
void setLoadedDocument();
void unloadDocument();
void testTreeStructure();
- void testListStructure();
void testPageNumberRole();
+ void testLocationAndZoomRoles();
};
void tst_QPdfBookmarkModel::emptyModel()
@@ -66,7 +33,6 @@ void tst_QPdfBookmarkModel::emptyModel()
QPdfBookmarkModel model;
QVERIFY(!model.document());
- QCOMPARE(model.structureMode(), QPdfBookmarkModel::TreeMode);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.columnCount(), 1);
QCOMPARE(model.index(0, 0).isValid(), false);
@@ -80,7 +46,6 @@ void tst_QPdfBookmarkModel::setEmptyDocument()
model.setDocument(&document);
QCOMPARE(model.document(), &document);
- QCOMPARE(model.structureMode(), QPdfBookmarkModel::TreeMode);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.columnCount(), 1);
QCOMPARE(model.index(0, 0).isValid(), false);
@@ -96,10 +61,10 @@ void tst_QPdfBookmarkModel::setEmptyDocumentAndLoad()
QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset()));
QSignalSpy modelResetSpy(&model, SIGNAL(modelReset()));
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None);
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
QCOMPARE(model.rowCount(), 3);
}
@@ -107,7 +72,7 @@ void tst_QPdfBookmarkModel::setEmptyDocumentAndLoad()
void tst_QPdfBookmarkModel::setLoadedDocument()
{
QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None);
QPdfBookmarkModel model;
@@ -116,8 +81,8 @@ void tst_QPdfBookmarkModel::setLoadedDocument()
model.setDocument(&document);
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
QCOMPARE(model.rowCount(), 3);
}
@@ -125,7 +90,7 @@ void tst_QPdfBookmarkModel::setLoadedDocument()
void tst_QPdfBookmarkModel::unloadDocument()
{
QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None);
QPdfBookmarkModel model;
model.setDocument(&document);
@@ -137,8 +102,8 @@ void tst_QPdfBookmarkModel::unloadDocument()
document.close();
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(modelAboutToBeResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
QCOMPARE(model.rowCount(), 0);
}
@@ -146,7 +111,7 @@ void tst_QPdfBookmarkModel::unloadDocument()
void tst_QPdfBookmarkModel::testTreeStructure()
{
QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::Error::None);
QPdfBookmarkModel model;
model.setDocument(&document);
@@ -154,115 +119,76 @@ void tst_QPdfBookmarkModel::testTreeStructure()
QCOMPARE(model.rowCount(), 3);
const QModelIndex index1 = model.index(0, 0);
- QCOMPARE(index1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 1"));
- QCOMPARE(index1.data(QPdfBookmarkModel::LevelRole).toInt(), 0);
+ QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 1"));
+ QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 0);
QCOMPARE(model.rowCount(index1), 2);
const QModelIndex index1_1 = model.index(0, 0, index1);
- QCOMPARE(index1_1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 1.1"));
- QCOMPARE(index1_1.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
+ QCOMPARE(index1_1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 1.1"));
+ QCOMPARE(index1_1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1);
QCOMPARE(model.rowCount(index1_1), 0);
const QModelIndex index1_2 = model.index(1, 0, index1);
- QCOMPARE(index1_2.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 1.2"));
- QCOMPARE(index1_2.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
+ QCOMPARE(index1_2.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 1.2"));
+ QCOMPARE(index1_2.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1);
QCOMPARE(model.rowCount(index1_2), 0);
const QModelIndex index2 = model.index(1, 0);
- QCOMPARE(index2.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2"));
- QCOMPARE(index2.data(QPdfBookmarkModel::LevelRole).toInt(), 0);
+ QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2"));
+ QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 0);
QCOMPARE(model.rowCount(index2), 2);
const QModelIndex index2_1 = model.index(0, 0, index2);
- QCOMPARE(index2_1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2.1"));
- QCOMPARE(index2_1.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
+ QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2.1"));
+ QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1);
QCOMPARE(model.rowCount(index2_1), 1);
const QModelIndex index2_1_1 = model.index(0, 0, index2_1);
- QCOMPARE(index2_1_1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2.1.1"));
- QCOMPARE(index2_1_1.data(QPdfBookmarkModel::LevelRole).toInt(), 2);
+ QCOMPARE(index2_1_1.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2.1.1"));
+ QCOMPARE(index2_1_1.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 2);
QCOMPARE(model.rowCount(index2_1_1), 0);
const QModelIndex index2_2 = model.index(1, 0, index2);
- QCOMPARE(index2_2.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2.2"));
- QCOMPARE(index2_2.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
+ QCOMPARE(index2_2.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 2.2"));
+ QCOMPARE(index2_2.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 1);
QCOMPARE(model.rowCount(index2_2), 0);
const QModelIndex index3 = model.index(2, 0);
- QCOMPARE(index3.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 3"));
- QCOMPARE(index3.data(QPdfBookmarkModel::LevelRole).toInt(), 0);
+ QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Title)).toString(), QLatin1String("Section 3"));
+ QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Level)).toInt(), 0);
QCOMPARE(model.rowCount(index3), 0);
const QModelIndex index4 = model.index(3, 0);
QCOMPARE(index4, QModelIndex());
}
-void tst_QPdfBookmarkModel::testListStructure()
+void tst_QPdfBookmarkModel::testPageNumberRole()
{
QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None);
QPdfBookmarkModel model;
model.setDocument(&document);
- QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset()));
- QSignalSpy modelResetSpy(&model, SIGNAL(modelReset()));
-
- model.setStructureMode(QPdfBookmarkModel::ListMode);
-
- QCOMPARE(modelAboutToBeResetSpy.count(), 1);
- QCOMPARE(modelResetSpy.count(), 1);
-
- QCOMPARE(model.rowCount(), 8);
+ QCOMPARE(model.rowCount(), 3);
const QModelIndex index1 = model.index(0, 0);
- QCOMPARE(index1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 1"));
- QCOMPARE(index1.data(QPdfBookmarkModel::LevelRole).toInt(), 0);
- QCOMPARE(model.rowCount(index1), 0);
-
- const QModelIndex index1_1 = model.index(1, 0);
- QCOMPARE(index1_1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 1.1"));
- QCOMPARE(index1_1.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
- QCOMPARE(model.rowCount(index1_1), 0);
-
- const QModelIndex index1_2 = model.index(2, 0);
- QCOMPARE(index1_2.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 1.2"));
- QCOMPARE(index1_2.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
- QCOMPARE(model.rowCount(index1_2), 0);
+ QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 0);
- const QModelIndex index2 = model.index(3, 0);
- QCOMPARE(index2.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2"));
- QCOMPARE(index2.data(QPdfBookmarkModel::LevelRole).toInt(), 0);
- QCOMPARE(model.rowCount(index2), 0);
-
- const QModelIndex index2_1 = model.index(4, 0);
- QCOMPARE(index2_1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2.1"));
- QCOMPARE(index2_1.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
- QCOMPARE(model.rowCount(index2_1), 0);
-
- const QModelIndex index2_1_1 = model.index(5, 0);
- QCOMPARE(index2_1_1.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2.1.1"));
- QCOMPARE(index2_1_1.data(QPdfBookmarkModel::LevelRole).toInt(), 2);
- QCOMPARE(model.rowCount(index2_1_1), 0);
-
- const QModelIndex index2_2 = model.index(6, 0);
- QCOMPARE(index2_2.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 2.2"));
- QCOMPARE(index2_2.data(QPdfBookmarkModel::LevelRole).toInt(), 1);
- QCOMPARE(model.rowCount(index2_2), 0);
+ const QModelIndex index2 = model.index(1, 0);
+ QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 1);
- const QModelIndex index3 = model.index(7, 0);
- QCOMPARE(index3.data(QPdfBookmarkModel::TitleRole).toString(), QLatin1String("Section 3"));
- QCOMPARE(index3.data(QPdfBookmarkModel::LevelRole).toInt(), 0);
- QCOMPARE(model.rowCount(index3), 0);
+ const QModelIndex index2_1 = model.index(0, 0, index2);
+ QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 1);
- const QModelIndex index4 = model.index(8, 0);
- QCOMPARE(index4, QModelIndex());
+ const QModelIndex index3 = model.index(2, 0);
+ QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Page)).toInt(), 2);
}
-void tst_QPdfBookmarkModel::testPageNumberRole()
+void tst_QPdfBookmarkModel::testLocationAndZoomRoles()
{
QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None);
QPdfBookmarkModel model;
model.setDocument(&document);
@@ -270,16 +196,20 @@ void tst_QPdfBookmarkModel::testPageNumberRole()
QCOMPARE(model.rowCount(), 3);
const QModelIndex index1 = model.index(0, 0);
- QCOMPARE(index1.data(QPdfBookmarkModel::PageNumberRole).toInt(), 0);
+ QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 69));
+ QCOMPARE(index1.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0);
const QModelIndex index2 = model.index(1, 0);
- QCOMPARE(index2.data(QPdfBookmarkModel::PageNumberRole).toInt(), 1);
+ QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 57));
+ QCOMPARE(index2.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0);
const QModelIndex index2_1 = model.index(0, 0, index2);
- QCOMPARE(index2_1.data(QPdfBookmarkModel::PageNumberRole).toInt(), 1);
+ QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 526));
+ QCOMPARE(index2_1.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0);
const QModelIndex index3 = model.index(2, 0);
- QCOMPARE(index3.data(QPdfBookmarkModel::PageNumberRole).toInt(), 2);
+ QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Location)).toPoint(), QPoint(57, 402));
+ QCOMPARE(index3.data(int(QPdfBookmarkModel::Role::Zoom)).toInt(), 0);
}
QTEST_MAIN(tst_QPdfBookmarkModel)
diff --git a/tests/auto/pdf/qpdfdocument/BLACKLIST b/tests/auto/pdf/qpdfdocument/BLACKLIST
deleted file mode 100644
index b8db556d6..000000000
--- a/tests/auto/pdf/qpdfdocument/BLACKLIST
+++ /dev/null
@@ -1,6 +0,0 @@
-[password]
-*
-
-[passwordClearedOnClose]
-*
-
diff --git a/tests/auto/pdf/qpdfdocument/CMakeLists.txt b/tests/auto/pdf/qpdfdocument/CMakeLists.txt
index 4551fdb6c..b8300ef27 100644
--- a/tests/auto/pdf/qpdfdocument/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfdocument/CMakeLists.txt
@@ -1,9 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfdocument
SOURCES
tst_qpdfdocument.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::PrintSupport
Qt::Pdf
+ TESTDATA
+ pdf-sample.protected.pdf
+ pdf-sample.metadata.pdf
+ rotated_text.pdf
+ tagged_mcr_multipage.pdf
+ test.pdf
)
diff --git a/tests/auto/pdf/qpdfdocument/rotated_text.pdf b/tests/auto/pdf/qpdfdocument/rotated_text.pdf
new file mode 100644
index 000000000..d6d8db84e
--- /dev/null
+++ b/tests/auto/pdf/qpdfdocument/rotated_text.pdf
@@ -0,0 +1,70 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /MediaBox [ 0 0 200 200 ]
+ /Count 1
+ /Kids [ 3 0 R ]
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 4 0 R
+ >>
+ >>
+ /Contents 5 0 R
+>>
+endobj
+4 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Times-Roman
+>>
+endobj
+5 0 obj <<
+ /Length 406
+>>
+stream
+BT
+0 0 Td
+/F1 12 Tf
+0.70710678118 -0.70710678118 0.70710678118 0.70710678118 100 100 Tm
+(Hello,) Tj
+0 0 Td
+/F1 12 Tf
+-0.70710678118 -0.70710678118 0.70710678118 -0.70710678118 100 100 Tm
+( world!\r\n) Tj
+0 0 Td
+/F1 12 Tf
+-0.70710678118 0.70710678118 -0.70710678118 -0.70710678118 100 100 Tm
+(Goodbye,) Tj
+0 0 Td
+/F1 12 Tf
+0.70710678118 0.70710678118 -0.70710678118 0.70710678118 100 100 Tm
+( world!) Tj
+ET
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000161 00000 n
+0000000287 00000 n
+0000000365 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 6
+>>
+startxref
+823
+%%EOF
diff --git a/tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf b/tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf
new file mode 100644
index 000000000..fcc5fafda
--- /dev/null
+++ b/tests/auto/pdf/qpdfdocument/tagged_mcr_multipage.pdf
@@ -0,0 +1,136 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /MarkInfo <<
+ /Type /MarkInfo
+ /Marked true
+ >>
+ /Pages 2 0 R
+ /StructTreeRoot 8 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /CropBox [ 10.8197 8.459 605.705 801.639 ]
+ /MediaBox [ 0.0 0.0 616.721 809.902 ]
+ /Count 2
+ /Kids [
+ 4 0 R
+ 6 0 R
+ ]
+>>
+endobj
+3 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Times-Roman
+>>
+endobj
+4 0 obj <<
+ /Type /Page
+ /Tabs /S
+ /Parent 2 0 R
+ /StructParents 0
+ /Contents 5 0 R
+ /Resources <<
+ /ProcSet [/PDF /Text]
+ /Font <<
+ /F1 3 0 R
+ >>
+ >>
+>>
+endobj
+5 0 obj <<
+ /Length 83
+>>
+stream
+BT
+/Document <</MCID 0 >>BDC
+0 i
+/F1 1 Tf
+12 0 0 12 43.073 771.625 Tm
+(1)Tj
+EMC
+ET
+endstream
+endobj
+6 0 obj <<
+ /Type /Page
+ /Tabs /S
+ /Parent 2 0 R
+ /StructParents 1
+ /Contents 7 0 R
+ /Resources <<
+ /ProcSet [/PDF /Text]
+ /Font <<
+ /F1 3 0 R
+ >>
+ >>
+>>
+endobj
+7 0 obj <<
+ /Length 83
+>>
+stream
+BT
+/Document <</MCID 0 >>BDC
+0 i
+/F1 1 Tf
+12 0 0 12 43.073 771.625 Tm
+(2)Tj
+EMC
+ET
+endstream
+endobj
+8 0 obj <<
+ /Type /StructTreeRoot
+ /K 10 0 R
+ /ParentTree 9 0 R
+ /ParentTreeNextKey 2
+>>
+endobj
+9 0 obj <<
+ /Nums [
+ 0
+ [10 0 R]
+ 1
+ [10 0 R]
+ ]
+>>
+endobj
+10 0 obj <<
+ /T ()
+ /S /Document
+ /P 8 0 R
+ /Pg 4 0 R
+ /K [
+ 0
+ <<
+ /MCID 0
+ /Pg 6 0 R
+ /Type /MCR
+ >>
+ ]
+>>
+%endobj
+xref
+0 11
+0000000000 65535 f
+0000000015 00000 n
+0000000149 00000 n
+0000000315 00000 n
+0000000393 00000 n
+0000000575 00000 n
+0000000709 00000 n
+0000000891 00000 n
+0000001025 00000 n
+0000001125 00000 n
+0000001198 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 11
+>>
+startxref
+1345
+%%EOF
diff --git a/tests/auto/pdf/qpdfdocument/test.pdf b/tests/auto/pdf/qpdfdocument/test.pdf
new file mode 100644
index 000000000..0832dfbed
--- /dev/null
+++ b/tests/auto/pdf/qpdfdocument/test.pdf
Binary files differ
diff --git a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
index 29b85fc89..d222bff0c 100644
--- a/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
+++ b/tests/auto/pdf/qpdfdocument/tst_qpdfdocument.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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:LGPL3$
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -40,7 +7,9 @@
#include <QPainter>
#include <QPdfDocument>
#include <QPrinter>
+#include <QDateTime>
#include <QTemporaryFile>
+#include <QTimeZone>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
@@ -66,16 +35,32 @@ private slots:
void status();
void passwordClearedOnClose();
void metaData();
+ void pageLabels();
+ void getSelection_data();
+ void getSelection();
+ void getSelectionAtIndex_data();
+ void getSelectionAtIndex();
+
+private:
+ void consistencyCheck(QPdfDocument &doc) const;
};
struct TemporaryPdf: public QTemporaryFile
{
TemporaryPdf();
QPageLayout pageLayout;
+
+ static QString pageText(int page) {
+ switch (page) {
+ case 0: return QStringLiteral("Hello Page 1");
+ case 1: return QStringLiteral("Hello Page 2");
+ default: return {};
+ }
+ }
};
-TemporaryPdf::TemporaryPdf()
+TemporaryPdf::TemporaryPdf():QTemporaryFile(QStringLiteral("qpdfdocument"))
{
open();
pageLayout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF());
@@ -88,9 +73,9 @@ TemporaryPdf::TemporaryPdf()
{
QPainter painter(&printer);
- painter.drawText(100, 100, QStringLiteral("Hello Page 1"));
+ painter.drawText(100, 100, pageText(0));
printer.newPage();
- painter.drawText(100, 100, QStringLiteral("Hello Page 2"));
+ painter.drawText(100, 100, pageText(1));
}
}
@@ -105,12 +90,12 @@ void tst_QPdfDocument::pageCount()
QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int)));
QCOMPARE(doc.pageCount(), 0);
- QCOMPARE(doc.load(tempPdf.fileName()), QPdfDocument::NoError);
+ QCOMPARE(doc.load(tempPdf.fileName()), QPdfDocument::Error::None);
QCOMPARE(doc.pageCount(), 2);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
- QCOMPARE(doc.pageSize(0).toSize(), tempPdf.pageLayout.fullRectPoints().size());
+ QCOMPARE(doc.pagePointSize(0).toSize(), tempPdf.pageLayout.fullRectPoints().size());
}
void tst_QPdfDocument::loadFromIODevice()
@@ -120,13 +105,26 @@ void tst_QPdfDocument::loadFromIODevice()
QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status)));
QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int)));
doc.load(&tempPdf);
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Ready);
- QCOMPARE(doc.error(), QPdfDocument::NoError);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready);
+ QCOMPARE(doc.error(), QPdfDocument::Error::None);
QCOMPARE(doc.pageCount(), 2);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
+
+ consistencyCheck(doc);
+}
+
+void tst_QPdfDocument::consistencyCheck(QPdfDocument &doc) const
+{
+ for (int i = 0; i < doc.pageCount(); ++i) {
+ const QString expected = TemporaryPdf::pageText(i);
+ QPdfSelection page = doc.getAllText(i);
+ QCOMPARE(page.text(), expected);
+ auto pageMoved = std::move(page);
+ QCOMPARE(pageMoved.text(), expected);
+ }
}
void tst_QPdfDocument::loadAsync()
@@ -144,12 +142,14 @@ void tst_QPdfDocument::loadAsync()
doc.load(reply.data());
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Ready);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready);
QCOMPARE(doc.pageCount(), 2);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
+
+ consistencyCheck(doc);
}
void tst_QPdfDocument::password()
@@ -158,15 +158,15 @@ void tst_QPdfDocument::password()
QSignalSpy passwordChangedSpy(&doc, SIGNAL(passwordChanged()));
QCOMPARE(doc.pageCount(), 0);
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::IncorrectPasswordError);
- QCOMPARE(passwordChangedSpy.count(), 0);
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::IncorrectPassword);
+ QCOMPARE(passwordChangedSpy.size(), 0);
doc.setPassword(QStringLiteral("WrongPassword"));
- QCOMPARE(passwordChangedSpy.count(), 1);
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::IncorrectPasswordError);
- QCOMPARE(doc.status(), QPdfDocument::Error);
+ QCOMPARE(passwordChangedSpy.size(), 1);
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::IncorrectPassword);
+ QCOMPARE(doc.status(), QPdfDocument::Status::Error);
doc.setPassword(QStringLiteral("Qt"));
- QCOMPARE(passwordChangedSpy.count(), 2);
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::NoError);
+ QCOMPARE(passwordChangedSpy.size(), 2);
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::None);
QCOMPARE(doc.pageCount(), 1);
}
@@ -180,21 +180,25 @@ void tst_QPdfDocument::close()
doc.load(&tempPdf);
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Ready);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
statusChangedSpy.clear();
pageCountChangedSpy.clear();
+ consistencyCheck(doc);
+ if (QTest::currentTestFailed())
+ return;
+
doc.close();
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Unloading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Null);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null);
QCOMPARE(doc.pageCount(), 0);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
}
@@ -207,31 +211,33 @@ void tst_QPdfDocument::loadAfterClose()
QSignalSpy pageCountChangedSpy(&doc, SIGNAL(pageCountChanged(int)));
doc.load(&tempPdf);
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Ready);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
statusChangedSpy.clear();
pageCountChangedSpy.clear();
doc.close();
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Unloading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Null);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
statusChangedSpy.clear();
pageCountChangedSpy.clear();
doc.load(&tempPdf);
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Ready);
- QCOMPARE(doc.error(), QPdfDocument::NoError);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready);
+ QCOMPARE(doc.error(), QPdfDocument::Error::None);
QCOMPARE(doc.pageCount(), 2);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), doc.pageCount());
+
+ consistencyCheck(doc);
}
void tst_QPdfDocument::closeOnDestroy()
@@ -249,10 +255,10 @@ void tst_QPdfDocument::closeOnDestroy()
delete doc;
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Unloading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Null);
- QCOMPARE(pageCountChangedSpy.count(), 1);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null);
+ QCOMPARE(pageCountChangedSpy.size(), 1);
QCOMPARE(pageCountChangedSpy[0][0].toInt(), 0);
}
@@ -267,8 +273,8 @@ void tst_QPdfDocument::closeOnDestroy()
delete doc;
- QCOMPARE(statusChangedSpy.count(), 0);
- QCOMPARE(pageCountChangedSpy.count(), 0);
+ QCOMPARE(statusChangedSpy.size(), 0);
+ QCOMPARE(pageCountChangedSpy.size(), 0);
}
}
@@ -277,35 +283,35 @@ void tst_QPdfDocument::status()
TemporaryPdf tempPdf;
QPdfDocument doc;
- QCOMPARE(doc.status(), QPdfDocument::Null);
+ QCOMPARE(doc.status(), QPdfDocument::Status::Null);
QSignalSpy statusChangedSpy(&doc, SIGNAL(statusChanged(QPdfDocument::Status)));
// open existing document
doc.load(&tempPdf);
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Ready);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Ready);
statusChangedSpy.clear();
- QCOMPARE(doc.status(), QPdfDocument::Ready);
+ QCOMPARE(doc.status(), QPdfDocument::Status::Ready);
// close document
doc.close();
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Unloading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Null);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Unloading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Null);
statusChangedSpy.clear();
- QCOMPARE(doc.status(), QPdfDocument::Null);
+ QCOMPARE(doc.status(), QPdfDocument::Status::Null);
// try to open non-existing document
doc.load(QFINDTESTDATA("does-not-exist.pdf"));
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Error);
- QCOMPARE(doc.status(), QPdfDocument::Error);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Error);
+ QCOMPARE(doc.status(), QPdfDocument::Status::Error);
statusChangedSpy.clear();
// try to open non-existing document asynchronously
@@ -320,15 +326,15 @@ void tst_QPdfDocument::status()
stopWatch.start();
forever {
QCoreApplication::instance()->processEvents();
- if (statusChangedSpy.count() == 2)
+ if (statusChangedSpy.size() == 2)
break;
if (stopWatch.elapsed() >= 30000)
break;
}
- QCOMPARE(statusChangedSpy.count(), 2);
- QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Loading);
- QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Error);
+ QCOMPARE(statusChangedSpy.size(), 2);
+ QCOMPARE(statusChangedSpy[0][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Loading);
+ QCOMPARE(statusChangedSpy[1][0].value<QPdfDocument::Status>(), QPdfDocument::Status::Error);
statusChangedSpy.clear();
}
@@ -340,17 +346,17 @@ void tst_QPdfDocument::passwordClearedOnClose()
QSignalSpy passwordChangedSpy(&doc, SIGNAL(passwordChanged()));
doc.setPassword(QStringLiteral("Qt"));
- QCOMPARE(passwordChangedSpy.count(), 1);
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::NoError);
+ QCOMPARE(passwordChangedSpy.size(), 1);
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.protected.pdf")), QPdfDocument::Error::None);
passwordChangedSpy.clear();
doc.close(); // password is cleared on close
- QCOMPARE(passwordChangedSpy.count(), 1);
+ QCOMPARE(passwordChangedSpy.size(), 1);
passwordChangedSpy.clear();
doc.load(&tempPdf);
doc.close(); // signal is not emitted if password didn't change
- QCOMPARE(passwordChangedSpy.count(), 0);
+ QCOMPARE(passwordChangedSpy.size(), 0);
}
void tst_QPdfDocument::metaData()
@@ -358,26 +364,118 @@ void tst_QPdfDocument::metaData()
QPdfDocument doc;
// a closed document does not return any meta data
- QCOMPARE(doc.metaData(QPdfDocument::Title).toString(), QString());
- QCOMPARE(doc.metaData(QPdfDocument::Subject).toString(), QString());
- QCOMPARE(doc.metaData(QPdfDocument::Author).toString(), QString());
- QCOMPARE(doc.metaData(QPdfDocument::Keywords).toString(), QString());
- QCOMPARE(doc.metaData(QPdfDocument::Producer).toString(), QString());
- QCOMPARE(doc.metaData(QPdfDocument::Creator).toString(), QString());
- QCOMPARE(doc.metaData(QPdfDocument::CreationDate).toDateTime(), QDateTime());
- QCOMPARE(doc.metaData(QPdfDocument::ModificationDate).toDateTime(), QDateTime());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Title).toString(), QString());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Subject).toString(), QString());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Author).toString(), QString());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Keywords).toString(), QString());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Producer).toString(), QString());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Creator).toString(), QString());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(), QDateTime());
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(), QDateTime());
- QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.metadata.pdf")), QPdfDocument::NoError);
+ QCOMPARE(doc.load(QFINDTESTDATA("pdf-sample.metadata.pdf")), QPdfDocument::Error::None);
// check for proper meta data from sample document
- QCOMPARE(doc.metaData(QPdfDocument::Title).toString(), QString::fromLatin1("Qt PDF Unit Test Document"));
- QCOMPARE(doc.metaData(QPdfDocument::Subject).toString(), QString::fromLatin1("A test for meta data access"));
- QCOMPARE(doc.metaData(QPdfDocument::Author).toString(), QString::fromLatin1("John Doe"));
- QCOMPARE(doc.metaData(QPdfDocument::Keywords).toString(), QString::fromLatin1("meta data keywords"));
- QCOMPARE(doc.metaData(QPdfDocument::Producer).toString(), QString::fromLatin1("LibreOffice 5.1"));
- QCOMPARE(doc.metaData(QPdfDocument::Creator).toString(), QString::fromLatin1("Writer"));
- QCOMPARE(doc.metaData(QPdfDocument::CreationDate).toDateTime(), QDateTime(QDate(2016, 8, 7), QTime(7, 3, 6), Qt::UTC));
- QCOMPARE(doc.metaData(QPdfDocument::ModificationDate).toDateTime(), QDateTime(QDate(2016, 8, 8), QTime(8, 3, 6), Qt::UTC));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Title).toString(), QString::fromLatin1("Qt PDF Unit Test Document"));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Subject).toString(), QString::fromLatin1("A test for meta data access"));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Author).toString(), QString::fromLatin1("John Doe"));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Keywords).toString(), QString::fromLatin1("meta data keywords"));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Producer).toString(), QString::fromLatin1("LibreOffice 5.1"));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::Creator).toString(), QString::fromLatin1("Writer"));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::CreationDate).toDateTime(),
+ QDateTime(QDate(2016, 8, 7), QTime(7, 3, 6), QTimeZone::UTC));
+ QCOMPARE(doc.metaData(QPdfDocument::MetaDataField::ModificationDate).toDateTime(),
+ QDateTime(QDate(2016, 8, 8), QTime(8, 3, 6), QTimeZone::UTC));
+}
+
+void tst_QPdfDocument::pageLabels()
+{
+ QPdfDocument doc;
+ QCOMPARE(doc.load(QFINDTESTDATA("test.pdf")), QPdfDocument::Error::None);
+ QCOMPARE(doc.pageCount(), 3);
+ QCOMPARE(doc.pageLabel(0), "Qt");
+ QCOMPARE(doc.pageLabel(1), "1");
+ QCOMPARE(doc.pageLabel(2), "i"); // i of the tiger!
+}
+
+void tst_QPdfDocument::getSelection_data()
+{
+ QTest::addColumn<QString>("pdfPath");
+ QTest::addColumn<int>("page");
+ QTest::addColumn<QPointF>("start");
+ QTest::addColumn<QPointF>("end");
+ QTest::addColumn<QString>("expectedText");
+ QTest::addColumn<int>("expectedStartIndex");
+ QTest::addColumn<int>("expectedEndIndex");
+ QTest::addColumn<QRect>("expectedBounds");
+ QTest::addColumn<int>("expectedPolygonCount");
+
+ QTest::newRow("raid") << QFINDTESTDATA("test.pdf")
+ << 1 << QPointF(316.4, 206) << QPointF(339, 201)
+ << "raid" << 80 << 84 << QRect(316, 201, 21, 12) << 1;
+ QTest::newRow("rotated text") << QFINDTESTDATA("rotated_text.pdf")
+ << 0 << QPointF(102, 94) << QPointF(125, 73)
+ << "world!" << 25 << 31 << QRect(98, 70, 26, 28) << 1;
+}
+
+void tst_QPdfDocument::getSelection()
+{
+ QFETCH(QString, pdfPath);
+ QFETCH(int, page);
+ QFETCH(QPointF, start);
+ QFETCH(QPointF, end);
+ QFETCH(QString, expectedText);
+ QFETCH(int, expectedStartIndex);
+ QFETCH(int, expectedEndIndex);
+ QFETCH(QRect, expectedBounds);
+ QFETCH(int, expectedPolygonCount);
+
+ QPdfDocument doc;
+ QCOMPARE(doc.load(pdfPath), QPdfDocument::Error::None);
+
+ QPdfSelection sel = doc.getSelection(page, start, end);
+ QCOMPARE(sel.text(), expectedText);
+ QCOMPARE(sel.startIndex(), expectedStartIndex);
+ QCOMPARE(sel.endIndex(), expectedEndIndex);
+ QCOMPARE(sel.boundingRectangle().toRect(), expectedBounds);
+ QCOMPARE(sel.bounds().size(), expectedPolygonCount);
+}
+
+void tst_QPdfDocument::getSelectionAtIndex_data()
+{
+ QTest::addColumn<QString>("pdfPath");
+ QTest::addColumn<int>("page");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<int>("maxLen");
+ QTest::addColumn<QString>("expectedText");
+ QTest::addColumn<QRect>("expectedBounds");
+ QTest::addColumn<int>("expectedPolygonCount");
+
+ QTest::newRow("raid") << QFINDTESTDATA("test.pdf")
+ << 1 << 80 << 4 << "raid" << QRect(316, 201, 21, 12) << 1;
+ QTest::newRow("rotated text") << QFINDTESTDATA("rotated_text.pdf")
+ << 0 << 7 << 6 << "world!" << QRect(76, 102, 26, 28) << 1;
+ QTest::newRow("displaced text") << QFINDTESTDATA("tagged_mcr_multipage.pdf")
+ << 0 << 0 << 10 << "1" << QRect(34, 22, 3, 8) << 1;
+}
+
+void tst_QPdfDocument::getSelectionAtIndex()
+{
+ QFETCH(QString, pdfPath);
+ QFETCH(int, page);
+ QFETCH(int, start);
+ QFETCH(int, maxLen);
+ QFETCH(QString, expectedText);
+ QFETCH(QRect, expectedBounds);
+ QFETCH(int, expectedPolygonCount);
+
+ QPdfDocument doc;
+ QCOMPARE(doc.load(pdfPath), QPdfDocument::Error::None);
+
+ QPdfSelection sel = doc.getSelectionAtIndex(page, start, maxLen);
+ QCOMPARE(sel.text(), expectedText);
+ QCOMPARE(sel.boundingRectangle().toRect(), expectedBounds);
+ QCOMPARE(sel.bounds().size(), expectedPolygonCount);
}
QTEST_MAIN(tst_QPdfDocument)
diff --git a/tests/auto/pdf/qpdfpagenavigation/CMakeLists.txt b/tests/auto/pdf/qpdfpagenavigation/CMakeLists.txt
deleted file mode 100644
index 12ece7507..000000000
--- a/tests/auto/pdf/qpdfpagenavigation/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-qt_internal_add_test(tst_qpdfpagenavigation
- SOURCES
- tst_qpdfpagenavigation.cpp
- PUBLIC_LIBRARIES
- Qt::Gui
- Qt::Network
- Qt::Pdf
-)
diff --git a/tests/auto/pdf/qpdfpagenavigation/tst_qpdfpagenavigation.cpp b/tests/auto/pdf/qpdfpagenavigation/tst_qpdfpagenavigation.cpp
deleted file mode 100644
index ff6a02750..000000000
--- a/tests/auto/pdf/qpdfpagenavigation/tst_qpdfpagenavigation.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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:LGPL3$
-** 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 <QtTest/QtTest>
-
-#include <QPdfDocument>
-#include <QPdfPageNavigation>
-
-class tst_QPdfPageNavigation: public QObject
-{
- Q_OBJECT
-
-private slots:
- void defaultValues();
- void setEmptyDocument();
- void setEmptyDocumentAndLoad();
- void setLoadedDocument();
- void unloadDocument();
- void navigate();
-};
-
-void tst_QPdfPageNavigation::defaultValues()
-{
- QPdfPageNavigation pageNavigation;
-
- QCOMPARE(pageNavigation.document(), nullptr);
- QCOMPARE(pageNavigation.currentPage(), 0);
- QCOMPARE(pageNavigation.pageCount(), 0);
- QCOMPARE(pageNavigation.canGoToPreviousPage(), false);
- QCOMPARE(pageNavigation.canGoToNextPage(), false);
-}
-
-void tst_QPdfPageNavigation::setEmptyDocument()
-{
- QPdfDocument document;
- QPdfPageNavigation pageNavigation;
-
- pageNavigation.setDocument(&document);
-
- QCOMPARE(pageNavigation.document(), &document);
- QCOMPARE(pageNavigation.currentPage(), 0);
- QCOMPARE(pageNavigation.pageCount(), 0);
- QCOMPARE(pageNavigation.canGoToPreviousPage(), false);
- QCOMPARE(pageNavigation.canGoToNextPage(), false);
-}
-
-void tst_QPdfPageNavigation::setEmptyDocumentAndLoad()
-{
- QPdfDocument document;
- QPdfPageNavigation pageNavigation;
-
- pageNavigation.setDocument(&document);
-
- QSignalSpy currentPageChangedSpy(&pageNavigation, &QPdfPageNavigation::currentPageChanged);
- QSignalSpy pageCountChangedSpy(&pageNavigation, &QPdfPageNavigation::pageCountChanged);
- QSignalSpy canGoToPreviousPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged);
- QSignalSpy canGoToNextPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged);
-
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagenavigation.pdf")), QPdfDocument::NoError);
-
- QCOMPARE(currentPageChangedSpy.count(), 0); // current page stays '0'
- QCOMPARE(pageCountChangedSpy.count(), 1);
- QCOMPARE(pageCountChangedSpy[0][0].toInt(), 3);
- QCOMPARE(canGoToPreviousPageChangedSpy.count(), 0); // still no previous page available
- QCOMPARE(canGoToNextPageChangedSpy.count(), 1);
- QCOMPARE(canGoToNextPageChangedSpy[0][0].toBool(), true);
-}
-
-void tst_QPdfPageNavigation::setLoadedDocument()
-{
- QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagenavigation.pdf")), QPdfDocument::NoError);
-
- QPdfPageNavigation pageNavigation;
-
- QSignalSpy currentPageChangedSpy(&pageNavigation, &QPdfPageNavigation::currentPageChanged);
- QSignalSpy pageCountChangedSpy(&pageNavigation, &QPdfPageNavigation::pageCountChanged);
- QSignalSpy canGoToPreviousPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged);
- QSignalSpy canGoToNextPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged);
-
- pageNavigation.setDocument(&document);
-
- QCOMPARE(currentPageChangedSpy.count(), 0); // current page stays '0'
- QCOMPARE(pageCountChangedSpy.count(), 1);
- QCOMPARE(pageCountChangedSpy[0][0].toInt(), 3);
- QCOMPARE(canGoToPreviousPageChangedSpy.count(), 0); // still no previous page available
- QCOMPARE(canGoToNextPageChangedSpy.count(), 1);
- QCOMPARE(canGoToNextPageChangedSpy[0][0].toBool(), true);
-}
-
-void tst_QPdfPageNavigation::unloadDocument()
-{
- QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagenavigation.pdf")), QPdfDocument::NoError);
-
- QPdfPageNavigation pageNavigation;
- pageNavigation.setDocument(&document);
-
- QSignalSpy currentPageChangedSpy(&pageNavigation, &QPdfPageNavigation::currentPageChanged);
- QSignalSpy pageCountChangedSpy(&pageNavigation, &QPdfPageNavigation::pageCountChanged);
- QSignalSpy canGoToPreviousPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged);
- QSignalSpy canGoToNextPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged);
-
- document.close();
-
- QCOMPARE(currentPageChangedSpy.count(), 0); // current page stays '0'
- QCOMPARE(pageCountChangedSpy.count(), 1);
- QCOMPARE(pageCountChangedSpy[0][0].toInt(), 0);
- QCOMPARE(canGoToPreviousPageChangedSpy.count(), 0); // still no previous page available
- QCOMPARE(canGoToNextPageChangedSpy.count(), 1);
- QCOMPARE(canGoToNextPageChangedSpy[0][0].toBool(), false);
-}
-
-void tst_QPdfPageNavigation::navigate()
-{
- QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagenavigation.pdf")), QPdfDocument::NoError);
-
- QPdfPageNavigation pageNavigation;
- pageNavigation.setDocument(&document);
-
- QSignalSpy currentPageChangedSpy(&pageNavigation, &QPdfPageNavigation::currentPageChanged);
- QSignalSpy canGoToPreviousPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToPreviousPageChanged);
- QSignalSpy canGoToNextPageChangedSpy(&pageNavigation, &QPdfPageNavigation::canGoToNextPageChanged);
-
- QCOMPARE(pageNavigation.currentPage(), 0);
-
- // try to go to previous page while there is none
- QCOMPARE(pageNavigation.canGoToPreviousPage(), false);
- pageNavigation.goToPreviousPage();
- QCOMPARE(canGoToPreviousPageChangedSpy.count(), 0);
- QCOMPARE(pageNavigation.currentPage(), 0);
- QCOMPARE(pageNavigation.canGoToPreviousPage(), false);
-
- // try to go to next page
- QCOMPARE(pageNavigation.canGoToNextPage(), true);
- pageNavigation.goToNextPage();
- QCOMPARE(canGoToPreviousPageChangedSpy.count(), 1);
- QCOMPARE(canGoToNextPageChangedSpy.count(), 0);
- QCOMPARE(currentPageChangedSpy.count(), 1);
- QCOMPARE(pageNavigation.currentPage(), 1);
- QCOMPARE(pageNavigation.canGoToPreviousPage(), true);
-
- currentPageChangedSpy.clear();
- canGoToPreviousPageChangedSpy.clear();
- canGoToNextPageChangedSpy.clear();
-
- // try to go to last page
- pageNavigation.setCurrentPage(2);
- QCOMPARE(canGoToPreviousPageChangedSpy.count(), 0);
- QCOMPARE(canGoToNextPageChangedSpy.count(), 1);
- QCOMPARE(currentPageChangedSpy.count(), 1);
- QCOMPARE(pageNavigation.currentPage(), 2);
- QCOMPARE(pageNavigation.canGoToNextPage(), false);
-
- // check that invalid requests are ignored
- pageNavigation.setCurrentPage(-1);
- QCOMPARE(pageNavigation.currentPage(), 2);
-
- pageNavigation.setCurrentPage(3);
- QCOMPARE(pageNavigation.currentPage(), 2);
-}
-
-QTEST_MAIN(tst_QPdfPageNavigation)
-
-#include "tst_qpdfpagenavigation.moc"
diff --git a/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt b/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt
new file mode 100644
index 000000000..3e8b8f416
--- /dev/null
+++ b/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_test(tst_qpdfpagenavigator.cpp
+ SOURCES
+ tst_qpdfpagenavigator.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::Network
+ Qt::Pdf
+ Qt::PdfWidgets
+ TESTDATA
+ pdf-sample.bookmarks_pages.pdf
+)
diff --git a/tests/auto/pdf/qpdfpagenavigation/pdf-sample.pagenavigation.pdf b/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf
index c4e1aa36e..c4e1aa36e 100644
--- a/tests/auto/pdf/qpdfpagenavigation/pdf-sample.pagenavigation.pdf
+++ b/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf
Binary files differ
diff --git a/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp
new file mode 100644
index 000000000..327a9f36a
--- /dev/null
+++ b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+
+#include <QtTest/QtTest>
+
+#include <QPdfDocument>
+#include <QPdfView>
+#include <QPdfPageNavigator>
+
+class tst_QPdfPageNavigator: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void offScreenSignals();
+};
+
+void tst_QPdfPageNavigator::offScreenSignals()
+{
+ QPdfDocument document;
+ QPdfView pdfView;
+ QPdfPageNavigator *navigator = pdfView.pageNavigator();
+
+ QSignalSpy currentPageChanged(navigator, &QPdfPageNavigator::currentPageChanged);
+ QSignalSpy currentLocationChanged(navigator, &QPdfPageNavigator::currentLocationChanged);
+ QSignalSpy backAvailableChanged(navigator, &QPdfPageNavigator::backAvailableChanged);
+ QSignalSpy forwardAvailableChanged(navigator, &QPdfPageNavigator::forwardAvailableChanged);
+ QSignalSpy jumped(navigator, &QPdfPageNavigator::jumped);
+
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None);
+ QVERIFY2(document.pageCount() == 3, "Test document has changed! 3 pages expected.");
+ pdfView.setDocument(&document);
+
+ // Start with a clean history
+ QCOMPARE(forwardAvailableChanged.count(), 0);
+ QCOMPARE(backAvailableChanged.count(), 0);
+
+ navigator->jump(3, QPoint());
+ QCOMPARE(forwardAvailableChanged.count(), 0);
+ QCOMPARE(backAvailableChanged.count(), 1);
+ QCOMPARE(currentPageChanged.count(), 1);
+ QCOMPARE(currentLocationChanged.count(), 0);
+ QCOMPARE(jumped.count(), 1);
+
+ navigator->jump(1, QPoint());
+ QCOMPARE(forwardAvailableChanged.count(), 0);
+ QCOMPARE(backAvailableChanged.count(), 1);
+ QCOMPARE(currentPageChanged.count(), 2);
+ QCOMPARE(currentLocationChanged.count(), 0);
+ QCOMPARE(jumped.count(), 2);
+
+ navigator->back();
+ QCOMPARE(forwardAvailableChanged.count(), 1);
+ QCOMPARE(backAvailableChanged.count(), 1);
+ QCOMPARE(currentPageChanged.count(), 3);
+ QCOMPARE(currentLocationChanged.count(), 0);
+ QCOMPARE(jumped.count(), 3);
+
+ navigator->forward();
+ QCOMPARE(forwardAvailableChanged.count(), 2);
+ QCOMPARE(backAvailableChanged.count(), 1);
+ QCOMPARE(currentPageChanged.count(), 4);
+ QCOMPARE(currentLocationChanged.count(), 0);
+ QCOMPARE(jumped.count(), 4);
+}
+
+QTEST_MAIN(tst_QPdfPageNavigator)
+
+#include "tst_qpdfpagenavigator.moc"
diff --git a/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt b/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt
index f4084cce1..53a68fe59 100644
--- a/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfpagerenderer/CMakeLists.txt
@@ -1,9 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfpagerenderer
SOURCES
tst_qpdfpagerenderer.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::Pdf
+ TESTDATA
+ pdf-sample.pagerenderer.pdf
)
diff --git a/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp b/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
index 534fbd9ce..39d32df0b 100644
--- a/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
+++ b/tests/auto/pdf/qpdfpagerenderer/tst_qpdfpagerenderer.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPDF module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias König <tobias.koenig@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QPdfDocument>
#include <QPdfPageRenderer>
@@ -89,7 +56,7 @@ void tst_QPdfPageRenderer::withLoadedDocumentSingleThreaded()
QPdfPageRenderer pageRenderer;
pageRenderer.setDocument(&document);
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::Error::None);
QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered);
@@ -97,7 +64,7 @@ void tst_QPdfPageRenderer::withLoadedDocumentSingleThreaded()
const quint64 requestId = pageRenderer.requestPage(0, imageSize);
QCOMPARE(requestId, quint64(1));
- QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QTRY_COMPARE(pageRenderedSpy.size(), 1);
QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
@@ -112,7 +79,7 @@ void tst_QPdfPageRenderer::withLoadedDocumentMultiThreaded()
pageRenderer.setDocument(&document);
pageRenderer.setRenderMode(QPdfPageRenderer::RenderMode::MultiThreaded);
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::Error::None);
QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered);
@@ -120,7 +87,7 @@ void tst_QPdfPageRenderer::withLoadedDocumentMultiThreaded()
const quint64 requestId = pageRenderer.requestPage(0, imageSize);
QCOMPARE(requestId, quint64(1));
- QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QTRY_COMPARE(pageRenderedSpy.size(), 1);
QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
@@ -133,7 +100,7 @@ void tst_QPdfPageRenderer::switchingRenderMode()
QPdfPageRenderer pageRenderer;
pageRenderer.setDocument(&document);
- QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.pagerenderer.pdf")), QPdfDocument::Error::None);
QSignalSpy pageRenderedSpy(&pageRenderer, &QPdfPageRenderer::pageRendered);
@@ -141,7 +108,7 @@ void tst_QPdfPageRenderer::switchingRenderMode()
const QSize imageSize(100, 100);
const quint64 firstRequestId = pageRenderer.requestPage(0, imageSize);
- QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QTRY_COMPARE(pageRenderedSpy.size(), 1);
QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
QCOMPARE(pageRenderedSpy[0][2].value<QImage>().size(), imageSize);
@@ -157,7 +124,7 @@ void tst_QPdfPageRenderer::switchingRenderMode()
const quint64 secondRequestId = pageRenderer.requestPage(0, imageSize);
QVERIFY(firstRequestId != secondRequestId);
- QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QTRY_COMPARE(pageRenderedSpy.size(), 1);
QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
QCOMPARE(pageRenderedSpy[0][2].value<QImage>(), image);
@@ -171,7 +138,7 @@ void tst_QPdfPageRenderer::switchingRenderMode()
const quint64 thirdRequestId = pageRenderer.requestPage(0, imageSize);
- QTRY_COMPARE(pageRenderedSpy.count(), 1);
+ QTRY_COMPARE(pageRenderedSpy.size(), 1);
QCOMPARE(pageRenderedSpy[0][0].toInt(), 0);
QCOMPARE(pageRenderedSpy[0][1].toSize(), imageSize);
QCOMPARE(pageRenderedSpy[0][2].value<QImage>(), image);
diff --git a/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt b/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt
index 2c3e744d0..668d1ea36 100644
--- a/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt
+++ b/tests/auto/pdf/qpdfsearchmodel/CMakeLists.txt
@@ -1,8 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qpdfsearchmodel
SOURCES
tst_qpdfsearchmodel.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Network
Qt::Pdf
+ TESTDATA
+ rotated_text.pdf
+ tagged_mcr_multipage.pdf
+ test.pdf
)
diff --git a/tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf b/tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf
new file mode 100644
index 000000000..d6d8db84e
--- /dev/null
+++ b/tests/auto/pdf/qpdfsearchmodel/rotated_text.pdf
@@ -0,0 +1,70 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /MediaBox [ 0 0 200 200 ]
+ /Count 1
+ /Kids [ 3 0 R ]
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Resources <<
+ /Font <<
+ /F1 4 0 R
+ >>
+ >>
+ /Contents 5 0 R
+>>
+endobj
+4 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Times-Roman
+>>
+endobj
+5 0 obj <<
+ /Length 406
+>>
+stream
+BT
+0 0 Td
+/F1 12 Tf
+0.70710678118 -0.70710678118 0.70710678118 0.70710678118 100 100 Tm
+(Hello,) Tj
+0 0 Td
+/F1 12 Tf
+-0.70710678118 -0.70710678118 0.70710678118 -0.70710678118 100 100 Tm
+( world!\r\n) Tj
+0 0 Td
+/F1 12 Tf
+-0.70710678118 0.70710678118 -0.70710678118 -0.70710678118 100 100 Tm
+(Goodbye,) Tj
+0 0 Td
+/F1 12 Tf
+0.70710678118 0.70710678118 -0.70710678118 0.70710678118 100 100 Tm
+( world!) Tj
+ET
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000161 00000 n
+0000000287 00000 n
+0000000365 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 6
+>>
+startxref
+823
+%%EOF
diff --git a/tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf b/tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf
new file mode 100644
index 000000000..fcc5fafda
--- /dev/null
+++ b/tests/auto/pdf/qpdfsearchmodel/tagged_mcr_multipage.pdf
@@ -0,0 +1,136 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /MarkInfo <<
+ /Type /MarkInfo
+ /Marked true
+ >>
+ /Pages 2 0 R
+ /StructTreeRoot 8 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /CropBox [ 10.8197 8.459 605.705 801.639 ]
+ /MediaBox [ 0.0 0.0 616.721 809.902 ]
+ /Count 2
+ /Kids [
+ 4 0 R
+ 6 0 R
+ ]
+>>
+endobj
+3 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Times-Roman
+>>
+endobj
+4 0 obj <<
+ /Type /Page
+ /Tabs /S
+ /Parent 2 0 R
+ /StructParents 0
+ /Contents 5 0 R
+ /Resources <<
+ /ProcSet [/PDF /Text]
+ /Font <<
+ /F1 3 0 R
+ >>
+ >>
+>>
+endobj
+5 0 obj <<
+ /Length 83
+>>
+stream
+BT
+/Document <</MCID 0 >>BDC
+0 i
+/F1 1 Tf
+12 0 0 12 43.073 771.625 Tm
+(1)Tj
+EMC
+ET
+endstream
+endobj
+6 0 obj <<
+ /Type /Page
+ /Tabs /S
+ /Parent 2 0 R
+ /StructParents 1
+ /Contents 7 0 R
+ /Resources <<
+ /ProcSet [/PDF /Text]
+ /Font <<
+ /F1 3 0 R
+ >>
+ >>
+>>
+endobj
+7 0 obj <<
+ /Length 83
+>>
+stream
+BT
+/Document <</MCID 0 >>BDC
+0 i
+/F1 1 Tf
+12 0 0 12 43.073 771.625 Tm
+(2)Tj
+EMC
+ET
+endstream
+endobj
+8 0 obj <<
+ /Type /StructTreeRoot
+ /K 10 0 R
+ /ParentTree 9 0 R
+ /ParentTreeNextKey 2
+>>
+endobj
+9 0 obj <<
+ /Nums [
+ 0
+ [10 0 R]
+ 1
+ [10 0 R]
+ ]
+>>
+endobj
+10 0 obj <<
+ /T ()
+ /S /Document
+ /P 8 0 R
+ /Pg 4 0 R
+ /K [
+ 0
+ <<
+ /MCID 0
+ /Pg 6 0 R
+ /Type /MCR
+ >>
+ ]
+>>
+%endobj
+xref
+0 11
+0000000000 65535 f
+0000000015 00000 n
+0000000149 00000 n
+0000000315 00000 n
+0000000393 00000 n
+0000000575 00000 n
+0000000709 00000 n
+0000000891 00000 n
+0000001025 00000 n
+0000001125 00000 n
+0000001198 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 11
+>>
+startxref
+1345
+%%EOF
diff --git a/tests/auto/pdf/qpdfsearchmodel/test.pdf b/tests/auto/pdf/qpdfsearchmodel/test.pdf
index a9dc1bc29..0832dfbed 100644
--- a/tests/auto/pdf/qpdfsearchmodel/test.pdf
+++ b/tests/auto/pdf/qpdfsearchmodel/test.pdf
Binary files differ
diff --git a/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp b/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp
index c0706faaf..cf71b148e 100644
--- a/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp
+++ b/tests/auto/pdf/qpdfsearchmodel/tst_qpdfsearchmodel.cpp
@@ -1,38 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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:LGPL3$
-** 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtTest/QtTest>
@@ -40,6 +7,8 @@
#include <QPdfDocument>
#include <QPdfSearchModel>
+Q_LOGGING_CATEGORY(lcTests, "qt.pdf.tests")
+
class tst_QPdfSearchModel: public QObject
{
Q_OBJECT
@@ -48,20 +17,51 @@ public:
tst_QPdfSearchModel() {}
private slots:
+ void findText_data();
void findText();
};
+void tst_QPdfSearchModel::findText_data()
+{
+ QTest::addColumn<QString>("pdfPath");
+ QTest::addColumn<QString>("searchString");
+ QTest::addColumn<int>("expectedMatchCount");
+ QTest::addColumn<int>("matchIndexToCheck");
+ QTest::addColumn<int>("expectedRectangleCount");
+ QTest::addColumn<int>("rectIndexToCheck");
+ QTest::addColumn<QRect>("expectedMatchBounds");
+
+ QTest::newRow("the search for ai") << QFINDTESTDATA("test.pdf")
+ << "ai" << 3 << 0 << 1 << 0 << QRect(321, 202, 9, 11);
+ QTest::newRow("rotated text") << QFINDTESTDATA("rotated_text.pdf")
+ << "world!" << 2 << 0 << 1 << 0 << QRect(76, 102, 26, 28);
+ QTest::newRow("displaced text") << QFINDTESTDATA("tagged_mcr_multipage.pdf")
+ << "1" << 1 << 0 << 1 << 0 << QRect(34, 22, 3, 8);
+}
+
void tst_QPdfSearchModel::findText()
{
+ QFETCH(QString, pdfPath);
+ QFETCH(QString, searchString);
+ QFETCH(int, expectedMatchCount);
+ QFETCH(int, matchIndexToCheck);
+ QFETCH(int, expectedRectangleCount);
+ QFETCH(int, rectIndexToCheck);
+ QFETCH(QRect, expectedMatchBounds);
+
QPdfDocument document;
- QCOMPARE(document.load(QFINDTESTDATA("test.pdf")), QPdfDocument::NoError);
+ QCOMPARE(document.load(pdfPath), QPdfDocument::Error::None);
QPdfSearchModel model;
model.setDocument(&document);
- QList<QRectF> matches = model.matches(1, "ai");
+ model.setSearchString(searchString);
- qDebug() << matches;
- QCOMPARE(matches.count(), 3);
+ QTRY_COMPARE(model.count(), expectedMatchCount); // wait for the timer
+ QPdfLink match = model.resultAtIndex(matchIndexToCheck);
+ qCDebug(lcTests) << match;
+ QList<QRectF> rects = match.rectangles();
+ QCOMPARE(rects.size(), expectedRectangleCount);
+ QCOMPARE(rects.at(rectIndexToCheck).toRect(), expectedMatchBounds);
}
QTEST_MAIN(tst_QPdfSearchModel)
diff --git a/tests/auto/pdfquick/CMakeLists.txt b/tests/auto/pdfquick/CMakeLists.txt
new file mode 100644
index 000000000..e6a3a460c
--- /dev/null
+++ b/tests/auto/pdfquick/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(multipageview)
+add_subdirectory(pdfpageimage)
diff --git a/tests/auto/pdfquick/multipageview/BLACKLIST b/tests/auto/pdfquick/multipageview/BLACKLIST
new file mode 100644
index 000000000..9012902f6
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/BLACKLIST
@@ -0,0 +1,7 @@
+# QTBUG-111306
+[navigation:click links and go back, twice]
+android
+
+# QTBUG-111306
+[navigation:click two links in series and then go back]
+android
diff --git a/tests/auto/pdfquick/multipageview/CMakeLists.txt b/tests/auto/pdfquick/multipageview/CMakeLists.txt
new file mode 100644
index 000000000..50f7d7d8f
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Collect test data
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_multipageview
+ SOURCES
+ tst_multipageview.cpp
+ ../shared/util.cpp ../shared/util.h
+ LIBRARIES
+ Qt::Gui
+ Qt::Quick
+ Qt::PdfQuickPrivate
+ TESTDATA ${test_data}
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_multipageview CONDITION ANDROID OR IOS
+ DEFINES
+ QT_QMLTEST_DATADIR=":/data"
+)
+
+qt_internal_extend_target(tst_multipageview CONDITION NOT ANDROID AND NOT IOS
+ DEFINES
+ QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
+)
+
diff --git a/tests/auto/pdfquick/multipageview/data/bookmarksAndLinks.pdf b/tests/auto/pdfquick/multipageview/data/bookmarksAndLinks.pdf
new file mode 100644
index 000000000..aa0b99039
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/data/bookmarksAndLinks.pdf
@@ -0,0 +1,317 @@
+%PDF-1.7
+
+1 0 obj
+<<
+ /Type /Catalog
+ /PageMode /FullScreen
+ /Outlines 6 0 R
+ /Pages 2 0 R
+ /Names 50 0 R
+ /PageLabels 23 0 R
+ /ViewerPreferences<</NonFullScreenPageMode (UseThumbs)>>
+>>
+endobj
+
+50 0 obj
+<<
+ /Dests <</Names [ (ToTest2) [4 0 R /XYZ 300 300 1] (ToTest3) [5 0 R /XYZ 290 10 0.5] (ToTest1) [3 0 R /XYZ 600 800 1] ]>>
+>>
+endobj
+
+23 0 obj
+<<
+ /Nums [0 <</S /D /P(test )>> 3 <</S /A >> 4<</S /R/St >> 5<</S /r/St >> ]
+ /Limits [0 5]
+>>
+endobj
+
+2 0 obj
+<<
+ /Type /Pages
+ /Kids [3 0 R 4 0 R 5 0 R]
+ /Count 3
+>>
+endobj
+
+3 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 10 600 800]
+ /Annots [24 0 R 25 0 R]
+ /Contents 16 0 R
+ /Resources <<
+ /Font <</F1 18 0 R>>
+ >>
+>>
+endobj
+
+24 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest2)
+ /A << /Type /Action
+ /S /GoTo
+ /D [5 0 R /FitR ¨C4 399 199 533]
+ >>
+ /Rect [10 690 150 720]
+
+>>
+endobj
+
+25 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest3)
+ /Rect [10 630 150 650]
+>>
+endobj
+
+
+16 0 obj
+<< /Length 0 >>
+ stream
+ BT
+ /F1 72 Tf
+ 200 200 TD
+ 0 0 1 RG
+ 5 Tr
+ (Test_1) Tj
+ 0 800 m
+ 600 0 l S
+ /F1 30 Tf
+ 0 1 0 RG
+ 1 Tr
+ -190 490 TD
+ (GO Test_2) Tj
+ 0 -50 TD
+ 5 w
+ 2 Tr
+ 1 0 0 RG
+ (GO Test_3) Tj
+ ET
+ endstream
+endobj
+
+
+endobj
+
+18 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F1
+ /BaseFont /Helvetica
+>>
+endobj
+
+4 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [10 0 500 700]
+ /Annots [60 0 R]
+ /Contents 19 0 R
+ /Resources <<
+ /Font <</F2 20 0 R>>
+ >>
+>>
+endobj
+
+19 0 obj
+<< /Length 0 >>
+stream
+BT
+ 1 -0.7 0 1 30 100 cm
+ /F2 50 Tf
+ 10 50 TD
+ (TEST_2) Tj
+
+ 1 0.7 0 1 -30 -100 cm
+ /F2 25 Tf
+ 1 0 1 RG
+ 7 w
+ 100 60 TD
+
+ (GO Test_1) Tj
+ 100 100 140 40 re S f
+ET
+endstream
+endobj
+
+20 0 obj
+<<
+ /Type /Font
+ /Subtype /TrueType
+ /Name /F2
+ /BaseFont /NewYork , Bold
+ /FirstChar 0
+ /LastChar 255
+ /Widths 23 0 R
+ /FontDescriptor 7 0 R
+ /Encoding /MacRomanEncoding
+>>
+endobj
+
+60 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest1)
+ /Rect [110 110 230 150]
+>>
+endobj
+
+5 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [-10 -10 400 600]
+ /Annots [61 0 R]
+ /Contents 21 0 R
+ /Resources << /Font <</F3 22 0 R>> >>
+>>
+endobj
+
+21 0 obj
+<< /Length 0 >>
+stream
+BT
+ /F3 30 Tf
+ 290 10 TD
+ (TEST_3) Tj
+ -50 90 TD
+ (GO Test_2)Tj
+ET
+endstream
+endobj
+
+22 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F3
+ /BaseFont /Courier-Bold
+>>
+endobj
+
+61 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest2)
+ /Rect [240 90 400 130]
+>>
+
+6 0 obj
+<<
+ /Type /Outlines
+ /First 7 0 R
+ /Last 11 0 R
+ /Count 4 0 R
+>>
+endobj
+
+7 0 obj
+<<
+ /Title (First)
+ /Parent 6 0 R
+ /Next 8 0 R
+ /C [1 0 0]
+ /Dest [ 3 0 R /XYZ 600 800 0.5 ]
+>>
+endobj
+
+8 0 obj
+<<
+ /Title (Second)
+ /Parent 6 0 R
+ /Prev 7 0 R
+ /Next 9 0 R
+ /C [0 1 0]
+ % /Dest [ 4 0 R /XYZ 500 700 null ]
+/Dest (ToTest2)
+>>
+endobj
+
+9 0 obj
+<<
+ /Title (Third)
+ /Parent 6 0 R
+ /Prev 8 0 R
+ /Next 10 0 R
+ /C [0 0 1]
+ /Dest [ 5 0 R /XYZ 400 600 0.8 ]
+>>
+endobj
+
+10 0 obj
+<<
+ /Title (Fourth)
+ /Parent 6 0 R
+ /Prev 9 0 R
+ /Next 11 0 R
+>>
+endobj
+
+11 0 obj
+<<
+ /Title (Fivth)
+ /Parent 6 0 R
+ /Prev 10 0 R
+ /First 12 0 R
+ /Last 15 0 R
+ /Count 4
+>>
+endobj
+
+12 0 obj
+<<
+ /Title (Fivth_1)
+ /Parent 11 0 R
+ /Next 13 0 R
+>>
+endobj
+
+13 0 obj
+<<
+ /Title (Fivth_2)
+ /Parent 11 0 R
+ /Prev 12 0 R
+ /Next 14 0 R
+>>
+endobj
+
+14 0 obj
+<<
+ /Title (Fivth_3)
+ /Parent 11 0 R
+ /Prev 13 0 R
+ /Next 15 0 R
+>>
+endobj
+
+15 0 obj
+<<
+ /Title (Fivth_4)
+ /Parent 11 0 R
+ /Prev 14 0 R
+>>
+endobj
+
+
+
+
+xref
+0000000000 65536 f
+
+trailer
+<<
+ /Size 0
+ /Root 1 0 R
+>>
+startxref
+0
+%%EOF
diff --git a/tests/auto/pdfquick/multipageview/data/jumpOnDocumentReady.qml b/tests/auto/pdfquick/multipageview/data/jumpOnDocumentReady.qml
new file mode 100644
index 000000000..ce74f5ed8
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/data/jumpOnDocumentReady.qml
@@ -0,0 +1,18 @@
+import QtQuick
+import QtQuick.Pdf
+
+PdfMultiPageView {
+ id: view
+ width: 480
+ height: 480
+
+ document: PdfDocument {
+ id: document
+ onStatusChanged: {
+ if(status === PdfDocument.Ready)
+ view.goToPage(2)
+ }
+ }
+
+ Component.onCompleted: document.source = "bookmarksAndLinks.pdf"
+}
diff --git a/tests/auto/pdfquick/multipageview/data/multiPageView.qml b/tests/auto/pdfquick/multipageview/data/multiPageView.qml
new file mode 100644
index 000000000..bf88180ce
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/data/multiPageView.qml
@@ -0,0 +1,8 @@
+import QtQuick
+import QtQuick.Pdf
+
+PdfMultiPageView {
+ width: 480; height: 480
+ property alias source: document.source
+ document: PdfDocument { id: document }
+}
diff --git a/tests/auto/pdfquick/multipageview/data/multiPageViewWithFeedback.qml b/tests/auto/pdfquick/multipageview/data/multiPageViewWithFeedback.qml
new file mode 100644
index 000000000..93a556c97
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/data/multiPageViewWithFeedback.qml
@@ -0,0 +1,18 @@
+import QtQuick
+import QtQuick.Pdf
+
+PdfMultiPageView {
+ id: view
+ property point hoverPos: hover.point.position
+ width: 640; height: 480
+ document: PdfDocument { }
+
+ // mouse hover feedback for test development
+ Rectangle {
+ width: 200
+ height: hoverPosLabel.implicitHeight + 12
+ color: "beige"
+ Text { id: hoverPosLabel; x: 6; y: 6; text: view.hoverPos.x + ", " + view.hoverPos.y }
+ }
+ HoverHandler { id: hover }
+}
diff --git a/tests/auto/pdfquick/multipageview/data/pdf-sample.protected.pdf b/tests/auto/pdfquick/multipageview/data/pdf-sample.protected.pdf
new file mode 100644
index 000000000..d76fdd1a6
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/data/pdf-sample.protected.pdf
Binary files differ
diff --git a/tests/auto/pdfquick/multipageview/data/qpdfwriter.pdf b/tests/auto/pdfquick/multipageview/data/qpdfwriter.pdf
new file mode 100644
index 000000000..4abc76f6d
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/data/qpdfwriter.pdf
Binary files differ
diff --git a/tests/auto/pdfquick/multipageview/tst_multipageview.cpp b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
new file mode 100644
index 000000000..c5e0b30db
--- /dev/null
+++ b/tests/auto/pdfquick/multipageview/tst_multipageview.cpp
@@ -0,0 +1,446 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QSignalSpy>
+#include <QTest>
+#include <QtCore/QLoggingCategory>
+#include <QtGui/QClipboard>
+#include <QtGui/QPointingDevice>
+#include <QtGui/QStyleHints>
+#include <QtQuick/QQuickView>
+#include <QtPdfQuick/private/qquickpdflinkmodel_p.h>
+#include <QtPdfQuick/private/qquickpdfsearchmodel_p.h>
+#include <QtPdfQuick/private/qquickpdfpageimage_p.h>
+#include "../shared/util.h"
+
+using namespace Qt::StringLiterals;
+
+Q_LOGGING_CATEGORY(lcTests, "qt.pdf.tests")
+
+class tst_MultiPageView : public QQuickDataTest
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void internalLink_data();
+ void internalLink();
+ void navigation_data();
+ void navigation();
+ void password();
+ void selectionAndClipboard();
+ void search();
+ void pinchDragPinch();
+ void jumpOnDocumentReady();
+
+public:
+ enum NavigationAction {
+ Back,
+ Forward,
+ GotoPage,
+ GotoLocation,
+ ClickLink
+ };
+ Q_ENUM(NavigationAction)
+
+ struct NavigationCommand {
+ NavigationAction action;
+ int index;
+ QPointF location;
+ qreal zoom;
+ QPointF expectedContentPos;
+ int expectedCurrentPage;
+ };
+
+private:
+ QScopedPointer<QPointingDevice> touchscreen = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
+};
+
+void tst_MultiPageView::internalLink_data()
+{
+ QTest::addColumn<int>("linkIndex");
+ QTest::addColumn<int>("expectedPage");
+ QTest::addColumn<qreal>("expectedZoom");
+ QTest::addColumn<QPoint>("expectedScroll");
+
+ QTest::newRow("first link") << 0 << 1 << qreal(1) << QPoint(134, 1286);
+ // TODO fails because it zooms out, and the view leaves gaps between pages currently
+// QTest::newRow("second link") << 1 << 2 << qreal(0.5) << QPoint(0, 717);
+}
+
+void tst_MultiPageView::internalLink()
+{
+ QFETCH(int, linkIndex);
+ QFETCH(int, expectedPage);
+ QFETCH(qreal, expectedZoom);
+ QFETCH(QPoint, expectedScroll);
+
+ QQuickView window;
+ QVERIFY(showView(window, testFileUrl("multiPageView.qml")));
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+ pdfView->setProperty("source", testFileUrl("bookmarksAndLinks.pdf"));
+ QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
+
+ QQuickItem *table = static_cast<QQuickItem *>(findFirstChild(pdfView, "QQuickTableView"));
+ QVERIFY(table);
+ QQuickItem *firstPage = tableViewItemAtCell(table, 0, 0);
+ QVERIFY(firstPage);
+ QQuickPdfLinkModel *linkModel = firstPage->findChild<QQuickPdfLinkModel*>();
+ QVERIFY(linkModel);
+ QQuickItem *repeater = qobject_cast<QQuickItem *>(linkModel->parent());
+ QVERIFY(repeater);
+ QVERIFY(repeater->property("count").toInt() > linkIndex);
+
+ QCOMPARE(pdfView->property("backEnabled").toBool(), false);
+ QCOMPARE(pdfView->property("forwardEnabled").toBool(), false);
+
+ // get the PdfLinkDelegate instance, which has a TapHandler declared inside
+ QQuickItem *linkDelegate = repeaterItemAt(repeater, linkIndex);
+ QVERIFY(linkDelegate);
+ const auto modelIdx = linkModel->index(linkIndex);
+ const int linkPage = linkModel->data(modelIdx, int(QPdfLinkModel::Role::Page)).toInt();
+ QVERIFY(linkPage >= 0);
+ const QPointF linkLocation = linkModel->data(modelIdx, int(QPdfLinkModel::Role::Location)).toPointF();
+ const qreal linkZoom = linkModel->data(modelIdx, int(QPdfLinkModel::Role::Zoom)).toReal();
+
+ // click on it, and check whether it went to the right place
+ const auto point = linkDelegate->position().toPoint() + QPoint(15, 15);
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, point);
+ QTRY_COMPARE(tableViewContentPos(table).y(), expectedScroll.y());
+ const auto linkScrollPos = tableViewContentPos(table);
+ qCDebug(lcTests, "clicked link @ %d, %d and expected scrolling to %d, %d; actually scrolled to %d, %d",
+ point.x(), point.y(), expectedScroll.x(), expectedScroll.y(), linkScrollPos.x(), linkScrollPos.y());
+ QVERIFY(qAbs(linkScrollPos.x() - expectedScroll.x()) < 15);
+ QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
+ QCOMPARE(pdfView->property("currentPage").toInt(), linkPage);
+ QCOMPARE(linkPage, expectedPage);
+ QCOMPARE(pdfView->property("renderScale").toReal(), linkZoom);
+ QCOMPARE(linkZoom, expectedZoom);
+ qCDebug(lcTests, "link %d goes to page %d location {%lf,%lf} zoom %lf scroll to {%lf,%lf}",
+ linkIndex, linkPage, linkLocation.x(), linkLocation.y(), linkZoom,
+ table->property("contentX").toReal(), table->property("contentY").toReal());
+
+ // check that we can go back to where we came from
+ QCOMPARE(pdfView->property("backEnabled").toBool(), true);
+ QCOMPARE(pdfView->property("forwardEnabled").toBool(), false);
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "back"));
+ QTRY_COMPARE(tableViewContentPos(table), QPoint(0, 0));
+ QCOMPARE(pdfView->property("currentPage").toInt(), 0);
+ QCOMPARE(pdfView->property("renderScale").toReal(), qreal(1));
+
+ // and then forward again
+ QCOMPARE(pdfView->property("backEnabled").toBool(), false);
+ QCOMPARE(pdfView->property("forwardEnabled").toBool(), true);
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "forward"));
+ QTRY_COMPARE(tableViewContentPos(table), linkScrollPos);
+ QCOMPARE(pdfView->property("currentPage").toInt(), linkPage);
+ QCOMPARE(pdfView->property("renderScale").toReal(), linkZoom);
+}
+
+void tst_MultiPageView::navigation_data()
+{
+ QTest::addColumn<QList<NavigationCommand>>("actions");
+ const int totalPageSpacing = 832; // 826 points + 6 px (rowSpacing)
+
+ QList<NavigationCommand> actions;
+ actions << NavigationCommand {NavigationAction::GotoPage, 2, {}, 0, {0, 1664}, 2}
+ << NavigationCommand {NavigationAction::GotoPage, 3, {}, 0, {0, 2496}, 3}
+ << NavigationCommand {NavigationAction::Back, 0, {}, 0, {0, 1664}, 2}
+ << NavigationCommand {NavigationAction::Back, 0, {}, 0, {0, 0}, 0};
+ QTest::newRow("goto and back") << actions;
+
+ actions.clear();
+ actions // first link is "More..." going to page 0, location 8, 740
+ << NavigationCommand {NavigationAction::ClickLink, 0, {465, 65}, 0, {0, 740}, 0}
+ << NavigationCommand {NavigationAction::Back, 0, {}, 0, {0, 0}, 0}
+ // link "setPdfVersion()" going to page 3, location 8, 295
+ << NavigationCommand {NavigationAction::ClickLink, 0, {255, 455}, 0, {0, totalPageSpacing * 3 + 295}, 3}
+ << NavigationCommand {NavigationAction::Back, 0, {}, 0, {0, 0}, 0};
+ QTest::newRow("click links and go back, twice") << actions;
+
+ actions.clear();
+ actions // first link is "More..." going to page 0, location 8, 740
+ << NavigationCommand {NavigationAction::ClickLink, 0, {465, 65}, 0, {0, 740}, 0}
+ // link "newPage()" going to page 1, location 8, 290
+ << NavigationCommand {NavigationAction::ClickLink, 0, {480, 40}, 0, {0, totalPageSpacing + 290}, 1} // fails, goes back to page 0
+ << NavigationCommand {NavigationAction::Back, 0, {}, 0, {8, 740}, 0}
+ << NavigationCommand {NavigationAction::Back, 0, {}, 0, {0, 0}, 0};
+ QTest::newRow("click two links in series and then go back") << actions;
+}
+
+void tst_MultiPageView::navigation()
+{
+ QFETCH(QList<NavigationCommand>, actions);
+
+ QQuickView window;
+ window.setColor(Qt::gray);
+ window.setSource(testFileUrl("multiPageViewWithFeedback.qml"));
+ QTRY_COMPARE(window.status(), QQuickView::Ready);
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+ QObject *doc = pdfView->property("document").value<QObject *>();
+ QVERIFY(doc);
+ doc->setProperty("source", testFileUrl("qpdfwriter.pdf"));
+ QQuickItem *table = static_cast<QQuickItem *>(findFirstChild(pdfView, "QQuickTableView"));
+ QVERIFY(table);
+ // Expect that contentY == destination y after a jump, for ease of comparison.
+ // 0.01 is close enough to 0 that we can compare int positions accurately,
+ // but nonzero so that QRectF::isValid() is true in tableView.positionViewAtCell()
+ table->setProperty("jumpLocationMargin", QPointF(0.01, 0.01));
+
+ window.show();
+ window.requestActivate();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QTRY_COMPARE(table->property("contentHeight").toInt(), 3322);
+ QCOMPARE(table->property("contentY").toInt(), 0);
+
+ for (const NavigationCommand &nav : actions) {
+ switch (nav.action) {
+ case NavigationAction::Back:
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "back"));
+ QCOMPARE(pdfView->property("forwardEnabled").toBool(), true);
+ break;
+ case NavigationAction::Forward:
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "forward"));
+ QCOMPARE(pdfView->property("backEnabled").toBool(), true);
+ break;
+ case NavigationAction::GotoPage:
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "goToPage",
+ Q_ARG(QVariant, QVariant(nav.index))));
+ QCOMPARE(pdfView->property("backEnabled").toBool(), true);
+ break;
+ case NavigationAction::GotoLocation:
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "goToLocation",
+ Q_ARG(QVariant, QVariant(nav.index)),
+ Q_ARG(QVariant, QVariant(nav.location)),
+ Q_ARG(QVariant, QVariant(nav.zoom)) ));
+ break;
+ case NavigationAction::ClickLink:
+ // Link delegates don't exist until page rendering is done
+ QTRY_VERIFY(pdfView->property("currentPageRenderingStatus").toInt() == 1); // QQuickImage::Status::Ready
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, nav.location.toPoint());
+ // Wait for the destination page to be rendered
+ QTRY_VERIFY(pdfView->property("currentPageRenderingStatus").toInt() == 1); // QQuickImage::Status::Ready
+ break;
+ }
+ qCDebug(lcTests) << "action" << nav.action << "index" << nav.index
+ << "contentX,Y" << table->property("contentX").toInt() << table->property("contentY").toInt()
+ << "expected" << nav.expectedContentPos;
+ QTRY_COMPARE(table->property("contentY").toInt(), nav.expectedContentPos.y());
+ // some minor side-to-side scrolling happens, in practice
+ QVERIFY(qAbs(table->property("contentX").toInt() - nav.expectedContentPos.x()) < 10);
+ QCOMPARE(pdfView->property("currentPage").toInt(), nav.expectedCurrentPage);
+ }
+
+ QCOMPARE(pdfView->property("backEnabled").toBool(), false);
+}
+
+void tst_MultiPageView::password()
+{
+ QQuickView window;
+ QVERIFY(showView(window, testFileUrl("multiPageView.qml")));
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+ QQuickPdfDocument *doc = pdfView->property("document").value<QQuickPdfDocument*>();
+ QVERIFY(doc);
+ QPdfDocument *cppDoc = static_cast<QPdfDocument *>(qmlExtendedObject(doc));
+ QVERIFY(cppDoc);
+ QSignalSpy passwordRequiredSpy(doc, SIGNAL(passwordRequired()));
+ // actually QPdfDocument::passwordRequired, but QML_EXTENDED gives us this signal virtually in QQuickPdfDocument
+ QVERIFY(passwordRequiredSpy.isValid());
+ QSignalSpy passwordChangedSpy(doc, SIGNAL(passwordChanged()));
+ // actually QPdfDocument::passwordChanged, but QML_EXTENDED gives us this signal virtually in QQuickPdfDocument
+ QVERIFY(passwordChangedSpy.isValid());
+ QSignalSpy statusChangedSpy(doc, SIGNAL(statusChanged(QPdfDocument::Status)));
+ // actually QPdfDocument::statusChanged, but QML_EXTENDED gives us this signal virtually in QQuickPdfDocument
+ QVERIFY(statusChangedSpy.isValid());
+ QSignalSpy pageCountChangedSpy(doc, SIGNAL(pageCountChanged(int)));
+ // QPdfDocument::pageCountChanged(int), but QML_EXTENDED gives us this signal virtually in QQuickPdfDocument
+ QVERIFY(pageCountChangedSpy.isValid());
+ QSignalSpy extPageCountChangedSpy(cppDoc, &QPdfDocument::pageCountChanged);
+ // actual QPdfDocument::pageCountChanged(int), for comparison with the illusory QQuickPdfDocument::pageCountChanged
+ QVERIFY(extPageCountChangedSpy.isValid());
+
+ QVERIFY(pdfView->setProperty("source", testFileUrl(u"pdf-sample.protected.pdf"_s)));
+
+ QTRY_COMPARE(passwordRequiredSpy.size(), 1);
+ qCDebug(lcTests) << "error while awaiting password" << doc->error()
+ << "passwordRequired count" << passwordRequiredSpy.size()
+ << "statusChanged count" << statusChangedSpy.size();
+ QCOMPARE(doc->property("status").toInt(), int(QPdfDocument::Status::Error));
+ QCOMPARE(pageCountChangedSpy.size(), 0);
+ QCOMPARE(extPageCountChangedSpy.size(), 0);
+ QCOMPARE(statusChangedSpy.size(), 2); // Loading and then Error
+ statusChangedSpy.clear();
+ QVERIFY(doc->setProperty("password", u"Qt"_s));
+ QCOMPARE(passwordChangedSpy.size(), 1);
+ QTRY_COMPARE(doc->property("status").toInt(), int(QPdfDocument::Status::Ready));
+ qCDebug(lcTests) << "after setPassword" << doc->error()
+ << "passwordChanged count" << passwordChangedSpy.size()
+ << "statusChanged count" << statusChangedSpy.size()
+ << "pageCountChanged count" << pageCountChangedSpy.size();
+ QCOMPARE(statusChangedSpy.size(), 2); // Loading and then Ready
+ QCOMPARE(pageCountChangedSpy.size(), 1);
+ QCOMPARE(extPageCountChangedSpy.size(), pageCountChangedSpy.size());
+}
+
+void tst_MultiPageView::selectionAndClipboard()
+{
+ QQuickView window;
+ QVERIFY(showView(window, testFileUrl("multiPageView.qml")));
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+ QQuickPdfDocument *doc = pdfView->property("document").value<QQuickPdfDocument*>();
+ QVERIFY(doc);
+ QVERIFY(doc->setProperty("password", u"Qt"_s));
+ QVERIFY(pdfView->setProperty("source", testFileUrl((u"pdf-sample.protected.pdf"_s))));
+ QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
+
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "selectAll"));
+ QString sel = pdfView->property("selectedText").toString();
+ QCOMPARE(sel.size(), 1073);
+
+#if QT_CONFIG(clipboard)
+ QClipboard *clip = qApp->clipboard();
+ if (clip->supportsSelection())
+ QCOMPARE(clip->text(QClipboard::Selection), sel);
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "copySelectionToClipboard"));
+ QCOMPARE(clip->text(QClipboard::Clipboard), sel);
+#endif // clipboard
+}
+
+void tst_MultiPageView::search()
+{
+ QQuickView window;
+ QVERIFY(showView(window, testFileUrl("multiPageView.qml")));
+ window.setResizeMode(QQuickView::SizeRootObjectToView);
+ window.resize(200, 200);
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+ QTRY_COMPARE(pdfView->width(), 200);
+ QQuickPdfDocument *doc = pdfView->property("document").value<QQuickPdfDocument*>();
+ QVERIFY(doc);
+ QVERIFY(doc->setProperty("password", u"Qt"_s));
+ QVERIFY(pdfView->setProperty("source", testFileUrl(u"pdf-sample.protected.pdf"_s)));
+ QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
+ QPdfSearchModel *searchModel = pdfView->property("searchModel").value<QPdfSearchModel*>();
+ QVERIFY(searchModel);
+ QQuickItem *table = static_cast<QQuickItem *>(findFirstChild(pdfView, "QQuickTableView"));
+ QVERIFY(table);
+ QQuickItem *firstPage = tableViewItemAtCell(table, 0, 0);
+ QVERIFY(firstPage);
+ QObject *multiline = findFirstChild(firstPage, "QQuickPathMultiline");
+ QVERIFY(multiline);
+
+ pdfView->setProperty("searchString", u"PDF"_s);
+ QTRY_COMPARE(searchModel->rowCount(QModelIndex()), 7); // occurrences of the word "PDF" in this file
+ const int count = searchModel->rowCount(QModelIndex());
+ QList<QList<QPointF>> resultOutlines = multiline->property("paths").value<QList<QList<QPointF>>>();
+ QCOMPARE(resultOutlines.size(), 7);
+ QPoint contentPos = tableViewContentPos(table);
+ int movements = 0;
+ for (int i = 0; i < count; ++i) {
+ // only one page, so IndexOnPage data is the same as overall index
+ QCOMPARE(i, searchModel->data(searchModel->index(i), int(QPdfSearchModel::Role::IndexOnPage)).toInt());
+ QCOMPARE(resultOutlines.at(i).size(), 5); // 5-point polygon is a rectangle (including drawing back to the start, to close it)
+ QCOMPARE(resultOutlines.at(i).first(), searchModel->data(searchModel->index(i), int(QPdfSearchModel::Role::Location)).toPointF());
+
+ QVERIFY(QMetaObject::invokeMethod(pdfView, "searchForward"));
+ QTest::qWait(500); // animation time; but it doesn't always need to move
+ // TODO maybe: if movement starts, wait for it to stop somehow?
+ qCDebug(lcTests) << i << resultOutlines.at(i) << "scrolled to" << tableViewContentPos(table);
+ if (tableViewContentPos(table) != contentPos)
+ ++movements;
+ contentPos = tableViewContentPos(table);
+ }
+ qCDebug(lcTests) << "total movements" << movements;
+ QVERIFY(movements > 4);
+}
+
+void tst_MultiPageView::pinchDragPinch()
+{
+ qputenv("QML_NO_TOUCH_COMPRESSION", "1");
+ QQuickView window;
+ QVERIFY(showView(window, testFileUrl("multiPageView.qml")));
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+ pdfView->setProperty("source", testFileUrl("bookmarksAndLinks.pdf"));
+ QTRY_COMPARE(pdfView->property("currentPageRenderingStatus").toInt(), QQuickPdfPageImage::Ready);
+ QQuickItem *table = static_cast<QQuickItem *>(findFirstChild(pdfView, "QQuickTableView"));
+ QVERIFY(table);
+ QQuickItem *firstPage = tableViewItemAtCell(table, 0, 0);
+ QVERIFY(firstPage);
+ QQuickItem *paper = firstPage->childAt(10, 10);
+ QVERIFY(paper);
+ QQuickPdfPageImage *image = firstPage->findChild<QQuickPdfPageImage *>();
+ QVERIFY(image);
+
+ auto pinch = [&window, paper, this]() {
+ const int threshold = QGuiApplication::styleHints()->startDragDistance();
+ const int movement = 100;
+ QCOMPARE_GT(movement, threshold);
+ const qreal initialScale = paper->scale();
+ QPoint p0(100, 200);
+ QPoint p1(200, 200);
+ QTest::QTouchEventSequence seq = QTest::touchEvent(&window, touchscreen.get());
+ seq.press(0, p0, &window).commit();
+ seq.stationary(0).press(1, p1, &window).commit();
+ p1.setX(p1.x() + movement);
+ QSignalSpy frameSwappedSpy(&window, &QQuickWindow::frameSwapped);
+ seq.stationary(0).move(1, p1, &window).commit();
+ // after a frame is rendered, the PinchHandler ought to be active
+ // (but verifying it would require private API)
+ QTRY_VERIFY(frameSwappedSpy.size() > 0);
+ QTRY_COMPARE(paper->scale(), initialScale);
+
+ for (int i = 1; i <= 2; ++i) {
+ p1.setX(p1.x() + movement);
+ seq.stationary(0).move(1, p1, &window).commit();
+ QTRY_COMPARE(paper->scale(), initialScale + i * 0.5);
+ }
+ seq.release(0, p0, &window).release(1, p1, &window).commit();
+ };
+
+ auto drag = [&window, table, this]() {
+ const int movement = 100;
+ QPoint p0(200, 200);
+ QTest::QTouchEventSequence seq = QTest::touchEvent(&window, touchscreen.get());
+ seq.press(0, p0, &window).commit();
+ p0.setY(p0.y() + movement);
+ seq.move(0, p0, &window).commit();
+ p0.setY(p0.y() + movement);
+ seq.move(0, p0, &window).commit();
+ seq.release(0, p0, &window).commit();
+ QTRY_COMPARE(table->property("moving"), false);
+ };
+
+ pinch();
+ qCDebug(lcTests) << "new scale" << pdfView->property("renderScale").toReal();
+ QTRY_COMPARE(pdfView->property("renderScale").toReal(), 2);
+
+ drag();
+ QCOMPARE(pdfView->property("renderScale").toReal(), 2);
+
+ pinch();
+ qCDebug(lcTests) << "new scale" << pdfView->property("renderScale").toReal();
+ QTRY_COMPARE(pdfView->property("renderScale").toReal(), 4);
+
+ // wait for rendering to be done before we exit: if we delete the document
+ // prematurely, QPdfIOHandler might access a dangling pointer
+ QTRY_COMPARE(image->status(), QQuickPdfPageImage::Ready);
+}
+
+void tst_MultiPageView::jumpOnDocumentReady() // QTBUG-119416
+{
+ QQuickView window;
+ QVERIFY(showView(window, testFileUrl("jumpOnDocumentReady.qml")));
+ QQuickItem *pdfView = window.rootObject();
+ QVERIFY(pdfView);
+
+ // QML calls view.goToPage(2): verify that it eventually happens
+ QTRY_COMPARE(pdfView->property("currentPage").toInt(), 2);
+}
+
+QTEST_MAIN(tst_MultiPageView)
+#include "tst_multipageview.moc"
diff --git a/tests/auto/pdfquick/pdfpageimage/CMakeLists.txt b/tests/auto/pdfquick/pdfpageimage/CMakeLists.txt
new file mode 100644
index 000000000..da67d8721
--- /dev/null
+++ b/tests/auto/pdfquick/pdfpageimage/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Collect test data
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_pdfpageimage
+ SOURCES
+ tst_pdfpageimage.cpp
+ ../shared/util.cpp ../shared/util.h
+ LIBRARIES
+ Qt::Gui
+ Qt::Quick
+ Qt::PdfQuickPrivate
+ TESTDATA ${test_data}
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_pdfpageimage CONDITION ANDROID OR IOS
+ DEFINES
+ QT_QMLTEST_DATADIR=":/data"
+)
+
+qt_internal_extend_target(tst_pdfpageimage CONDITION NOT ANDROID AND NOT IOS
+ DEFINES
+ QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
+)
+
diff --git a/tests/auto/pdfquick/pdfpageimage/data/bookmarksAndLinks.pdf b/tests/auto/pdfquick/pdfpageimage/data/bookmarksAndLinks.pdf
new file mode 100644
index 000000000..aa0b99039
--- /dev/null
+++ b/tests/auto/pdfquick/pdfpageimage/data/bookmarksAndLinks.pdf
@@ -0,0 +1,317 @@
+%PDF-1.7
+
+1 0 obj
+<<
+ /Type /Catalog
+ /PageMode /FullScreen
+ /Outlines 6 0 R
+ /Pages 2 0 R
+ /Names 50 0 R
+ /PageLabels 23 0 R
+ /ViewerPreferences<</NonFullScreenPageMode (UseThumbs)>>
+>>
+endobj
+
+50 0 obj
+<<
+ /Dests <</Names [ (ToTest2) [4 0 R /XYZ 300 300 1] (ToTest3) [5 0 R /XYZ 290 10 0.5] (ToTest1) [3 0 R /XYZ 600 800 1] ]>>
+>>
+endobj
+
+23 0 obj
+<<
+ /Nums [0 <</S /D /P(test )>> 3 <</S /A >> 4<</S /R/St >> 5<</S /r/St >> ]
+ /Limits [0 5]
+>>
+endobj
+
+2 0 obj
+<<
+ /Type /Pages
+ /Kids [3 0 R 4 0 R 5 0 R]
+ /Count 3
+>>
+endobj
+
+3 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 10 600 800]
+ /Annots [24 0 R 25 0 R]
+ /Contents 16 0 R
+ /Resources <<
+ /Font <</F1 18 0 R>>
+ >>
+>>
+endobj
+
+24 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest2)
+ /A << /Type /Action
+ /S /GoTo
+ /D [5 0 R /FitR ¨C4 399 199 533]
+ >>
+ /Rect [10 690 150 720]
+
+>>
+endobj
+
+25 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest3)
+ /Rect [10 630 150 650]
+>>
+endobj
+
+
+16 0 obj
+<< /Length 0 >>
+ stream
+ BT
+ /F1 72 Tf
+ 200 200 TD
+ 0 0 1 RG
+ 5 Tr
+ (Test_1) Tj
+ 0 800 m
+ 600 0 l S
+ /F1 30 Tf
+ 0 1 0 RG
+ 1 Tr
+ -190 490 TD
+ (GO Test_2) Tj
+ 0 -50 TD
+ 5 w
+ 2 Tr
+ 1 0 0 RG
+ (GO Test_3) Tj
+ ET
+ endstream
+endobj
+
+
+endobj
+
+18 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F1
+ /BaseFont /Helvetica
+>>
+endobj
+
+4 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [10 0 500 700]
+ /Annots [60 0 R]
+ /Contents 19 0 R
+ /Resources <<
+ /Font <</F2 20 0 R>>
+ >>
+>>
+endobj
+
+19 0 obj
+<< /Length 0 >>
+stream
+BT
+ 1 -0.7 0 1 30 100 cm
+ /F2 50 Tf
+ 10 50 TD
+ (TEST_2) Tj
+
+ 1 0.7 0 1 -30 -100 cm
+ /F2 25 Tf
+ 1 0 1 RG
+ 7 w
+ 100 60 TD
+
+ (GO Test_1) Tj
+ 100 100 140 40 re S f
+ET
+endstream
+endobj
+
+20 0 obj
+<<
+ /Type /Font
+ /Subtype /TrueType
+ /Name /F2
+ /BaseFont /NewYork , Bold
+ /FirstChar 0
+ /LastChar 255
+ /Widths 23 0 R
+ /FontDescriptor 7 0 R
+ /Encoding /MacRomanEncoding
+>>
+endobj
+
+60 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest1)
+ /Rect [110 110 230 150]
+>>
+endobj
+
+5 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [-10 -10 400 600]
+ /Annots [61 0 R]
+ /Contents 21 0 R
+ /Resources << /Font <</F3 22 0 R>> >>
+>>
+endobj
+
+21 0 obj
+<< /Length 0 >>
+stream
+BT
+ /F3 30 Tf
+ 290 10 TD
+ (TEST_3) Tj
+ -50 90 TD
+ (GO Test_2)Tj
+ET
+endstream
+endobj
+
+22 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F3
+ /BaseFont /Courier-Bold
+>>
+endobj
+
+61 0 obj
+<<
+ /Subtype /Link
+ /Border [0 0 0]
+ /Dest (ToTest2)
+ /Rect [240 90 400 130]
+>>
+
+6 0 obj
+<<
+ /Type /Outlines
+ /First 7 0 R
+ /Last 11 0 R
+ /Count 4 0 R
+>>
+endobj
+
+7 0 obj
+<<
+ /Title (First)
+ /Parent 6 0 R
+ /Next 8 0 R
+ /C [1 0 0]
+ /Dest [ 3 0 R /XYZ 600 800 0.5 ]
+>>
+endobj
+
+8 0 obj
+<<
+ /Title (Second)
+ /Parent 6 0 R
+ /Prev 7 0 R
+ /Next 9 0 R
+ /C [0 1 0]
+ % /Dest [ 4 0 R /XYZ 500 700 null ]
+/Dest (ToTest2)
+>>
+endobj
+
+9 0 obj
+<<
+ /Title (Third)
+ /Parent 6 0 R
+ /Prev 8 0 R
+ /Next 10 0 R
+ /C [0 0 1]
+ /Dest [ 5 0 R /XYZ 400 600 0.8 ]
+>>
+endobj
+
+10 0 obj
+<<
+ /Title (Fourth)
+ /Parent 6 0 R
+ /Prev 9 0 R
+ /Next 11 0 R
+>>
+endobj
+
+11 0 obj
+<<
+ /Title (Fivth)
+ /Parent 6 0 R
+ /Prev 10 0 R
+ /First 12 0 R
+ /Last 15 0 R
+ /Count 4
+>>
+endobj
+
+12 0 obj
+<<
+ /Title (Fivth_1)
+ /Parent 11 0 R
+ /Next 13 0 R
+>>
+endobj
+
+13 0 obj
+<<
+ /Title (Fivth_2)
+ /Parent 11 0 R
+ /Prev 12 0 R
+ /Next 14 0 R
+>>
+endobj
+
+14 0 obj
+<<
+ /Title (Fivth_3)
+ /Parent 11 0 R
+ /Prev 13 0 R
+ /Next 15 0 R
+>>
+endobj
+
+15 0 obj
+<<
+ /Title (Fivth_4)
+ /Parent 11 0 R
+ /Prev 14 0 R
+>>
+endobj
+
+
+
+
+xref
+0000000000 65536 f
+
+trailer
+<<
+ /Size 0
+ /Root 1 0 R
+>>
+startxref
+0
+%%EOF
diff --git a/tests/auto/pdfquick/pdfpageimage/data/pdfPageImage.qml b/tests/auto/pdfquick/pdfpageimage/data/pdfPageImage.qml
new file mode 100644
index 000000000..a268bf14b
--- /dev/null
+++ b/tests/auto/pdfquick/pdfpageimage/data/pdfPageImage.qml
@@ -0,0 +1,16 @@
+import QtQuick
+import QtQuick.Pdf
+
+Item {
+ width: 320
+ height: 320
+
+ PdfDocument {
+ id: doc
+ source: "bookmarksAndLinks.pdf"
+ }
+
+ PdfPageImage {
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp b/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
new file mode 100644
index 000000000..d2c9c8709
--- /dev/null
+++ b/tests/auto/pdfquick/pdfpageimage/tst_pdfpageimage.cpp
@@ -0,0 +1,131 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QRegularExpression>
+#include <QSignalSpy>
+#include <QTest>
+#include <QtQuick/QQuickView>
+#include <QtPdfQuick/private/qquickpdfdocument_p.h>
+#include <QtPdfQuick/private/qquickpdfpageimage_p.h>
+#include "../shared/util.h"
+
+using namespace Qt::StringLiterals;
+
+Q_LOGGING_CATEGORY(lcTests, "qt.pdf.tests")
+
+// #define DEBUG_WRITE_OUTPUT
+
+class tst_PdfPageImage : public QQuickDataTest
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void settableProperties_data();
+ void settableProperties();
+
+public:
+ enum Property {
+ Source = 0x01,
+ Document = 0x02,
+ SourceSize = 0x04,
+ SourceClipRect = 0x08,
+ MipMap = 0x10,
+ AutoTransform = 0x20,
+ Asynchronous = 0x40,
+ NoCache = 0x80,
+ Mirror = 0x100,
+ MirrorVertically = 0x200,
+ ColorSpace = 0x400,
+ };
+ Q_DECLARE_FLAGS(Properties, Property)
+ Q_FLAG(Properties)
+
+private:
+#ifdef DEBUG_WRITE_OUTPUT
+ QTemporaryDir m_tmpDir;
+#endif
+};
+
+void tst_PdfPageImage::settableProperties_data()
+{
+ QTest::addColumn<tst_PdfPageImage::Properties>("toSet");
+ QTest::addColumn<QSize>("expectedSize");
+ QTest::addColumn<QRegularExpression>("expectedWarning");
+
+ const QRegularExpression NoWarning;
+ const qreal dpr = qGuiApp->devicePixelRatio();
+
+ QTest::newRow("source") << Properties(Source) << (QSizeF(600, 790) * dpr).toSize()
+ << QRegularExpression("document property not set: falling back to inefficient loading"); // QTBUG-104767
+ QTest::newRow("document") << Properties(Document) << QSize(600, 790) << NoWarning;
+ QTest::newRow("source and document") << Properties(Source | Document) << QSize(600, 790)
+ << QRegularExpression("document and source properties in conflict");
+ QTest::newRow("document and sourceSize") << Properties(Document | SourceSize) << QSize(100, 100) << NoWarning;
+ QTest::newRow("document and sourceClipRect") << Properties(Document | SourceClipRect) << QSize(100, 100) << NoWarning;
+ QTest::newRow("document and autoTransform") << Properties(Document | AutoTransform) << QSize(600, 790) << NoWarning;
+ QTest::newRow("document and async") << Properties(Document | Asynchronous) << QSize(600, 790) << NoWarning;
+ QTest::newRow("document and nocache") << Properties(Document | NoCache) << QSize(600, 790) << NoWarning;
+ QTest::newRow("document and mirror") << Properties(Document | Mirror) << QSize(600, 790) << NoWarning;
+ QTest::newRow("document and mirrorVertically") << Properties(Document | MirrorVertically) << QSize(600, 790) << NoWarning;
+ QTest::newRow("document and colorSpace") << Properties(Document | ColorSpace) << QSize(600, 790) << NoWarning;
+}
+
+void tst_PdfPageImage::settableProperties()
+{
+ QFETCH(tst_PdfPageImage::Properties, toSet);
+ QFETCH(QSize, expectedSize);
+ QFETCH(QRegularExpression, expectedWarning);
+
+ QQuickView window;
+ if (!expectedWarning.pattern().isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, expectedWarning);
+ QVERIFY(showView(window, testFileUrl("pdfPageImage.qml")));
+ QQuickPdfPageImage *pdfImage = window.rootObject()->findChild<QQuickPdfPageImage *>();
+ QVERIFY(pdfImage);
+ QQuickPdfDocument *doc = window.rootObject()->findChild<QQuickPdfDocument *>();
+ QVERIFY(doc);
+ if (toSet.testFlag(Document))
+ pdfImage->setDocument(doc);
+ if (toSet.testFlag(Source))
+ pdfImage->setSource(doc->source());
+ if (toSet.testFlag(SourceSize))
+ pdfImage->setSourceSize({100, 100});
+ if (toSet.testFlag(SourceClipRect))
+ pdfImage->setSourceClipRect({100, 100, 100, 100});
+ if (toSet.testFlag(MipMap))
+ pdfImage->setMipmap(true);
+ if (toSet.testFlag(AutoTransform))
+ pdfImage->setAutoTransform(true);
+ if (toSet.testFlag(Asynchronous)) {
+ QCOMPARE(pdfImage->asynchronous(), false);
+ // test the opposite of the default
+ pdfImage->setAsynchronous(true);
+ }
+ if (toSet.testFlag(NoCache)) {
+ QCOMPARE(pdfImage->cache(), true);
+ // test the opposite of the default
+ pdfImage->setCache(false);
+ }
+ if (toSet.testFlag(Mirror)) {
+ QCOMPARE(pdfImage->mirror(), false);
+ pdfImage->setMirror(true);
+ }
+ if (toSet.testFlag(MirrorVertically)) {
+ QCOMPARE(pdfImage->mirrorVertically(), false);
+ pdfImage->setMirrorVertically(true);
+ }
+ if (toSet.testFlag(ColorSpace))
+ pdfImage->setColorSpace(QColorSpace::ProPhotoRgb);
+ QTRY_COMPARE(pdfImage->status(), QQuickPdfPageImage::Ready);
+ const QImage img = pdfImage->image();
+ QCOMPARE(img.size(), expectedSize);
+#ifdef DEBUG_WRITE_OUTPUT
+ m_tmpDir.setAutoRemove(false);
+ const auto path = m_tmpDir.filePath(QString::fromLocal8Bit(QTest::currentDataTag()) + ".png");
+ qCDebug(lcTests) << "saving to" << path;
+ img.save(path);
+#endif
+}
+
+QTEST_MAIN(tst_PdfPageImage)
+#include "tst_pdfpageimage.moc"
diff --git a/tests/auto/pdfquick/shared/util.cpp b/tests/auto/pdfquick/shared/util.cpp
new file mode 100644
index 000000000..c540ebfa6
--- /dev/null
+++ b/tests/auto/pdfquick/shared/util.cpp
@@ -0,0 +1,110 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "util.h"
+#include <QtQuick/QQuickItem>
+
+QQuickDataTest::QQuickDataTest() :
+ m_initialized(false),
+#ifdef QT_TESTCASE_BUILDDIR
+ m_dataDirectory(QTest::qFindTestData("data", QT_QMLTEST_DATADIR, 0, QT_TESTCASE_BUILDDIR)),
+#else
+ m_dataDirectory(QTest::qFindTestData("data", QT_QMLTEST_DATADIR, 0)),
+#endif
+
+ m_dataDirectoryUrl(m_dataDirectory.startsWith(QLatin1Char(':'))
+ ? QUrl(QLatin1String("qrc") + m_dataDirectory)
+ : QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/')))
+{
+}
+
+QQuickDataTest::~QQuickDataTest()
+{
+}
+
+void QQuickDataTest::initTestCase()
+{
+ QVERIFY2(!m_dataDirectory.isEmpty(), "'data' directory not found");
+ m_directory = QFileInfo(m_dataDirectory).absolutePath();
+ if (m_dataDirectoryUrl.scheme() != QLatin1String("qrc"))
+ QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory));
+
+ if (QGuiApplication::platformName() == QLatin1String("offscreen")
+ || QGuiApplication::platformName() == QLatin1String("minimal"))
+ {
+ QSKIP("Skipping visual tests due to running with offscreen/minimal");
+ }
+
+ m_initialized = true;
+}
+
+void QQuickDataTest::cleanupTestCase()
+{
+ m_initialized = false;
+}
+
+QString QQuickDataTest::testFile(const QString &fileName) const
+{
+ if (m_directory.isEmpty())
+ qFatal("QQuickDataTest::initTestCase() not called.");
+ QString result = m_dataDirectory;
+ result += QLatin1Char('/');
+ result += fileName;
+ return result;
+}
+
+QObject *QQuickDataTest::findFirstChild(QObject *parent, const char *className)
+{
+ const auto children = parent->findChildren<QObject*>();
+ for (QObject *child : children) {
+ if (child->inherits(className))
+ return child;
+ }
+ return nullptr;
+}
+
+bool QQuickDataTest::showView(QQuickView &view, const QUrl &url)
+{
+ view.setSource(url);
+ while (view.status() == QQuickView::Loading)
+ QTest::qWait(10);
+ if (view.status() != QQuickView::Ready)
+ return false;
+ const QRect screenGeometry = view.screen()->availableGeometry();
+ const QSize size = view.size();
+ const QPoint offset = QPoint(size.width() / 2, size.height() / 2);
+ view.setFramePosition(screenGeometry.center() - offset);
+#if QT_CONFIG(cursor) // Get the cursor out of the way.
+ QCursor::setPos(view.geometry().topRight() + QPoint(100, 100));
+#endif
+ view.show();
+ if (!QTest::qWaitForWindowExposed(&view))
+ return false;
+ if (!view.rootObject())
+ return false;
+ return true;
+}
+
+QQuickItem *QQuickDataTest::repeaterItemAt(QQuickItem *repeater, int i)
+{
+ static const QMetaMethod itemAtMethod = repeater->metaObject()->method(
+ repeater->metaObject()->indexOfMethod("itemAt(int)"));
+ QQuickItem *ret = nullptr;
+ itemAtMethod.invoke(repeater, Qt::DirectConnection, Q_RETURN_ARG(QQuickItem*, ret), Q_ARG(int, i));
+ return ret;
+}
+
+QQuickItem *QQuickDataTest::tableViewItemAtCell(QQuickItem *table, int col, int row)
+{
+ static const QMetaMethod itemAtCellMethod = table->metaObject()->method(
+ table->metaObject()->indexOfMethod("itemAtCell(int,int)"));
+ QQuickItem *ret = nullptr;
+ itemAtCellMethod.invoke(table, Qt::DirectConnection,
+ Q_RETURN_ARG(QQuickItem*, ret), Q_ARG(int, col), Q_ARG(int, row));
+ return ret;
+}
+
+QPoint QQuickDataTest::tableViewContentPos(QQuickItem *table)
+{
+ return QPoint(table->property("contentX").toInt(), table->property("contentY").toInt());
+}
diff --git a/tests/auto/pdfquick/shared/util.h b/tests/auto/pdfquick/shared/util.h
new file mode 100644
index 000000000..9ceb711af
--- /dev/null
+++ b/tests/auto/pdfquick/shared/util.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QUICK_VISUAL_TEST_UTIL_H
+#define QUICK_VISUAL_TEST_UTIL_H
+
+#include <QtCore/QUrl>
+#include <QtQuick/QQuickView>
+#include <QtTest/QTest>
+
+/*! \internal
+ Base class for tests with data that are located in a "data" subfolder.
+*/
+class QQuickDataTest : public QObject
+{
+ Q_OBJECT
+public:
+ QQuickDataTest();
+ ~QQuickDataTest();
+
+ bool initialized() const { return m_initialized; }
+
+ bool showView(QQuickView &view, const QUrl &url);
+
+ QString testFile(const QString &fileName) const;
+ inline QString testFile(const char *fileName) const
+ { return testFile(QLatin1String(fileName)); }
+ inline QUrl testFileUrl(const QString &fileName) const
+ {
+ const QString fn = testFile(fileName);
+ return fn.startsWith(QLatin1Char(':'))
+ ? QUrl(QLatin1String("qrc") + fn)
+ : QUrl::fromLocalFile(fn);
+ }
+ inline QUrl testFileUrl(const char *fileName) const
+ { return testFileUrl(QLatin1String(fileName)); }
+
+ inline QString dataDirectory() const { return m_dataDirectory; }
+ inline QUrl dataDirectoryUrl() const { return m_dataDirectoryUrl; }
+ inline QString directory() const { return m_directory; }
+
+ QObject *findFirstChild(QObject *parent, const char *className);
+ QQuickItem *repeaterItemAt(QQuickItem *repeater, int i);
+ QQuickItem *tableViewItemAtCell(QQuickItem *table, int col, int row);
+ QPoint tableViewContentPos(QQuickItem *table);
+
+public slots:
+ virtual void initTestCase();
+ virtual void cleanupTestCase();
+
+private:
+ bool m_initialized;
+ QString m_dataDirectory;
+ QUrl m_dataDirectoryUrl;
+ QString m_directory;
+};
+
+#endif
diff --git a/tests/auto/quick/CMakeLists.txt b/tests/auto/quick/CMakeLists.txt
index d44d67d38..d2cf7c3b3 100644
--- a/tests/auto/quick/CMakeLists.txt
+++ b/tests/auto/quick/CMakeLists.txt
@@ -1,8 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(dialogs)
add_subdirectory(publicapi)
add_subdirectory(qquickwebenginedefaultsurfaceformat)
add_subdirectory(qtbug-70248)
-add_subdirectory(uidelegates)
+# Re-enable if QTBUG-101744 and QTBUG-103354 have been fixed.
+if(NOT MACOS)
+ add_subdirectory(uidelegates)
+endif()
add_subdirectory(inspectorserver)
add_subdirectory(qmltests)
add_subdirectory(qquickwebengineview)
diff --git a/tests/auto/quick/dialogs/CMakeLists.txt b/tests/auto/quick/dialogs/CMakeLists.txt
index b7f088f0d..4d8dc853b 100644
--- a/tests/auto/quick/dialogs/CMakeLists.txt
+++ b/tests/auto/quick/dialogs/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/quick/dialogs/WebView.qml b/tests/auto/quick/dialogs/WebView.qml
index 29b5d2ca0..45fafb42d 100644
--- a/tests/auto/quick/dialogs/WebView.qml
+++ b/tests/auto/quick/dialogs/WebView.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtWebEngine
diff --git a/tests/auto/quick/dialogs/testhandler.cpp b/tests/auto/quick/dialogs/testhandler.cpp
index 78a944cc6..f45852630 100644
--- a/tests/auto/quick/dialogs/testhandler.cpp
+++ b/tests/auto/quick/dialogs/testhandler.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "testhandler.h"
diff --git a/tests/auto/quick/dialogs/testhandler.h b/tests/auto/quick/dialogs/testhandler.h
index 93ecfcdcb..c72e81841 100644
--- a/tests/auto/quick/dialogs/testhandler.h
+++ b/tests/auto/quick/dialogs/testhandler.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTHANDLER_H
#define TESTHANDLER_H
diff --git a/tests/auto/quick/dialogs/tst_dialogs.cpp b/tests/auto/quick/dialogs/tst_dialogs.cpp
index 8543c47da..2b861efa6 100644
--- a/tests/auto/quick/dialogs/tst_dialogs.cpp
+++ b/tests/auto/quick/dialogs/tst_dialogs.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "testhandler.h"
#include <quickutil.h>
@@ -96,7 +71,7 @@ void tst_Dialogs::createDialog(const QLatin1String &dialog, bool &ok)
m_listener->runJavaScript(trigger.arg(dialog));
QTRY_VERIFY(m_listener->ready());
QTest::mouseClick(m_window, Qt::LeftButton);
- QTRY_COMPARE(dialogSpy.count(), 1);
+ QTRY_COMPARE(dialogSpy.size(), 1);
ok = true;
}
@@ -121,7 +96,7 @@ void tst_Dialogs::contextMenuRequested()
QTRY_COMPARE_WITH_TIMEOUT(m_listener->ready(), true, 20000);
QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
QTest::mouseClick(m_window, Qt::RightButton);
- QTRY_COMPARE(dialogSpy.count(), 1);
+ QTRY_COMPARE(dialogSpy.size(), 1);
auto dialog = qobject_cast<QWebEngineContextMenuRequest *>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
}
@@ -178,7 +153,7 @@ void tst_Dialogs::authenticationDialogRequested()
QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
m_listener->load(url);
- QTRY_COMPARE(dialogSpy.count(), 1);
+ QTRY_COMPARE(dialogSpy.size(), 1);
auto *dialog = qobject_cast<QQuickWebEngineAuthenticationDialogRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
dialog->dialogReject();
@@ -222,7 +197,7 @@ void tst_Dialogs::javaScriptDialogRequested()
QSignalSpy dialogSpy(m_listener, &TestHandler::requestChanged);
m_listener->runJavaScript(script);
- QTRY_COMPARE(dialogSpy.count(), 1);
+ QTRY_COMPARE(dialogSpy.size(), 1);
auto *dialog = qobject_cast<QQuickWebEngineJavaScriptDialogRequest*>(m_listener->request());
QVERIFY2(dialog, "Incorrect dialog requested");
dialog->dialogReject();
diff --git a/tests/auto/quick/inspectorserver/CMakeLists.txt b/tests/auto/quick/inspectorserver/CMakeLists.txt
index e2c3bb2ab..d890581b8 100644
--- a/tests/auto/quick/inspectorserver/CMakeLists.txt
+++ b/tests/auto/quick/inspectorserver/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_inspectorserver
SOURCES
tst_inspectorserver.cpp
diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
index 7b85c7348..a9638bee4 100644
--- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
+++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QNetworkAccessManager>
#include <QNetworkReply>
@@ -34,6 +9,7 @@
#include <QtTest/QtTest>
#include <QQuickWebEngineProfile>
#include <QtWebEngineQuick/private/qquickwebengineview_p.h>
+#include <QWebEnginePage>
#define INSPECTOR_SERVER_PORT "23654"
static const QUrl s_inspectorServerHttpBaseUrl("http://localhost:" INSPECTOR_SERVER_PORT);
@@ -47,6 +23,7 @@ private Q_SLOTS:
void init();
void cleanup();
+ void testDevToolsId();
void testPageList();
void testRemoteDebuggingMessage();
void openRemoteDebuggingSession();
@@ -61,6 +38,7 @@ private:
tst_InspectorServer::tst_InspectorServer()
{
+ qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--remote-allow-origins=*");
qputenv("QTWEBENGINE_REMOTE_DEBUGGING", INSPECTOR_SERVER_PORT);
QtWebEngineQuick::initialize();
QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
@@ -103,7 +81,7 @@ inline QQuickWebEngineView* tst_InspectorServer::webView() const
QJsonArray tst_InspectorServer::fetchPageList() const
{
QNetworkAccessManager qnam;
- QSignalSpy spy(&qnam, &QNetworkAccessManager::finished);;
+ QSignalSpy spy(&qnam, &QNetworkAccessManager::finished);
QNetworkRequest request(s_inspectorServerHttpBaseUrl.resolved(QUrl("json/list")));
QScopedPointer<QNetworkReply> reply(qnam.get(request));
spy.wait();
@@ -115,13 +93,28 @@ QJsonArray tst_InspectorServer::fetchPageList() const
return QJsonDocument::fromJson(reply->readAll()).array();
}
+void tst_InspectorServer::testDevToolsId()
+{
+ const QUrl testPageUrl = QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ + QLatin1String("/html/basic_page.html"));
+ QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebEngineLoadingInfo)));
+ webView()->setUrl(testPageUrl);
+ QTRY_VERIFY_WITH_TIMEOUT(loadSpy.size() && !webView()->isLoading(), 10000);
+
+ // Our page should be the only one in the list.
+ QJsonArray pageList = fetchPageList();
+ QCOMPARE(pageList.size(), 1);
+ QCOMPARE(testPageUrl.toString(), pageList.at(0).toObject().value("url").toString());
+ QCOMPARE(webView()->devToolsId(), pageList.at(0).toObject().value("id").toString());
+}
+
void tst_InspectorServer::testPageList()
{
const QUrl testPageUrl = QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()
+ QLatin1String("/html/basic_page.html"));
QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebEngineLoadingInfo)));
webView()->setUrl(testPageUrl);
- QTRY_VERIFY(loadSpy.size() && !webView()->isLoading());
+ QTRY_VERIFY_WITH_TIMEOUT(loadSpy.size() && !webView()->isLoading(), 10000);
// Our page has developerExtrasEnabled and should be the only one in the list.
QJsonArray pageList = fetchPageList();
@@ -135,7 +128,7 @@ void tst_InspectorServer::testRemoteDebuggingMessage()
+ QLatin1String("/html/basic_page.html"));
QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebEngineLoadingInfo)));
webView()->setUrl(testPageUrl);
- QTRY_VERIFY(loadSpy.size() && !webView()->isLoading());
+ QTRY_VERIFY_WITH_TIMEOUT(loadSpy.size() && !webView()->isLoading(), 10000);
QJsonArray pageList = fetchPageList();
QCOMPARE(pageList.size(), 1);
@@ -161,7 +154,7 @@ void tst_InspectorServer::testRemoteDebuggingMessage()
.arg(pageList.at(0).toObject().value("webSocketDebuggerUrl").toString())
.arg(jsExpression));
- QTRY_COMPARE(webSocketQueryWebView->title(), jsExpressionResult);
+ QTRY_COMPARE_WITH_TIMEOUT(webSocketQueryWebView->title(), jsExpressionResult, 10000);
}
void tst_InspectorServer::openRemoteDebuggingSession()
@@ -170,7 +163,7 @@ void tst_InspectorServer::openRemoteDebuggingSession()
+ QLatin1String("/html/basic_page.html"));
QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebEngineLoadingInfo)));
webView()->setUrl(testPageUrl);
- QTRY_VERIFY(loadSpy.size() && !webView()->isLoading());
+ QTRY_VERIFY_WITH_TIMEOUT(loadSpy.size() && !webView()->isLoading(), 10000);
QJsonArray pageList = fetchPageList();
QCOMPARE(pageList.size(), 1);
@@ -185,7 +178,7 @@ void tst_InspectorServer::openRemoteDebuggingSession()
// - The page list didn't return a valid inspector URL
// - Or the front-end couldn't be loaded through the inspector HTTP server
// - Or the web socket connection couldn't be established between the front-end and the page through the inspector server
- QTRY_VERIFY_WITH_TIMEOUT(inspectorWebView->title().startsWith("DevTools -"), 30000);
+ QTRY_VERIFY_WITH_TIMEOUT(inspectorWebView->title().startsWith("DevTools -"), 60000);
}
QTEST_MAIN(tst_InspectorServer)
diff --git a/tests/auto/quick/publicapi/CMakeLists.txt b/tests/auto/quick/publicapi/CMakeLists.txt
index 4fa18e0b3..e345a076a 100644
--- a/tests/auto/quick/publicapi/CMakeLists.txt
+++ b/tests/auto/quick/publicapi/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_publicapi
SOURCES
tst_publicapi.cpp
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index af22add1f..cfa75f0bf 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QMetaEnum>
#include <QMetaMethod>
@@ -35,6 +10,8 @@
#include <QtTest/QtTest>
#include <QtWebEngineQuick/QQuickWebEngineProfile>
#include <QtWebEngineCore/QWebEngineCertificateError>
+#include <QtWebEngineCore/QWebEngineDesktopMediaRequest>
+#include <QtWebEngineCore/QWebEngineFileSystemAccessRequest>
#include <QtWebEngineCore/QWebEngineFindTextResult>
#include <QtWebEngineCore/QWebEngineFullScreenRequest>
#include <QtWebEngineCore/QWebEngineHistory>
@@ -47,6 +24,7 @@
#include <QtWebEngineCore/QWebEngineDownloadRequest>
#include <QtWebEngineCore/QWebEngineScript>
#include <QtWebEngineCore/QWebEngineLoadingInfo>
+#include <QtWebEngineCore/QWebEngineWebAuthUxRequest>
#include <private/qquickwebengineview_p.h>
#include <private/qquickwebengineaction_p.h>
#include <private/qquickwebengineclientcertificateselection_p.h>
@@ -85,17 +63,24 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
<< &QQuickWebEngineTooltipRequest::staticMetaObject
<< &QWebEngineContextMenuRequest::staticMetaObject
<< &QWebEngineCertificateError::staticMetaObject
+ << &QWebEngineDesktopMediaRequest::staticMetaObject
+ << &QWebEngineFileSystemAccessRequest::staticMetaObject
<< &QWebEngineFindTextResult::staticMetaObject
<< &QWebEngineLoadingInfo::staticMetaObject
+ << &QAbstractListModel::staticMetaObject
<< &QWebEngineNavigationRequest::staticMetaObject
<< &QWebEngineNewWindowRequest::staticMetaObject
<< &QWebEngineNotification::staticMetaObject
<< &QWebEngineQuotaRequest::staticMetaObject
<< &QWebEngineRegisterProtocolHandlerRequest::staticMetaObject
<< &QQuickWebEngineTouchSelectionMenuRequest::staticMetaObject
+ << &QWebEngineWebAuthUxRequest::staticMetaObject
+ << &QWebEngineWebAuthPinRequest::staticMetaObject
;
-static QList<QMetaEnum> knownEnumNames = QList<QMetaEnum>();
+static QList<QMetaEnum> knownEnumNames = QList<QMetaEnum>()
+ << QWebEngineDownloadRequest::staticMetaObject.enumerator(QWebEngineDownloadRequest::staticMetaObject.indexOfEnumerator("SavePageFormat"))
+ ;
static const QStringList hardcodedTypes = QStringList()
<< "QJSValue"
@@ -106,7 +91,9 @@ static const QStringList hardcodedTypes = QStringList()
<< "const QQuickWebEngineContextMenuData*"
<< "QWebEngineCookieStore*"
<< "Qt::LayoutDirection"
- << "QQuickWebEngineScriptCollection*";
+ << "QQuickWebEngineScriptCollection*"
+ << "QQmlComponent*"
+ << "QMultiMap<QByteArray,QByteArray>";
static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineAction.text --> QString"
@@ -283,10 +270,25 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineTooltipRequest.text --> QString"
<< "QQuickWebEngineTooltipRequest.type --> QQuickWebEngineTooltipRequest::RequestType"
<< "QQuickWebEngineTooltipRequest.accepted --> bool"
+ << "QWebEngineDesktopMediaRequest.screensModel --> QAbstractListModel*"
+ << "QWebEngineDesktopMediaRequest.windowsModel --> QAbstractListModel*"
+ << "QWebEngineDesktopMediaRequest.selectScreen(QModelIndex) --> void"
+ << "QWebEngineDesktopMediaRequest.selectWindow(QModelIndex) --> void"
+ << "QWebEngineDesktopMediaRequest.cancel() --> void"
<< "QWebEngineFullScreenRequest.accept() --> void"
<< "QWebEngineFullScreenRequest.origin --> QUrl"
<< "QWebEngineFullScreenRequest.reject() --> void"
<< "QWebEngineFullScreenRequest.toggleOn --> bool"
+ << "QWebEngineFileSystemAccessRequest.File --> HandleType"
+ << "QWebEngineFileSystemAccessRequest.Directory --> HandleType"
+ << "QWebEngineFileSystemAccessRequest.Read --> AccessFlags"
+ << "QWebEngineFileSystemAccessRequest.Write --> AccessFlags"
+ << "QWebEngineFileSystemAccessRequest.origin --> QUrl"
+ << "QWebEngineFileSystemAccessRequest.filePath --> QUrl"
+ << "QWebEngineFileSystemAccessRequest.handleType --> QWebEngineFileSystemAccessRequest::HandleType"
+ << "QWebEngineFileSystemAccessRequest.accessFlags --> QFlags<QWebEngineFileSystemAccessRequest::AccessFlag>"
+ << "QWebEngineFileSystemAccessRequest.accept() --> void"
+ << "QWebEngineFileSystemAccessRequest.reject() --> void"
<< "QWebEngineHistory.backItems --> QWebEngineHistoryModel*"
<< "QWebEngineHistory.clear() --> void"
<< "QWebEngineHistory.forwardItems --> QWebEngineHistoryModel*"
@@ -305,6 +307,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineJavaScriptDialogRequest.title --> QString"
<< "QQuickWebEngineJavaScriptDialogRequest.type --> QQuickWebEngineJavaScriptDialogRequest::DialogType"
<< "QWebEngineLoadingInfo.errorCode --> int"
+ << "QWebEngineLoadingInfo.responseHeaders --> QMultiMap<QByteArray,QByteArray>"
<< "QWebEngineLoadingInfo.errorDomain --> QWebEngineLoadingInfo::ErrorDomain"
<< "QWebEngineLoadingInfo.errorString --> QString"
<< "QWebEngineLoadingInfo.status --> QWebEngineLoadingInfo::LoadStatus"
@@ -314,6 +317,7 @@ static const QStringList expectedAPI = QStringList()
<< "QWebEngineLoadingInfo.LoadStartedStatus --> LoadStatus"
<< "QWebEngineLoadingInfo.LoadStoppedStatus --> LoadStatus"
<< "QWebEngineLoadingInfo.LoadSucceededStatus --> LoadStatus"
+ << "QWebEngineLoadingInfo.HttpStatusCodeDomain --> ErrorDomain"
<< "QWebEngineLoadingInfo.CertificateErrorDomain --> ErrorDomain"
<< "QWebEngineLoadingInfo.ConnectionErrorDomain --> ErrorDomain"
<< "QWebEngineLoadingInfo.DnsErrorDomain --> ErrorDomain"
@@ -355,6 +359,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.cachePath --> QString"
<< "QQuickWebEngineProfile.cachePathChanged() --> void"
<< "QQuickWebEngineProfile.clearHttpCache() --> void"
+ << "QQuickWebEngineProfile.clearHttpCacheCompleted() --> void"
<< "QQuickWebEngineProfile.downloadFinished(QQuickWebEngineDownloadRequest*) --> void"
<< "QQuickWebEngineProfile.downloadRequested(QQuickWebEngineDownloadRequest*) --> void"
<< "QQuickWebEngineProfile.downloadPath --> QString"
@@ -374,6 +379,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfile.persistentCookiesPolicyChanged() --> void"
<< "QQuickWebEngineProfile.persistentStoragePath --> QString"
<< "QQuickWebEngineProfile.persistentStoragePathChanged() --> void"
+ << "QQuickWebEngineProfile.isPushServiceEnabled --> bool"
+ << "QQuickWebEngineProfile.pushServiceEnabledChanged() --> void"
<< "QQuickWebEngineProfile.spellCheckEnabled --> bool"
<< "QQuickWebEngineProfile.spellCheckEnabledChanged() --> void"
<< "QQuickWebEngineProfile.spellCheckLanguages --> QStringList"
@@ -402,6 +409,10 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.dnsPrefetchEnabledChanged() --> void"
<< "QQuickWebEngineSettings.errorPageEnabled --> bool"
<< "QQuickWebEngineSettings.errorPageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.forceDarkMode --> bool"
+ << "QQuickWebEngineSettings.forceDarkModeChanged() --> void"
+ << "QQuickWebEngineSettings.scrollAnimatorEnabled --> bool"
+ << "QQuickWebEngineSettings.scrollAnimatorEnabledChanged() --> void"
<< "QQuickWebEngineSettings.focusOnNavigationEnabled --> bool"
<< "QQuickWebEngineSettings.focusOnNavigationEnabledChanged() --> void"
<< "QQuickWebEngineSettings.fullScreenSupportEnabled --> bool"
@@ -424,6 +435,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.localContentCanAccessRemoteUrlsChanged() --> void"
<< "QQuickWebEngineSettings.localStorageEnabled --> bool"
<< "QQuickWebEngineSettings.localStorageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.navigateOnDropEnabled --> bool"
+ << "QQuickWebEngineSettings.navigateOnDropEnabledChanged() --> void"
<< "QQuickWebEngineSettings.pdfViewerEnabled --> bool"
<< "QQuickWebEngineSettings.pdfViewerEnabledChanged() --> void"
<< "QQuickWebEngineSettings.playbackRequiresUserGesture --> bool"
@@ -446,6 +459,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.webGLEnabledChanged() --> void"
<< "QQuickWebEngineSettings.webRTCPublicInterfacesOnly --> bool"
<< "QQuickWebEngineSettings.webRTCPublicInterfacesOnlyChanged() --> void"
+ << "QQuickWebEngineSettings.readingFromCanvasEnabled --> bool"
+ << "QQuickWebEngineSettings.readingFromCanvasEnabledChanged() --> void"
<< "QQuickWebEngineSingleton.defaultProfile --> QQuickWebEngineProfile*"
<< "QQuickWebEngineSingleton.settings --> QQuickWebEngineSettings*"
<< "QQuickWebEngineSingleton.script() --> QWebEngineScript"
@@ -470,7 +485,6 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.action(WebAction) --> QQuickWebEngineAction*"
<< "QQuickWebEngineView.A0 --> PrintedPageSizeId"
<< "QQuickWebEngineView.A1 --> PrintedPageSizeId"
- << "QQuickWebEngineView.A10 --> PrintedPageSizeId"
<< "QQuickWebEngineView.A2 --> PrintedPageSizeId"
<< "QQuickWebEngineView.A3 --> PrintedPageSizeId"
<< "QQuickWebEngineView.A3Extra --> PrintedPageSizeId"
@@ -484,6 +498,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.A7 --> PrintedPageSizeId"
<< "QQuickWebEngineView.A8 --> PrintedPageSizeId"
<< "QQuickWebEngineView.A9 --> PrintedPageSizeId"
+ << "QQuickWebEngineView.A10 --> PrintedPageSizeId"
<< "QQuickWebEngineView.AbnormalTerminationStatus --> RenderProcessTerminationStatus"
<< "QQuickWebEngineView.AlignCenter --> WebAction"
<< "QQuickWebEngineView.AlignJustified --> WebAction"
@@ -501,7 +516,6 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.ArchE --> PrintedPageSizeId"
<< "QQuickWebEngineView.B0 --> PrintedPageSizeId"
<< "QQuickWebEngineView.B1 --> PrintedPageSizeId"
- << "QQuickWebEngineView.B10 --> PrintedPageSizeId"
<< "QQuickWebEngineView.B2 --> PrintedPageSizeId"
<< "QQuickWebEngineView.B3 --> PrintedPageSizeId"
<< "QQuickWebEngineView.B4 --> PrintedPageSizeId"
@@ -511,9 +525,13 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.B7 --> PrintedPageSizeId"
<< "QQuickWebEngineView.B8 --> PrintedPageSizeId"
<< "QQuickWebEngineView.B9 --> PrintedPageSizeId"
+ << "QQuickWebEngineView.B10 --> PrintedPageSizeId"
<< "QQuickWebEngineView.Back --> WebAction"
<< "QQuickWebEngineView.C5E --> PrintedPageSizeId"
<< "QQuickWebEngineView.CertificateErrorDomain --> ErrorDomain"
+ << "QQuickWebEngineView.ChangeTextDirectionLTR --> WebAction"
+ << "QQuickWebEngineView.ChangeTextDirectionRTL --> WebAction"
+ << "QQuickWebEngineView.ClipboardReadWrite --> Feature"
<< "QQuickWebEngineView.Comm10E --> PrintedPageSizeId"
<< "QQuickWebEngineView.ConnectionErrorDomain --> ErrorDomain"
<< "QQuickWebEngineView.Copy --> WebAction"
@@ -626,11 +644,10 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.LoadStartedStatus --> LoadStatus"
<< "QQuickWebEngineView.LoadStoppedStatus --> LoadStatus"
<< "QQuickWebEngineView.LoadSucceededStatus --> LoadStatus"
+ << "QQuickWebEngineView.LocalFontsAccess --> Feature"
<< "QQuickWebEngineView.MediaAudioCapture --> Feature"
<< "QQuickWebEngineView.MediaAudioVideoCapture --> Feature"
<< "QQuickWebEngineView.MediaVideoCapture --> Feature"
- << "QQuickWebEngineView.NPageSize --> PrintedPageSizeId"
- << "QQuickWebEngineView.NPaperSize --> PrintedPageSizeId"
<< "QQuickWebEngineView.NoErrorDomain --> ErrorDomain"
<< "QQuickWebEngineView.Notifications --> Feature"
<< "QQuickWebEngineView.NoWebAction --> WebAction"
@@ -670,6 +687,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.ToggleUnderline --> WebAction"
<< "QQuickWebEngineView.Undo --> WebAction"
<< "QQuickWebEngineView.Unselect --> WebAction"
+ << "QQuickWebEngineView.OpenLinkInNewBackgroundTab --> WebAction"
<< "QQuickWebEngineView.ViewSource --> WebAction"
<< "QQuickWebEngineView.WarningMessageLevel --> JavaScriptConsoleMessageLevel"
<< "QQuickWebEngineView.WebActionCount --> WebAction"
@@ -689,10 +707,13 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.contentsSize --> QSizeF"
<< "QQuickWebEngineView.contentsSizeChanged(QSizeF) --> void"
<< "QQuickWebEngineView.contextMenuRequested(QWebEngineContextMenuRequest*) --> void"
+ << "QQuickWebEngineView.desktopMediaRequested(QWebEngineDesktopMediaRequest) --> void"
+ << "QQuickWebEngineView.devToolsId --> QString"
<< "QQuickWebEngineView.devToolsView --> QQuickWebEngineView*"
<< "QQuickWebEngineView.devToolsViewChanged() --> void"
- << "QQuickWebEngineView.featurePermissionRequested(QUrl,Feature) --> void"
+ << "QQuickWebEngineView.featurePermissionRequested(QUrl,QQuickWebEngineView::Feature) --> void"
<< "QQuickWebEngineView.fileDialogRequested(QQuickWebEngineFileDialogRequest*) --> void"
+ << "QQuickWebEngineView.fileSystemAccessRequested(QWebEngineFileSystemAccessRequest) --> void"
<< "QQuickWebEngineView.findText(QString) --> void"
<< "QQuickWebEngineView.findText(QString,FindFlags) --> void"
<< "QQuickWebEngineView.findText(QString,FindFlags,QJSValue) --> void"
@@ -703,7 +724,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.goBack() --> void"
<< "QQuickWebEngineView.goBackOrForward(int) --> void"
<< "QQuickWebEngineView.goForward() --> void"
- << "QQuickWebEngineView.grantFeaturePermission(QUrl,Feature,bool) --> void"
+ << "QQuickWebEngineView.grantFeaturePermission(QUrl,QQuickWebEngineView::Feature,bool) --> void"
<< "QQuickWebEngineView.history --> QWebEngineHistory*"
<< "QQuickWebEngineView.icon --> QUrl"
<< "QQuickWebEngineView.iconChanged() --> void"
@@ -711,10 +732,10 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.inspectedViewChanged() --> void"
<< "QQuickWebEngineView.isFullScreen --> bool"
<< "QQuickWebEngineView.isFullScreenChanged() --> void"
- << "QQuickWebEngineView.javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString) --> void"
+ << "QQuickWebEngineView.javaScriptConsoleMessage(QQuickWebEngineView::JavaScriptConsoleMessageLevel,QString,int,QString) --> void"
<< "QQuickWebEngineView.javaScriptDialogRequested(QQuickWebEngineJavaScriptDialogRequest*) --> void"
<< "QQuickWebEngineView.lifecycleState --> QQuickWebEngineView::LifecycleState"
- << "QQuickWebEngineView.lifecycleStateChanged(LifecycleState) --> void"
+ << "QQuickWebEngineView.lifecycleStateChanged(QQuickWebEngineView::LifecycleState) --> void"
<< "QQuickWebEngineView.linkHovered(QUrl) --> void"
<< "QQuickWebEngineView.loadHtml(QString) --> void"
<< "QQuickWebEngineView.loadHtml(QString,QUrl) --> void"
@@ -753,11 +774,11 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.renderProcessPid --> qlonglong"
<< "QQuickWebEngineView.renderProcessPidChanged(qlonglong) --> void"
<< "QQuickWebEngineView.recommendedState --> QQuickWebEngineView::LifecycleState"
- << "QQuickWebEngineView.recommendedStateChanged(LifecycleState) --> void"
+ << "QQuickWebEngineView.recommendedStateChanged(QQuickWebEngineView::LifecycleState) --> void"
<< "QQuickWebEngineView.registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest) --> void"
<< "QQuickWebEngineView.reload() --> void"
<< "QQuickWebEngineView.reloadAndBypassCache() --> void"
- << "QQuickWebEngineView.renderProcessTerminated(RenderProcessTerminationStatus,int) --> void"
+ << "QQuickWebEngineView.renderProcessTerminated(QQuickWebEngineView::RenderProcessTerminationStatus,int) --> void"
<< "QQuickWebEngineView.replaceMisspelledWord(QString) --> void"
<< "QQuickWebEngineView.runJavaScript(QString) --> void"
<< "QQuickWebEngineView.runJavaScript(QString,QJSValue) --> void"
@@ -772,6 +793,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.title --> QString"
<< "QQuickWebEngineView.titleChanged() --> void"
<< "QQuickWebEngineView.tooltipRequested(QQuickWebEngineTooltipRequest*) --> void"
+ << "QQuickWebEngineView.touchHandleDelegate --> QQmlComponent*"
+ << "QQuickWebEngineView.touchHandleDelegateChanged() --> void"
<< "QQuickWebEngineView.touchSelectionMenuRequested(QQuickWebEngineTouchSelectionMenuRequest*) --> void"
<< "QQuickWebEngineView.triggerWebAction(WebAction) --> void"
<< "QQuickWebEngineView.url --> QUrl"
@@ -787,6 +810,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.zoomFactor --> double"
<< "QQuickWebEngineView.zoomFactorChanged(double) --> void"
<< "QQuickWebEngineView.acceptAsNewWindow(QWebEngineNewWindowRequest*) --> void"
+ << "QQuickWebEngineView.save(QString) --> void"
+ << "QQuickWebEngineView.save(QString,QWebEngineDownloadRequest::SavePageFormat) --> void"
<< "QWebEngineQuotaRequest.accept() --> void"
<< "QWebEngineQuotaRequest.origin --> QUrl"
<< "QWebEngineQuotaRequest.reject() --> void"
@@ -805,6 +830,55 @@ static const QStringList expectedAPI = QStringList()
<< "QWebEngineNotification.click() --> void"
<< "QWebEngineNotification.close() --> void"
<< "QWebEngineNotification.closed() --> void"
+ << "QQuickWebEngineView.webAuthUxRequested(QWebEngineWebAuthUxRequest*) --> void"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.NotStarted --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.FinishTokenCollection --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.RequestFailed --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.Cancelled --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.WebAuthUxState.Completed --> WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.PinEntryReason.Set --> PinEntryReason"
+ << "QWebEngineWebAuthUxRequest.PinEntryReason.Change --> PinEntryReason"
+ << "QWebEngineWebAuthUxRequest.PinEntryReason.Challenge --> PinEntryReason"
+ << "QWebEngineWebAuthUxRequest.PinEntryError.NoError --> PinEntryError"
+ << "QWebEngineWebAuthUxRequest.PinEntryError.InternalUvLocked --> PinEntryError"
+ << "QWebEngineWebAuthUxRequest.PinEntryError.WrongPin --> PinEntryError"
+ << "QWebEngineWebAuthUxRequest.PinEntryError.TooShort --> PinEntryError"
+ << "QWebEngineWebAuthUxRequest.PinEntryError.InvalidCharacters --> PinEntryError"
+ << "QWebEngineWebAuthUxRequest.PinEntryError.SameAsCurrentPin --> PinEntryError"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.Timeout --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.KeyNotRegistered --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.KeyAlreadyRegistered --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.SoftPinBlock --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.HardPinBlock --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorRemovedDuringPinEntry --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingResidentKeys --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingUserVerification --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingLargeBlob --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.NoCommonAlgorithms --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.StorageFull --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.UserConsentDenied --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.RequestFailureReason.WinUserCancelled --> RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.userNames --> QStringList"
+ << "QWebEngineWebAuthUxRequest.state --> QWebEngineWebAuthUxRequest::WebAuthUxState"
+ << "QWebEngineWebAuthUxRequest.relyingPartyId --> QString"
+ << "QWebEngineWebAuthUxRequest.pinRequest --> QWebEngineWebAuthPinRequest"
+ << "QWebEngineWebAuthUxRequest.requestFailureReason --> QWebEngineWebAuthUxRequest::RequestFailureReason"
+ << "QWebEngineWebAuthUxRequest.stateChanged(QWebEngineWebAuthUxRequest::WebAuthUxState) --> void"
+ << "QWebEngineWebAuthUxRequest.cancel() --> void"
+ << "QWebEngineWebAuthUxRequest.retry() --> void"
+ << "QWebEngineWebAuthUxRequest.setSelectedAccount(QString) --> void"
+ << "QWebEngineWebAuthUxRequest.setPin(QString) --> void"
+ << "QWebEngineWebAuthPinRequest.reason --> QWebEngineWebAuthUxRequest::PinEntryReason"
+ << "QWebEngineWebAuthPinRequest.error --> QWebEngineWebAuthUxRequest::PinEntryError"
+ << "QWebEngineWebAuthPinRequest.minPinLength --> int"
+ << "QWebEngineWebAuthPinRequest.remainingAttempts --> int"
+ << "QQuickWebEngineSettings.AllowImageAnimation --> ImageAnimationPolicy"
+ << "QQuickWebEngineSettings.AnimateImageOnce --> ImageAnimationPolicy"
+ << "QQuickWebEngineSettings.DisallowImageAnimation --> ImageAnimationPolicy"
+ << "QQuickWebEngineSettings.imageAnimationPolicy --> QQuickWebEngineSettings::ImageAnimationPolicy"
+ << "QQuickWebEngineSettings.imageAnimationPolicyChanged() --> void"
;
static bool isCheckedEnum(QMetaType t)
@@ -898,14 +972,14 @@ void tst_publicapi::publicAPI()
// Uncomment to print the actual API.
// QStringList sortedAPI(actualAPI);
// std::sort(sortedAPI.begin(), sortedAPI.end());
- // for (const QString &actual : qAsConst(sortedAPI))
+ // for (const QString &actual : std::as_const(sortedAPI))
// printf(" << \"%s\"\n", qPrintable(actual));
bool apiMatch = true;
// Make sure that nothing slips in the public API unintentionally.
- for (const QString &actual : qAsConst(actualAPI)) {
+ for (const QString &actual : std::as_const(actualAPI)) {
if (!expectedAPI.contains(actual)) {
- QWARN(qPrintable("Expected list is not up-to-date: " + actual));
+ qWarning("Expected list is not up-to-date: %ls", qUtf16Printable(actual));
apiMatch = false;
}
}
@@ -913,7 +987,7 @@ void tst_publicapi::publicAPI()
for (const QString &expected : expectedAPI) {
if (!actualAPI.contains(expected)) {
apiMatch = false;
- QWARN(qPrintable("Not implemented: " + expected));
+ qWarning("Not implemented: %ls", qUtf16Printable(expected));
}
}
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index f4009e16c..fc8f9f0d8 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -6,3 +6,7 @@ macos
[CertificateError::test_fatalError]
*
+
+[CertificateError::test_error]
+*
+
diff --git a/tests/auto/quick/qmltests/CMakeLists.txt b/tests/auto/quick/qmltests/CMakeLists.txt
index 455c4c746..daae6d60d 100644
--- a/tests/auto/quick/qmltests/CMakeLists.txt
+++ b/tests/auto/quick/qmltests/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
@@ -18,17 +21,21 @@ set(testList
tst_activeFocusOnPress.qml
tst_audioMuted.qml
tst_contextMenu.qml
+ tst_basicProfiles.qml
+ tst_datalist.qml
tst_desktopBehaviorLoadHtml.qml
tst_download.qml
+ tst_dragHandlerUnderView.qml
tst_favicon.qml
tst_faviconDatabase.qml
tst_filePicker.qml
+ tst_filesystem.qml
tst_findText.qml
tst_focusOnNavigation.qml
tst_fullScreenRequest.qml
- tst_geopermission.qml
tst_getUserMedia.qml
tst_inputMethod.qml
+ tst_inputTextDirection.qml
tst_javaScriptDialogs.qml
tst_keyboardEvents.qml
tst_keyboardModifierMapping.qml
@@ -51,7 +58,9 @@ set(testList
tst_titleChanged.qml
tst_unhandledKeyEventPropagation.qml
tst_userScripts.qml
+ tst_userScriptCollection.qml
tst_viewSource.qml
+ tst_save.qml
)
if(QT_FEATURE_webengine_webchannel)
@@ -62,6 +71,10 @@ if(QT_FEATURE_ssl)
list(APPEND testList tst_certificateError.qml)
endif()
+if (NOT APPLE)
+ list(APPEND testList tst_geopermission.qml)
+endif()
+
set(content "")
foreach(test ${testList})
set(contents "${contents}${CMAKE_CURRENT_LIST_DIR}/data/${test}\n")
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index 68417c6c5..415985471 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -65,7 +40,7 @@ WebEngineView {
}
function _waitFor(predicate, timeout) {
if (timeout === undefined)
- timeout = 12000;
+ timeout = 30000;
var i = 0
while (i < timeout && !predicate()) {
testResult.wait(50)
@@ -113,6 +88,21 @@ WebEngineView {
return textSelection;
}
+ function getElementValue(element) {
+ var elementValue;
+ runJavaScript("document.getElementById('" + element + "').value", function(result) {
+ elementValue = result;
+ });
+ testCase.tryVerify(function() { return elementValue != undefined; });
+ return elementValue;
+ }
+
+ function compareElementValue(element, expected) {
+ testCase.tryVerify(function() { return expected == getElementValue(element); }, 5000,
+ "Value of element \"" + element + "\" is \"" + expected + "\"");
+ }
+
+
TestResult { id: testResult }
onLoadingChanged: function(load) {
diff --git a/tests/auto/quick/qmltests/data/filesystemapi.html b/tests/auto/quick/qmltests/data/filesystemapi.html
new file mode 100644
index 000000000..ab1a33e4d
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/filesystemapi.html
@@ -0,0 +1,66 @@
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title> Failed to Upload </title>
+</script>
+</head>
+
+<body>
+<button>Request File Picker</button>
+<script>
+ async function handleDirectoryEntry( dirHandle, out ) {
+ for await (const entry of dirHandle.values()) {
+ if (entry.kind === "file"){
+ const file = await entry.getFile();
+ out[ file.name ] = file;
+ }
+ if (entry.kind === "directory") {
+ const newHandle = await dirHandle.getDirectoryHandle( entry.name, { create: false } );
+ const newOut = out[ entry.name ] = {};
+ await handleDirectoryEntry( newHandle, newOut );
+ }
+ }
+ }
+ const button = document.querySelector('button');
+ button.addEventListener('click', async function() {
+ switch(window.dialogType) {
+ case "savePicker":
+ const saveFileHandle = await window.showSaveFilePicker();
+ const writable = await saveFileHandle.createWritable();
+ await writable.write(new Blob(['TEST_CONTENT']));
+ await writable.close();
+ console.log("TEST:DONE")
+ break;
+ case "filePicker":
+ let [openFileHandle] = await window.showOpenFilePicker();
+ const options = {};
+ options.mode = 'readwrite'
+ await openFileHandle.requestPermission(options)
+ const file = await openFileHandle.getFile();
+ const contents = await file.text();
+ console.log("TEST:" + contents)
+ console.log("TEST:DONE")
+ break;
+ case "directoryPicker":
+ console.log("start")
+ const dirHandle = await window.showDirectoryPicker();
+ for await (const entry of dirHandle.values()) {
+ if (entry.kind === "file"){
+ continue
+ }
+ if (entry.kind === "directory") {
+ console.log("TEST:" + entry.name)
+ }
+ }
+ console.log("TEST:DONE")
+ break;
+ default:
+ }
+ });
+ window.onload = function() {
+ window.dialogType = window.location.href.split('=')[1];
+ document.querySelector('button').focus()
+ }
+</script>
+</body>
+</html>
diff --git a/tests/auto/quick/qmltests/data/test4.html b/tests/auto/quick/qmltests/data/test4.html
index cf5708994..82830668a 100644
--- a/tests/auto/quick/qmltests/data/test4.html
+++ b/tests/auto/quick/qmltests/data/test4.html
@@ -9,7 +9,6 @@
font-size: 50px;
}
</style>
- <meta name="viewport" content="initial-scale=2.0"/>
</head>
<body>
<button onclick="scrollWin()" id="scroll">Click me to scroll!</button><br><br>
diff --git a/tests/auto/quick/qmltests/data/titleupdate.js b/tests/auto/quick/qmltests/data/titleupdate.js
index c86139c13..720e83676 100644
--- a/tests/auto/quick/qmltests/data/titleupdate.js
+++ b/tests/auto/quick/qmltests/data/titleupdate.js
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
function updateTitle()
{
diff --git a/tests/auto/quick/qmltests/data/tst_action.qml b/tests/auto/quick/qmltests/data/tst_action.qml
index 554f0929a..9e49c2dbf 100644
--- a/tests/auto/quick/qmltests/data/tst_action.qml
+++ b/tests/auto/quick/qmltests/data/tst_action.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -90,7 +65,9 @@ TestWebEngineView {
{ webAction: WebEngineView.Indent, text: "&Indent", iconName: "", enabled: true },
{ webAction: WebEngineView.Outdent, text: "&Outdent", iconName: "", enabled: true },
{ webAction: WebEngineView.InsertOrderedList, text: "Insert &Ordered List", iconName: "", enabled: true },
- { webAction: WebEngineView.InsertUnorderedList, text: "Insert &Unordered List", iconName: "", enabled: true }
+ { webAction: WebEngineView.InsertUnorderedList, text: "Insert &Unordered List", iconName: "", enabled: true },
+ { webAction: WebEngineView.ChangeTextDirectionLTR, text: "Change text direction left to right", iconName: "", enabled: true },
+ { webAction: WebEngineView.ChangeTextDirectionRTL, text: "Change text direction right to left", iconName: "", enabled: true }
];
}
diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
index d423bdd12..77968f6b6 100644
--- a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
+++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_audioMuted.qml b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
index c6a882f5a..85f813f0c 100644
--- a/tests/auto/quick/qmltests/data/tst_audioMuted.qml
+++ b/tests/auto/quick/qmltests/data/tst_audioMuted.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_basicProfiles.qml b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
new file mode 100644
index 000000000..97a25cdd8
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_basicProfiles.qml
@@ -0,0 +1,90 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtWebEngine
+import Qt.labs.platform
+
+Item {
+ WebEngineProfile { id: otrProfile; /* MEMO implicit offTheRecord: true */ }
+ WebEngineProfile { id: nonOtrProfile; offTheRecord: false }
+
+ function getPath(path, offset = 1) { return path.substr(path.indexOf(':') + offset, path.length) }
+ property string appDataLocation: getPath(getPath(StandardPaths.writableLocation(StandardPaths.AppDataLocation).toString(), 3))
+ property string cacheLocation: getPath(getPath(StandardPaths.writableLocation(StandardPaths.CacheLocation).toString(), 3))
+ property string downloadLocation: getPath(getPath(StandardPaths.writableLocation(StandardPaths.DownloadLocation).toString(), 3))
+
+ TestCase {
+ name: "BasicProfiles"
+
+ function test_defaultProfile() {
+ let p = WebEngine.defaultProfile
+ verify(p.offTheRecord)
+
+ compare(p.storageName, '')
+ compare(p.cachePath, '')
+ compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/OffTheRecord')
+ compare(p.httpCacheType, WebEngineProfile.MemoryHttpCache)
+ compare(p.httpCacheMaximumSize, 0)
+ compare(p.persistentCookiesPolicy, WebEngineProfile.NoPersistentCookies)
+
+ compare(getPath(p.downloadPath), downloadLocation)
+ compare(p.httpAcceptLanguage, '')
+ verify(p.httpUserAgent !== '')
+ compare(p.spellCheckEnabled, false)
+ compare(p.spellCheckLanguages, [])
+
+ compare(p.userScripts.collection, [])
+ }
+
+ function test_otrProfile() {
+ let p = otrProfile
+ verify(p.offTheRecord)
+
+ compare(p.storageName, '')
+ compare(p.cachePath, '')
+ compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/OffTheRecord')
+ compare(p.httpCacheType, WebEngineProfile.MemoryHttpCache)
+ compare(p.httpCacheMaximumSize, 0)
+ compare(p.persistentCookiesPolicy, WebEngineProfile.NoPersistentCookies)
+
+ compare(getPath(p.downloadPath), downloadLocation)
+ compare(p.httpAcceptLanguage, '')
+ verify(p.httpUserAgent !== '')
+ compare(p.spellCheckEnabled, false)
+ compare(p.spellCheckLanguages, [])
+
+ compare(p.userScripts.collection, [])
+ }
+
+ function test_nonOtrProfile() {
+ let p = nonOtrProfile
+ verify(!p.offTheRecord)
+
+ compare(p.storageName, '')
+ compare(p.cachePath, '')
+ compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/UnknownProfile')
+ compare(p.httpCacheType, WebEngineProfile.MemoryHttpCache)
+ compare(p.httpCacheMaximumSize, 0)
+ compare(p.persistentCookiesPolicy, WebEngineProfile.NoPersistentCookies)
+
+ compare(getPath(p.downloadPath), downloadLocation)
+ compare(p.httpAcceptLanguage, '')
+ verify(p.httpUserAgent !== '')
+ compare(p.spellCheckEnabled, false)
+ compare(p.spellCheckLanguages, [])
+
+ compare(p.userScripts.collection, [])
+
+ p.storageName = 'Test'
+ compare(p.storageName, 'Test')
+ compare(getPath(p.cachePath), cacheLocation + '/QtWebEngine/' + p.storageName)
+ compare(getPath(p.persistentStoragePath), appDataLocation + '/QtWebEngine/' + p.storageName)
+
+ compare(p.httpCacheType, WebEngineProfile.DiskHttpCache)
+ compare(p.httpCacheMaximumSize, 0)
+ compare(p.persistentCookiesPolicy, WebEngineProfile.AllowPersistentCookies)
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_certificateError.qml b/tests/auto/quick/qmltests/data/tst_certificateError.qml
index a9031896a..220ef9ac8 100644
--- a/tests/auto/quick/qmltests/data/tst_certificateError.qml
+++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_contextMenu.qml b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
index d415996bd..58e27b8ba 100644
--- a/tests/auto/quick/qmltests/data/tst_contextMenu.qml
+++ b/tests/auto/quick/qmltests/data/tst_contextMenu.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_datalist.qml b/tests/auto/quick/qmltests/data/tst_datalist.qml
new file mode 100644
index 000000000..f739639b2
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_datalist.qml
@@ -0,0 +1,180 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtQuick.Controls
+import QtTest
+import QtWebEngine
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 400
+
+ property string html: "<html><body>" +
+ "<input id='browserInput' list='browserDatalist'>" +
+ "<datalist id='browserDatalist'>" +
+ " <option value='Internet Explorer'>" +
+ " <option value='Firefox'>" +
+ " <option value='Chrome'>" +
+ " <option value='Opera'>" +
+ " <option value='Safari'>" +
+ "</datalist>" +
+ "</body></html>"
+
+ function listView() {
+ if (webEngineView.parent.visibleChildren.length == 1) {
+ // No popup case.
+ return null;
+ }
+
+ let overlay = null;
+ for (let i = 0; i < webEngineView.parent.visibleChildren.length; ++i) {
+ let child = webEngineView.parent.visibleChildren[i];
+ if (child instanceof Overlay) {
+ overlay = child;
+ break;
+ }
+ }
+
+ if (!overlay)
+ return null;
+
+ let popupItem = null;
+ for (let i = 0; i < overlay.visibleChildren[0].visibleChildren.length; ++i) {
+ let child = overlay.visibleChildren[0].visibleChildren[i];
+ if (child.objectName == "QQuickPopupItem") {
+ popupItem = child;
+ }
+ }
+
+ if (!popupItem)
+ return null;
+
+ for (let i = 0; i < popupItem.visibleChildren.length; ++i) {
+ let child = popupItem.visibleChildren[i];
+ if (child instanceof ListView)
+ return child;
+ }
+
+ return null;
+ }
+
+ TestCase {
+ id: testCase
+ name: "WebEngineDatalist"
+ when: windowShown
+
+ function test_showAndHide() {
+ webEngineView.loadHtml(webEngineView.html);
+ verify(webEngineView.waitForLoadSucceeded());
+
+ var values = "";
+ webEngineView.runJavaScript(
+ "(function() {" +
+ " var browserDatalist = document.getElementById('browserDatalist');" +
+ " var options = browserDatalist.options;" +
+ " var result = [];" +
+ " for (let i = 0; i < options.length; ++i) {" +
+ " result.push(options[i].value);" +
+ " }" +
+ " return result;" +
+ "})();", function(result) { values = result; });
+ tryVerify(function() { return values.length != 0; });
+ compare(values, ["Internet Explorer", "Firefox", "Chrome", "Opera", "Safari"]);
+ compareElementValue("browserInput", "");
+
+ // Make sure there is no open popup yet.
+ verify(!listView());
+ // Click in the input field.
+ var browserInputCenter = getElementCenter("browserInput");
+ mouseClick(webEngineView, browserInputCenter.x, browserInputCenter.y, Qt.LeftButton);
+ // Wait for the popup.
+ tryVerify(function() { return listView() != null; });
+
+ // No suggestion is selected.
+ verify(!listView().currentItem);
+ compare(listView().count, 5);
+
+ // Accepting suggestion does nothing.
+ keyClick(Qt.Key_Enter);
+ tryVerify(function() { return listView() != null; });
+ verify(!listView().currentItem);
+
+ // Escape should close popup.
+ keyClick(Qt.Key_Escape);
+ tryVerify(function() { return listView() == null; });
+
+ // Key Down should open the popup and select the first suggestion.
+ keyClick(Qt.Key_Down);
+ tryVerify(function() { return listView() != null; });
+ compare(listView().currentIndex, 0);
+ verify(listView().currentItem);
+ }
+
+ function test_keyboardNavigationAndAccept() {
+ webEngineView.loadHtml(html);
+ verify(webEngineView.waitForLoadSucceeded());
+ setFocusToElement("browserInput");
+
+ // Make sure there is no open popup yet.
+ verify(!listView());
+
+ // Key Down should open the popup and select the first suggestion.
+ keyClick(Qt.Key_Down);
+ tryVerify(function() { return listView() != null; });
+ compare(listView().currentIndex, 0);
+
+ // Test keyboard navigation in list.
+ keyClick(Qt.Key_Up);
+ compare(listView().currentIndex, 4);
+ keyClick(Qt.Key_Up);
+ compare(listView().currentIndex, 3);
+ keyClick(Qt.Key_PageDown);
+ compare(listView().currentIndex, 4);
+ keyClick(Qt.Key_PageUp);
+ compare(listView().currentIndex, 0);
+ keyClick(Qt.Key_Down);
+ compare(listView().currentIndex, 1);
+ keyClick(Qt.Key_Down);
+ compare(listView().currentIndex, 2);
+
+ // Test accepting suggestion.
+ compare(listView().currentItem.text, "Chrome");
+ keyClick(Qt.Key_Enter);
+ compareElementValue("browserInput", "Chrome");
+ // Accept closes popup.
+ tryVerify(function() { return listView() == null; });
+
+ // Clear input field, should not trigger popup.
+ webEngineView.runJavaScript("document.getElementById('browserInput').value = ''");
+ compareElementValue("browserInput", "");
+ verify(listView() == null);
+ }
+
+ function test_filterSuggestion() {
+ webEngineView.loadHtml(html);
+ verify(webEngineView.waitForLoadSucceeded());
+ setFocusToElement("browserInput");
+
+ // Make sure there is no open popup yet.
+ verify(!listView());
+
+ // Filter suggestions.
+ keyClick(Qt.Key_F);
+ tryVerify(function() { return listView() != null; });
+ compare(listView().count, 2);
+ verify(!listView().currentItem);
+ compare(listView().itemAtIndex(0).text, "Firefox");
+ compare(listView().itemAtIndex(1).text, "Safari");
+ keyClick(Qt.Key_I);
+ tryVerify(function() { return listView().count == 1; });
+ verify(!listView().currentItem);
+ compare(listView().itemAtIndex(0).text, "Firefox");
+ keyClick(Qt.Key_L);
+ // Mismatch should close popup.
+ tryVerify(function() { return listView() == null; });
+ compareElementValue("browserInput", "fil");
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
index 8ab9925dd..6cb2841ec 100644
--- a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 93c430a51..61a363c39 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml b/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml
new file mode 100644
index 000000000..c22bd44c2
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml
@@ -0,0 +1,67 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtWebEngine
+
+Item {
+ id: parentItem
+ width: 400
+ height: 300
+
+ Rectangle {
+ id: draggableDownUnder
+ color: "wheat"
+ width: 350
+ height: 250
+
+ DragHandler { id: dragHandler }
+ }
+
+ TestWebEngineView {
+ id: webEngineView
+ width: 300
+ height: 250
+
+ property var testUrl: Qt.resolvedUrl("test4.html")
+
+ SignalSpy {
+ id: scrollPositionSpy
+ target: webEngineView
+ signalName: "onScrollPositionChanged"
+ }
+
+ SignalSpy {
+ id: dragActiveSpy
+ target: dragHandler
+ signalName: "activeChanged"
+ }
+
+ TestCase {
+ id: testCase
+ name: "KeepMouseGrabDuringScrolling"
+ when: windowShown
+
+ function test_scroll() {
+ webEngineView.url = Qt.resolvedUrl("test4.html");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ mousePress(webEngineView, 295, 20);
+ mouseMove(webEngineView, 295, 200);
+ mouseRelease(webEngineView, 295, 200);
+
+ // WebEngineView scrolled if the scrollbar was visible.
+ // But on macOS, the scrollbar is hidden, so text gets selected.
+ tryVerify(function() {
+ return (scrollPositionSpy.count === 1 && webEngineView.scrollPosition.y > 100)
+ || webEngineView.getTextSelection().length > 0;
+ });
+
+ // DragHandler didn't take over and drag
+ compare(dragActiveSpy.count, 0);
+ compare(draggableDownUnder.y, 0);
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index 79c835c70..15f116e5d 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -165,6 +140,38 @@ TestWebEngineView {
compare(iconUrl, Qt.resolvedUrl("icons/qt32.ico"))
}
+ function test_faviconLoadPushState_data() {
+ return [
+ { tag: "OTR", profile: defaultProfile },
+ { tag: "non-OTR", profile: nonOTRProfile },
+ ];
+ }
+
+ function test_faviconLoadPushState(row) {
+ webEngineView.profile = row.profile;
+ compare(iconChangedSpy.count, 0);
+
+ var iconUrl;
+
+ webEngineView.url = Qt.resolvedUrl("favicon.html");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(iconChangedSpy, "count", 1);
+ iconUrl = removeFaviconProviderPrefix(webEngineView.icon);
+ compare(iconUrl, Qt.resolvedUrl("icons/favicon.png"));
+
+ iconChangedSpy.clear();
+
+ // pushState() is a same document navigation and should not reset or
+ // update favicon.
+ compare(webEngineView.history.items.rowCount(), 1);
+ runJavaScript("history.pushState('', '')");
+ tryVerify(function() { return webEngineView.history.items.rowCount() === 2; });
+
+ // Favicon change is not expected.
+ compare(iconChangedSpy.count, 0);
+ iconUrl = removeFaviconProviderPrefix(webEngineView.icon);
+ compare(iconUrl, Qt.resolvedUrl("icons/favicon.png"));
+ }
function test_noFavicon_data() {
return [
diff --git a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
index 181c652d7..284390619 100644
--- a/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
+++ b/tests/auto/quick/qmltests/data/tst_faviconDatabase.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -110,6 +85,9 @@ TestWebEngineView {
function test_iconDatabase(row)
{
+ if (Screen.devicePixelRatio !== 1.0)
+ skip("This test is not supported on High DPI screens.");
+
webEngineView.profile = row.profile;
compare(iconChangedSpy.count, 0);
@@ -154,6 +132,9 @@ TestWebEngineView {
function test_iconDatabaseMultiView()
{
+ if (Screen.devicePixelRatio !== 1.0)
+ skip("This test is not supported on High DPI screens.");
+
var pixel;
var faviconImage = Qt.createQmlObject("
diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml
index 475718c31..a7b59b2e9 100644
--- a/tests/auto/quick/qmltests/data/tst_filePicker.qml
+++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -36,7 +11,6 @@ TestWebEngineView {
id: webEngineView
width: 400
height: 300
- property var titleChanges: []
function driveLetter() {
if (Qt.platform.os !== "windows")
@@ -55,8 +29,6 @@ TestWebEngineView {
signalName: "renderProcessTerminated"
}
- onTitleChanged: { titleChanges.push(webEngineView.title) }
-
TestCase {
id: testCase
name: "WebEngineViewSingleFileUpload"
@@ -69,7 +41,6 @@ TestWebEngineView {
FilePickerParams.nameFilters = []
titleSpy.clear()
terminationSpy.clear()
- titleChanges = []
}
function cleanup() {
@@ -112,10 +83,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryCompare(FilePickerParams, "filePickerOpened", true);
+ tryCompare(webEngineView, "title", row.expected);
webEngineView.url = Qt.resolvedUrl("about:blank");
verify(webEngineView.waitForLoadSucceeded());
tryCompare(webEngineView, "title", "about:blank");
- compare(titleChanges[titleChanges.length-2], row.expected);
// Custom dialog
@@ -123,7 +94,7 @@ TestWebEngineView {
function acceptedFileHandler(request) {
request.accepted = true;
- request.dialogAccept(row.input);
+ request.dialogAccept([row.input]);
finished = true;
}
@@ -133,10 +104,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryVerify(function() { return finished; });
+ tryCompare(webEngineView, "title", row.expected);
webEngineView.url = Qt.resolvedUrl("about:blank");
verify(webEngineView.waitForLoadSucceeded());
tryCompare(webEngineView, "title", "about:blank");
- compare(titleChanges[titleChanges.length-2], row.expected);
webEngineView.fileDialogRequested.disconnect(acceptedFileHandler);
}
@@ -171,7 +142,7 @@ TestWebEngineView {
FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data"))
keyClick(Qt.Key_Enter) // Focus is on the button. Open FileDialog.
- tryCompare(FilePickerParams, "filePickerOpened", true)
+ tryCompare(FilePickerParams, "directoryPickerOpened", true)
// Check that the title is a file list (eg. "test1.html,test2.html")
tryVerify(function() { return webEngineView.title.match("^([^,]+,)+[^,]+$"); })
@@ -267,10 +238,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryCompare(FilePickerParams, "filePickerOpened", true);
+ tryCompare(webEngineView, "title", row.expected);
webEngineView.url = Qt.resolvedUrl("about:blank");
verify(webEngineView.waitForLoadSucceeded());
tryCompare(webEngineView, "title", "about:blank");
- compare(titleChanges[titleChanges.length-2], row.expected);
// Custom dialog
@@ -278,7 +249,7 @@ TestWebEngineView {
function acceptedFileHandler(request) {
request.accepted = true;
- request.dialogAccept(row.input);
+ request.dialogAccept([row.input]);
finished = true;
}
@@ -288,10 +259,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryVerify(function() { return finished; });
+ tryCompare(webEngineView, "title", row.expected);
webEngineView.url = Qt.resolvedUrl("about:blank");
verify(webEngineView.waitForLoadSucceeded());
tryCompare(webEngineView, "title", "about:blank");
- compare(titleChanges[titleChanges.length-2], row.expected);
webEngineView.fileDialogRequested.disconnect(acceptedFileHandler);
}
diff --git a/tests/auto/quick/qmltests/data/tst_filesystem.qml b/tests/auto/quick/qmltests/data/tst_filesystem.qml
new file mode 100644
index 000000000..fa0da4457
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_filesystem.qml
@@ -0,0 +1,124 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtWebEngine
+import Test.util
+import "../../qmltests/data"
+import "../mock-delegates/TestParams"
+
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 300
+ property var logs: []
+ property bool accessRequested: false
+ property url file: tempDir.pathUrl('file.txt')
+
+ onJavaScriptConsoleMessage: function(level, message, lineNumber, source) {
+ var pair = message.split(':');
+ if (pair.length == 2 && pair[0] == "TEST")
+ logs.push(pair[1]);
+ }
+
+ TempDir { id: tempDir }
+
+ TestCase {
+ id: testCase
+ name: "FileSystemAPI"
+ when: windowShown
+
+ function init() {
+ clearLog()
+ FilePickerParams.filePickerOpened = false
+ FilePickerParams.selectFiles = false
+ FilePickerParams.selectedFilesUrl = []
+ FilePickerParams.nameFilters = []
+ accessRequested = false;
+ }
+
+ function cleanup() {
+ clearLog()
+ }
+
+ function clearLog() {
+ logs = []
+ }
+
+ function logContainsDoneMarker() {
+ if (logs.indexOf("DONE") > -1)
+ return true
+ else
+ return false
+ }
+
+ function result() {
+ return logs[0]
+ }
+
+ function fileAccessRequest(request) {
+ testCase.verify(!accessRequested)
+ accessRequested = true
+ testCase.verify(request.filePath == file)
+ testCase.verify(request.accessFlags == WebEngineFileSystemAccessRequest.Write | WebEngineFileSystemAccessRequest.Read)
+ request.accept()
+ }
+
+ function directoryAccessRequest(request) {
+ testCase.verify(!accessRequested)
+ accessRequested = true
+ testCase.verify(request.filePath == tempDir.pathUrl())
+ testCase.verify(request.accessFlags == WebEngineFileSystemAccessRequest.Read)
+ request.accept()
+ }
+
+ function test_saveFile() {
+ webEngineView.fileSystemAccessRequested.connect(fileAccessRequest);
+ webEngineView.url = Qt.resolvedUrl("filesystemapi.html?dialog=savePicker");
+ verify(webEngineView.waitForLoadSucceeded());
+ FilePickerParams.selectFiles = true;
+ FilePickerParams.selectedFilesUrl.push(file);
+ keyClick(Qt.Key_Enter); // Open SaveDialog.
+ tryCompare(FilePickerParams, "filePickerOpened", true);
+ tryVerify(logContainsDoneMarker,2000)
+ // write access for save dialogs is automatically granted
+ verify(!accessRequested)
+ webEngineView.fileSystemAccessRequested.disconnect(fileAccessRequest);
+ }
+
+ function test_openFile() {
+ // first save the file before open
+ test_saveFile()
+ init()
+ webEngineView.fileSystemAccessRequested.connect(fileAccessRequest);
+ webEngineView.url = Qt.resolvedUrl("filesystemapi.html?dialog=filePicker");
+ verify(webEngineView.waitForLoadSucceeded());
+ FilePickerParams.selectFiles = true;
+ FilePickerParams.selectedFilesUrl.push(file);
+ keyClick(Qt.Key_Enter); // Open FileDialog.
+ tryCompare(FilePickerParams, "filePickerOpened", true);
+ tryVerify(logContainsDoneMarker,2000)
+ verify(logs.indexOf("TEST_CONTENT") > -1)
+ verify(accessRequested)
+ webEngineView.fileSystemAccessRequested.disconnect(fileAccessRequest);
+ }
+
+ function test_selectDirectory() {
+ tempDir.createDirectory("TEST_DIR")
+ webEngineView.fileSystemAccessRequested.connect(directoryAccessRequest);
+ webEngineView.url = Qt.resolvedUrl("filesystemapi.html?dialog=directoryPicker");
+ verify(webEngineView.waitForLoadSucceeded())
+ FilePickerParams.selectFiles = true;
+ FilePickerParams.selectedFilesUrl.push(tempDir.pathUrl());
+ keyClick(Qt.Key_Enter); // Open showDirectoryDialog.
+ tryCompare(FilePickerParams, "directoryPickerOpened", true);
+ tryVerify(logContainsDoneMarker,2000)
+ verify(logs.indexOf("TEST_DIR") > -1)
+ verify(accessRequested)
+ webEngineView.fileSystemAccessRequested.disconnect(directoryAccessRequest);
+ }
+
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index 874f6184b..597cff73e 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -231,8 +206,7 @@ TestWebEngineView {
var listItemText = '';
for (var i = 0; i < 100000; ++i)
- listItemText += "bla ";
- listItemText = listItemText.trim();
+ listItemText += "bla";
webEngineView.loadHtml(
"<html><body>" +
diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
index 7ed684f79..f070e4bc5 100644
--- a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
+++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_geopermission.qml b/tests/auto/quick/qmltests/data/tst_geopermission.qml
index d16e94d8d..b99e50acc 100644
--- a/tests/auto/quick/qmltests/data/tst_geopermission.qml
+++ b/tests/auto/quick/qmltests/data/tst_geopermission.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
index fe2d91011..3b33b7abe 100644
--- a/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
+++ b/tests/auto/quick/qmltests/data/tst_getUserMedia.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_inputMethod.qml b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
index 0b7135bbf..cf79e8a4d 100644
--- a/tests/auto/quick/qmltests/data/tst_inputMethod.qml
+++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml b/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml
new file mode 100644
index 000000000..2141db4c8
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_inputTextDirection.qml
@@ -0,0 +1,43 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtWebEngine
+
+TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 400
+
+ TestCase {
+ id: testCase
+ name: "WebEngineInputTextDirection"
+ when: windowShown
+
+ function getInputTextDirection(element) {
+ var dir;
+ runJavaScript("document.getElementById('" + element + "').dir", function(result) {
+ dir = result;
+ });
+ tryVerify(function() { return dir != undefined; });
+ return dir;
+ }
+
+ function test_changeInputTextDirection() {
+ webEngineView.loadHtml("<html><body><input type='text' id='textfield' value='some text'></body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ setFocusToElement("textfield");
+
+ var rtlAction = webEngineView.action(WebEngineView.ChangeTextDirectionRTL);
+ verify(rtlAction);
+ rtlAction.trigger();
+ compare(getInputTextDirection("textfield"), "rtl");
+
+ var ltrAction = webEngineView.action(WebEngineView.ChangeTextDirectionLTR);
+ verify(ltrAction);
+ ltrAction.trigger();
+ compare(getInputTextDirection("textfield"), "ltr");
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
index 91b57c101..6e91b2e77 100644
--- a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
+++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** 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:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
index 7c594d921..0f69a7e81 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -54,20 +29,6 @@ TestWebEngineView {
"Element \"" + element + "\" is " + (expected ? "" : "not") + " checked");
}
- function getElementValue(element) {
- var elementValue;
- runJavaScript("document.getElementById('" + element + "').value", function(result) {
- elementValue = result;
- });
- tryVerify(function() { return elementValue != undefined; });
- return elementValue;
- }
-
- function compareElementValue(element, expected) {
- tryVerify(function() { return expected == getElementValue(element); }, 5000,
- "Value of element \"" + element + "\" is \"" + expected + "\"");
- }
-
function test_keyboardEvents() {
webEngineView.url = Qt.resolvedUrl("keyboardEvents.html");
verify(webEngineView.waitForLoadSucceeded());
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
index f37cdf4b6..d0bc75619 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_linkHovered.qml b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
index a1343cbed..a11bd2450 100644
--- a/tests/auto/quick/qmltests/data/tst_linkHovered.qml
+++ b/tests/auto/quick/qmltests/data/tst_linkHovered.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml
index 73a3833e0..8e9224bbf 100644
--- a/tests/auto/quick/qmltests/data/tst_loadFail.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
index c4ed9ed3d..8f94cd4a2 100644
--- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadProgress.qml b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
index e4aa2d882..2c06a0207 100644
--- a/tests/auto/quick/qmltests/data/tst_loadProgress.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadProgress.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
index 9d8de0a5a..c0eb5932b 100644
--- a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
index c331fab6b..25a62c878 100644
--- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml
+++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
index d75298a68..c0c6a6967 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_mouseMove.qml b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
index 6afab7aae..5ded24c57 100644
--- a/tests/auto/quick/qmltests/data/tst_mouseMove.qml
+++ b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
index c7edb05ba..2ea76c387 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
index b3e247c44..31c0cf44e 100644
--- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
+++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 6e1ebc92e..68350d107 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -123,11 +98,10 @@ TestWebEngineView {
if (viewType === "dialog") {
tryVerify(dialog.webEngineView.loadSucceeded)
- compare(dialog.webEngineView.url, "");
+ compare(dialog.webEngineView.url, Qt.url("about:blank"));
dialog.destroy();
}
- // https://chromium-review.googlesource.com/c/chromium/src/+/1300395
- compare(newViewRequest.requestedUrl, 'about:blank#blocked');
+ compare(newViewRequest.requestedUrl, 'about:blank');
newViewRequestedSpy.clear();
// Open a page in a new dialog
diff --git a/tests/auto/quick/qmltests/data/tst_notification.qml b/tests/auto/quick/qmltests/data/tst_notification.qml
index 46a21ff4d..5d55e1201 100644
--- a/tests/auto/quick/qmltests/data/tst_notification.qml
+++ b/tests/auto/quick/qmltests/data/tst_notification.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_properties.qml b/tests/auto/quick/qmltests/data/tst_properties.qml
index 7ae218977..13d40ed11 100644
--- a/tests/auto/quick/qmltests/data/tst_properties.qml
+++ b/tests/auto/quick/qmltests/data/tst_properties.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
index 949e50bb7..f16cd9c41 100644
--- a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
+++ b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -59,8 +34,7 @@ TestWebEngineView {
compare(result, testTitle2);
callbackCalled = true;
});
- wait(100);
- verify(callbackCalled);
+ tryVerify(function() { return callbackCalled; });
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_save.qml b/tests/auto/quick/qmltests/data/tst_save.qml
new file mode 100644
index 000000000..3289dbd8b
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_save.qml
@@ -0,0 +1,185 @@
+import QtQuick
+import QtTest
+import QtWebEngine
+import Test.util
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 200
+ profile: testSaveProfile
+
+ property url downloadUrl: ""
+ property int totalBytes: 0
+ property int receivedBytes: 0
+ property string downloadDir: ""
+ property string downloadFileName: ""
+ property bool isSavePageDownload: false
+ property var downloadState: []
+ property int savePageFormat: WebEngineDownloadRequest.MimeHtmlSaveFormat;
+ property bool autoCancel: false
+
+ TempDir {
+ id: tempDir
+ }
+
+ SignalSpy {
+ id: downLoadRequestedSpy
+ target: testSaveProfile
+ signalName: "downloadRequested"
+ }
+
+ SignalSpy {
+ id: downloadFinishedSpy
+ target: testSaveProfile
+ signalName: "downloadFinished"
+ }
+
+ WebEngineProfile {
+ id: testSaveProfile
+
+ onDownloadRequested: function(download) {
+ downloadState.push(download.state)
+ downloadUrl = download.url
+ savePageFormat = download.savePageFormat
+ downloadDir = download.downloadDirectory;
+ downloadFileName = download.downloadFileName
+ isSavePageDownload = download.isSavePageDownload
+
+ if (autoCancel)
+ download.cancel()
+ }
+ onDownloadFinished: function(download) {
+ receivedBytes = download.receivedBytes
+ totalBytes = download.totalBytes
+ downloadState.push(download.state)
+ }
+ }
+
+ TestCase {
+ name: "WebEngineViewSave"
+
+ function verifyData() {
+ var isDataValid = false
+ webEngineView.runJavaScript("(function() {" +
+ "var title = document.title.toString();" +
+ "var body = document.body.innerText;" +
+ " return title === \"Test page 1\" && body.includes(\"Hello.\")" +
+ "})();", function(result) {
+ isDataValid = result;
+ });
+ tryVerify(function() { return isDataValid });
+ return isDataValid;
+ }
+
+ function init() {
+ downLoadRequestedSpy.clear()
+ downloadFinishedSpy.clear()
+ totalBytes = 0
+ receivedBytes = 0
+ downloadDir = ""
+ downloadFileName = ""
+ isSavePageDownload = false
+ downloadState = []
+ downloadUrl = ""
+ autoCancel = false
+ }
+
+ function test_savePage_data() {
+ return [
+ { tag: "SingleHtmlSaveFormat", savePageFormat: WebEngineDownloadRequest.SingleHtmlSaveFormat },
+ { tag: "CompleteHtmlSaveFormat", savePageFormat: WebEngineDownloadRequest.CompleteHtmlSaveFormat },
+ { tag: "MimeHtmlSaveFormat", savePageFormat: WebEngineDownloadRequest.MimeHtmlSaveFormat },
+ ];
+ }
+
+ function test_savePage(row) {
+ var saveFormat = row.savePageFormat
+
+ var fileDir = tempDir.path()
+ var fileName = "saved_page.html"
+ var filePath = fileDir + "/"+ fileName
+
+ // load data to view
+ webEngineView.url = Qt.resolvedUrl("test1.html")
+ verify(webEngineView.waitForLoadSucceeded())
+ verify(verifyData())
+
+ webEngineView.save(filePath, saveFormat)
+ downLoadRequestedSpy.wait()
+ compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(savePageFormat, saveFormat)
+ compare(downloadDir, fileDir)
+ compare(downloadFileName, fileName)
+ compare(isSavePageDownload, true)
+ compare(downloadState[0], WebEngineDownloadRequest.DownloadInProgress)
+ downloadFinishedSpy.wait()
+ compare(downloadFinishedSpy.count, 1)
+ compare(totalBytes, receivedBytes)
+ compare(downloadState[1], WebEngineDownloadRequest.DownloadCompleted)
+
+ // load some other data
+ webEngineView.url = Qt.resolvedUrl("about:blank")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ // load save file to view
+ webEngineView.url = Qt.resolvedUrl(filePath)
+ verify(webEngineView.waitForLoadSucceeded())
+ verify(verifyData())
+ }
+
+ function test_saveImage_data() {
+ return [
+ { tag: "Auto accept", autoCancel: false },
+ { tag: "Cancel", autoCancel: true },
+ ];
+ }
+
+ function test_saveImage(row) {
+ autoCancel = row.autoCancel
+
+ var fileDir = tempDir.path()
+ var fileName = "favicon.png"
+ var filePath = fileDir + "/"+ fileName
+
+ // Load an image
+ webEngineView.url = Qt.resolvedUrl("icons/favicon.png")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ webEngineView.save(filePath)
+ downLoadRequestedSpy.wait()
+ compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(downloadDir, fileDir)
+ compare(downloadFileName, fileName)
+ compare(isSavePageDownload, true)
+ compare(downloadState[0], WebEngineDownloadRequest.DownloadInProgress)
+ downloadFinishedSpy.wait()
+ compare(downloadFinishedSpy.count, 1)
+ if (autoCancel) {
+ compare(receivedBytes, 0)
+ compare(downloadState[1], WebEngineDownloadRequest.DownloadCancelled)
+ } else {
+ compare(totalBytes, receivedBytes)
+ compare(downloadState[1], WebEngineDownloadRequest.DownloadCompleted)
+ }
+ }
+
+ function test_saveWebAction() {
+ // Load an image
+ webEngineView.url = Qt.resolvedUrl("icons/favicon.png")
+ verify(webEngineView.waitForLoadSucceeded())
+
+ // Saving without specifying path shouldn't be auto accepted
+ webEngineView.triggerWebAction(WebEngineView.SavePage)
+ downLoadRequestedSpy.wait()
+ compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(isSavePageDownload, true)
+ // The initial download request starts from DownloadRequested state,
+ // which means it wasn't automatically accepted.
+ compare(downloadState[0], WebEngineDownloadRequest.DownloadRequested)
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_scrollPosition.qml b/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
index 22fa92b85..cc7d15e4c 100644
--- a/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
+++ b/tests/auto/quick/qmltests/data/tst_scrollPosition.qml
@@ -1,33 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
-import QtQuick.Window
import QtTest
import QtWebEngine
@@ -61,7 +35,7 @@ TestWebEngineView {
tryCompare(scrollPositionSpy, "count", 1);
compare(webEngineView.scrollPosition.x, 0);
- compare(webEngineView.scrollPosition.y, 600 * Screen.devicePixelRatio);
+ compare(webEngineView.scrollPosition.y, 600);
}
function test_scrollPositionAfterReload() {
@@ -74,13 +48,13 @@ TestWebEngineView {
// Wait for proper scroll position change otherwise we cannot expect
// the new y position after reload.
tryCompare(webEngineView.scrollPosition, "x", 0);
- tryCompare(webEngineView.scrollPosition, "y", 600 * Screen.devicePixelRatio);
+ tryCompare(webEngineView.scrollPosition, "y", 600);
webEngineView.reload();
verify(webEngineView.waitForLoadSucceeded());
tryCompare(webEngineView.scrollPosition, "x", 0);
- tryCompare(webEngineView.scrollPosition, "y", 600 * Screen.devicePixelRatio);
+ tryCompare(webEngineView.scrollPosition, "y", 600);
}
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml
index 07ce77a04..f47674aa7 100644
--- a/tests/auto/quick/qmltests/data/tst_settings.qml
+++ b/tests/auto/quick/qmltests/data/tst_settings.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -103,6 +78,68 @@ TestWebEngineView {
webEngineView2.destroy();
}
+
+ function test_disableReadingFromCanvas_data() {
+ return [
+ { tag: 'disabled', disableReadingFromCanvas: false, result: true },
+ { tag: 'enabled', disableReadingFromCanvas: true, result: false },
+ ]
+ }
+
+ function test_disableReadingFromCanvas(data) {
+ webEngineView.settings.readingFromCanvasEnabled = !data.disableReadingFromCanvas;
+ webEngineView.loadHtml("<html><body>" +
+ "<canvas id='myCanvas' width='200' height='40' style='border:1px solid #000000;'></canvas>" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ verify(webEngineView.settings.readingFromCanvasEnabled === !data.disableReadingFromCanvas )
+
+ var jsCode = "(function(){" +
+ " var canvas = document.getElementById(\"myCanvas\");" +
+ " var ctx = canvas.getContext(\"2d\");" +
+ " ctx.fillStyle = \"rgb(255,0,255)\";" +
+ " ctx.fillRect(0, 0, 200, 40);" +
+ " try {" +
+ " src = canvas.toDataURL();" +
+ " }" +
+ " catch(err) {" +
+ " src = \"\";" +
+ " }" +
+ " return src.length ? true : false;" +
+ "})();";
+
+ var isDataRead = false;
+ runJavaScript(jsCode, function(result) {
+ isDataRead = result
+ });
+ tryVerify(function() { return isDataRead === data.result });
+ }
+
+ function test_forceDarkMode() {
+ // based on: https://developer.chrome.com/blog/auto-dark-theme/#detecting-auto-dark-theme
+ webEngineView.loadHtml("<html><body>" +
+ "<div id=\"detection\", style=\"display: none; background-color: canvas; color-scheme: light\"</div>" +
+ "</body></html>");
+ const script = "(() => {"
+ + " const detectionDiv = document.querySelector('#detection');"
+ + " return getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';"
+ + "})()";
+ verify(webEngineView.waitForLoadSucceeded());
+
+ var isAutoDark = true;
+ runJavaScript(script, result => isAutoDark = result);
+ tryVerify(() => {return !isAutoDark});
+
+ webEngineView.settings.forceDarkMode = true;
+ verify(webEngineView.settings.forceDarkMode == true)
+
+ isAutoDark = false;
+ // the page is not updated immediately
+ tryVerify(function() {
+ runJavaScript(script, result => isAutoDark = result);
+ return isAutoDark;
+ });
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_titleChanged.qml b/tests/auto/quick/qmltests/data/tst_titleChanged.qml
index d73664b02..66a7c115f 100644
--- a/tests/auto/quick/qmltests/data/tst_titleChanged.qml
+++ b/tests/auto/quick/qmltests/data/tst_titleChanged.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
index c84d5da2b..76363fa71 100644
--- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
+++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
diff --git a/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml b/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml
new file mode 100644
index 000000000..94c993771
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_userScriptCollection.qml
@@ -0,0 +1,127 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtWebEngine
+
+Item {
+
+ WebEngineProfile { id: testProfile }
+
+ TestWebEngineView {
+ id: webEngineView
+ width: 400
+ height: 300
+ }
+
+ TestCase {
+ name: "UserScriptCollection"
+
+ function cleanup() {
+ webEngineView.url = ""
+ webEngineView.userScripts.collection = []
+ compare(webEngineView.userScripts.collection.length, 0)
+ }
+
+ function test_collection() {
+ let scriptFoo = { name: "Foo",
+ sourceUrl: Qt.resolvedUrl("foo.js"),
+ injectionPoint: WebEngineScript.DocumentReady
+ }
+ let scriptBar = WebEngine.script()
+
+ scriptBar.name = "Bar"
+ scriptBar.sourceUrl = Qt.resolvedUrl("bar.js")
+ scriptBar.injectionPoint = WebEngineScript.DocumentReady
+
+ compare(webEngineView.userScripts.collection.length, 0)
+ webEngineView.userScripts.collection = [ scriptFoo, scriptBar ]
+ compare(webEngineView.userScripts.collection.length, 2)
+ compare(webEngineView.userScripts.collection[0].name, scriptFoo.name)
+ compare(webEngineView.userScripts.collection[0].sourceUrl, scriptFoo.sourceUrl)
+ compare(webEngineView.userScripts.collection[1].name, scriptBar.name)
+ compare(webEngineView.userScripts.collection[1].sourceUrl, scriptBar.sourceUrl)
+ webEngineView.userScripts.collection = []
+ compare(webEngineView.userScripts.collection.length, 0)
+ }
+
+ function test_insert() {
+ let scriptFoo = WebEngine.script()
+ scriptFoo.name = "Foo"
+ scriptFoo.sourceUrl = Qt.resolvedUrl("foo.js")
+ scriptFoo.injectionPoint = WebEngineScript.DocumentReady
+ let scriptBar = WebEngine.script()
+ scriptBar.name = "Bar"
+ scriptBar.sourceUrl = Qt.resolvedUrl("bar.js")
+ scriptBar.injectionPoint = WebEngineScript.DocumentReady
+
+ compare(webEngineView.userScripts.collection.length, 0)
+ webEngineView.userScripts.insert(scriptFoo)
+ webEngineView.userScripts.insert(scriptBar)
+ compare(webEngineView.userScripts.collection.length, 2)
+ compare(webEngineView.userScripts.collection[0].name, scriptFoo.name)
+ compare(webEngineView.userScripts.collection[1].name, scriptBar.name)
+ webEngineView.userScripts.collection = []
+ compare(webEngineView.userScripts.collection.length, 0)
+
+ var list = [ scriptFoo , scriptBar]
+ webEngineView.userScripts.insert(list)
+ compare(webEngineView.userScripts.collection.length, 2)
+ compare(webEngineView.userScripts.collection[0].name, scriptFoo.name)
+ compare(webEngineView.userScripts.collection[1].name, scriptBar.name)
+ }
+
+ function test_find() {
+ let scriptA = WebEngine.script()
+ scriptA.name = "A"
+ scriptA.sourceUrl = Qt.resolvedUrl("A.js")
+ let scriptB = WebEngine.script()
+ scriptB.name = "A"
+ scriptB.sourceUrl = Qt.resolvedUrl("B.js")
+ let scriptC = WebEngine.script()
+ scriptC.name = "C"
+ scriptC.sourceUrl = Qt.resolvedUrl("C.js")
+
+ compare(webEngineView.userScripts.collection.length, 0)
+ webEngineView.userScripts.collection = [ scriptA, scriptB, scriptC ];
+ compare(webEngineView.userScripts.collection.length, 3)
+ let scriptsA = webEngineView.userScripts.find("A")
+ let scriptsB = webEngineView.userScripts.find("B")
+ let scriptsC = webEngineView.userScripts.find("C")
+ compare(scriptsA.length, 2)
+ compare(scriptsB.length, 0)
+ compare(scriptsC.length, 1)
+ compare(scriptsA[0].name, scriptA.name)
+ compare(scriptsA[0].sourceUrl, scriptA.sourceUrl)
+ compare(scriptsA[1].name, scriptB.name)
+ compare(scriptsA[1].sourceUrl, scriptB.sourceUrl)
+ compare(scriptsC[0].name, scriptC.name)
+ compare(scriptsC[0].sourceUrl, scriptC.sourceUrl)
+ }
+
+ function test_contains() {
+ let scriptFoo = WebEngine.script()
+ scriptFoo.name = "Foo"
+ let scriptBar = WebEngine.script()
+ scriptBar.name = "Bar"
+ compare(webEngineView.userScripts.collection.length, 0)
+ webEngineView.userScripts.collection = [ scriptFoo ]
+ compare(webEngineView.userScripts.collection.length, 1)
+ verify(webEngineView.userScripts.contains(scriptFoo))
+ verify(!webEngineView.userScripts.contains(scriptBar))
+ }
+
+ function test_clear() {
+ let scriptFoo = WebEngine.script()
+ scriptFoo.name = "Foo"
+ let scriptBar = WebEngine.script()
+ scriptBar.name = "Bar"
+ compare(webEngineView.userScripts.collection.length, 0)
+ webEngineView.userScripts.collection = [ scriptFoo ];
+ compare(webEngineView.userScripts.collection.length, 1)
+ webEngineView.userScripts.clear()
+ compare(webEngineView.userScripts.collection.length, 0)
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml
index 0f1042f80..30704f47b 100644
--- a/tests/auto/quick/qmltests/data/tst_userScripts.qml
+++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -60,6 +35,8 @@ Item {
return script
}
+ WebEngineProfile { id: testProfile }
+
TestWebEngineView {
id: webEngineView
width: 400
@@ -89,13 +66,28 @@ Item {
}
TestCase {
- name: "WebEngineViewUserScripts"
-
+ name: "UserScripts"
- function init() {
+ function cleanup() {
webEngineView.url = "";
webEngineView.userScripts.collection = [];
+ compare(webEngineView.userScripts.collection.length, 0)
webEngineView.profile.userScripts.collection = [];
+ compare(webEngineView.profile.userScripts.collection.length, 0)
+ }
+
+ function test_profileScripts() {
+ // assusme it is the same type as in View
+ let t1 = String(testProfile.userScripts), t2 = String(webEngineView.userScripts)
+ compare(t1.substr(0, t1.indexOf('(')), t2.substr(0, t2.indexOf('(')))
+
+ // ... and just test basic things like access
+ compare(testProfile.userScripts.collection, [])
+ let script = changeDocumentTitleScript()
+ testProfile.userScripts.collection = [ script ]
+
+ compare(testProfile.userScripts.collection.length, 1)
+ compare(testProfile.userScripts.collection[0].name, script.name)
}
function test_oneScript() {
@@ -103,8 +95,10 @@ Item {
webEngineView.waitForLoadSucceeded();
tryCompare(webEngineView, "title", "Test page 1");
- webEngineView.userScripts.collection = [ changeDocumentTitleScript() ]
-
+ let script = changeDocumentTitleScript()
+ webEngineView.userScripts.collection = [ script ]
+ compare(webEngineView.userScripts.collection.length, 1)
+ compare(webEngineView.userScripts.collection[0].name, script.name)
compare(webEngineView.title, "Test page 1");
webEngineView.reload();
@@ -116,6 +110,7 @@ Item {
tryCompare(webEngineView, "title", "New title");
webEngineView.userScripts.collection = [];
+ compare(webEngineView.userScripts.collection.length, 0)
compare(webEngineView.title, "New title");
webEngineView.reload();
@@ -131,6 +126,7 @@ Item {
var script2 = appendDocumentTitleScript();
script2.injectionPoint = WebEngineScript.Deferred;
webEngineView.userScripts.collection = [ script1, script2 ];
+ compare(webEngineView.userScripts.collection.length, 2)
// Make sure the scripts are loaded in order.
webEngineView.reload();
@@ -140,12 +136,14 @@ Item {
script2.injectionPoint = WebEngineScript.DocumentReady
script1.injectionPoint = WebEngineScript.Deferred
webEngineView.userScripts.collection = [ script1, script2 ];
+ compare(webEngineView.userScripts.collection.length, 2)
webEngineView.reload();
webEngineView.waitForLoadSucceeded();
tryCompare(webEngineView, "title", "New title");
// Make sure we can remove scripts from the preload list.
webEngineView.userScripts.collection = [ script2 ];
+ compare(webEngineView.userScripts.collection.length, 1)
webEngineView.reload();
webEngineView.waitForLoadSucceeded();
tryCompare(webEngineView, "title", "Test page 1 with appendix");
@@ -169,6 +167,7 @@ Item {
function test_bigScript() {
webEngineView.userScripts.collection = [ bigUserScript() ];
+ compare(webEngineView.userScripts.collection.length, 1)
webEngineView.url = Qt.resolvedUrl("test1.html");
webEngineView.waitForLoadSucceeded();
tryCompare(webEngineView , "title", "Big user script changed title");
@@ -180,6 +179,8 @@ Item {
compare(script.injectionPoint, WebEngineScript.DocumentReady);
webEngineView.userScripts.collection = [ script ];
+ compare(webEngineView.userScripts.collection.length, 1)
+ compare(webEngineView.userScripts.collection[0].name, script.name)
// @include *data/test*.html
webEngineView.url = Qt.resolvedUrl("test1.html");
@@ -208,6 +209,7 @@ Item {
compare(script.injectionPoint, WebEngineScript.DocumentReady);
webEngineView.userScripts.collection = [ script ];
+ compare(webEngineView.userScripts.collection.length, 1)
// @match some:junk
webEngineView.url = Qt.resolvedUrl("test2.html");
@@ -216,7 +218,10 @@ Item {
}
function test_profileWideScript() {
- webEngineView.profile.userScripts.collection = [ changeDocumentTitleScript() ];
+ let script = changeDocumentTitleScript()
+ webEngineView.profile.userScripts.collection = [ script ];
+ compare(webEngineView.profile.userScripts.collection.length, 1)
+ compare(webEngineView.profile.userScripts.collection[0].name, script.name)
webEngineView.url = Qt.resolvedUrl("test1.html");
webEngineView.waitForLoadSucceeded();
diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml
index d6377cdad..d4449f7de 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSource.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -147,7 +122,7 @@ TestWebEngineView {
WebEngine.settings.errorPageEnabled = true
webEngineView.url = row.userInputUrl;
- tryCompare(loadSpy, 'count', 2);
+ tryCompare(loadSpy, 'count', 2, 12000);
let load = loadSpy.signalArguments[1][0]
let expectedStatus = row.loadSucceed ? WebEngineView.LoadSucceededStatus : WebEngineView.LoadFailedStatus
compare(load.status, expectedStatus);
diff --git a/tests/auto/quick/qmltests/data/tst_webchannel.qml b/tests/auto/quick/qmltests/data/tst_webchannel.qml
index 70edc1bcd..780b55934 100644
--- a/tests/auto/quick/qmltests/data/tst_webchannel.qml
+++ b/tests/auto/quick/qmltests/data/tst_webchannel.qml
@@ -1,29 +1,5 @@
-/*********************************************************************
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtTest
@@ -81,6 +57,12 @@ Item {
}
function test_basic() {
+ webView.userScripts.collection = [ {
+ name: "qtwebchanneljs",
+ sourceUrl: Qt.resolvedUrl("qrc:/qtwebchannel/qwebchannel.js"),
+ injectionPoint: WebEngineScript.DocumentCreation,
+ worldId: WebEngineScript.MainWorld
+ }]
webView.url = testUrl;
verify(webView.waitForLoadSucceeded());
diff --git a/tests/auto/quick/qmltests/data/webchannel-test.html b/tests/auto/quick/qmltests/data/webchannel-test.html
index 92966b24a..d8c3b1305 100644
--- a/tests/auto/quick/qmltests/data/webchannel-test.html
+++ b/tests/auto/quick/qmltests/data/webchannel-test.html
@@ -2,7 +2,6 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script type="text/javascript">
//BEGIN SETUP
var channel = new QWebChannel(qt.webChannelTransport, function(channel) {
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml
index 252678754..7d7efda0c 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/AlertDialog.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// Both dialogs are basically expected to behave in the same way from an API point of view
ConfirmDialog { }
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml
index c4d3dd183..6125d0b98 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/ConfirmDialog.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQml
import QtTest
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml
new file mode 100644
index 000000000..71da28843
--- /dev/null
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/DirectoryPicker.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import "../../TestParams"
+
+QtObject {
+ signal folderSelected(var folder)
+ signal rejected()
+
+ function open() {
+ FilePickerParams.directoryPickerOpened = true;
+ if (FilePickerParams.selectFiles)
+ folderSelected(FilePickerParams.selectedFilesUrl);
+ else
+ rejected();
+ }
+}
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml
index 0ba92f5ce..247088bcb 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/FilePicker.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import "../../TestParams"
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml
index aa03a9d30..cd7ed4821 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/Menu.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQml
import "../../TestParams"
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml
index dcc1ca4b6..67dab1bba 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/MenuItem.qml
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQml
diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml
index 800481797..81a63d918 100644
--- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/ControlsDelegates/PromptDialog.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQml
import QtTest
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
index 48f94df60..67d67dc40 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
pragma Singleton
import QtQuick
@@ -33,5 +8,6 @@ QtObject {
property var selectedFilesUrl: [];
property bool selectFiles: false;
property bool filePickerOpened: false;
+ property bool directoryPickerOpened: false;
property var nameFilters: [];
}
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml
index b24214a2e..1033b509e 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/JSDialogParams.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
pragma Singleton
import QtQml
diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml
index 952eb5ebe..d8a01764c 100644
--- a/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml
+++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/MenuParams.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
pragma Singleton
import QtQml
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index 00c6478e9..9e928157e 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <httpserver.h>
@@ -130,11 +105,18 @@ public:
return tempDir.isValid() ? tempDir.path() : QString();
}
+ Q_INVOKABLE QUrl pathUrl(const QString &filename = QString())
+ {
+ Q_ASSERT(tempDir.isValid());
+ return filename.isEmpty() ? QUrl::fromLocalFile(tempDir.path())
+ : QUrl::fromLocalFile(tempDir.filePath(filename));
+ }
+
Q_INVOKABLE void removeRecursive(const QString dirname)
{
QDir dir(dirname);
QFileInfoList entries(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
- for (int i = 0; i < entries.count(); ++i) {
+ for (int i = 0; i < entries.size(); ++i) {
if (entries[i].isDir())
removeRecursive(entries[i].filePath());
else
@@ -143,6 +125,8 @@ public:
QDir().rmdir(dirname);
}
+ Q_INVOKABLE void createDirectory(const QString dirname) { QDir(tempDir.path()).mkdir(dirname); }
+
private:
QTemporaryDir tempDir;
};
@@ -251,22 +235,17 @@ int main(int argc, char **argv)
sigaction(SIGSEGV, &sigAction, 0);
#endif
- QScopedPointer<Application> app;
+ QtWebEngineQuick::initialize();
// Force to use English language for testing due to error message checks
QLocale::setDefault(QLocale("en"));
- static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
- QList<const char *> w_argv(argc); \
- for (int i = 0; i < argc; ++i) \
- w_argv[i] = argv[i]; \
- for (int i = 0; i < params.size(); ++i) \
- w_argv.append(params[i].data()); \
- int w_argc = w_argv.size(); \
+ static QByteArrayList params = {QByteArrayLiteral("--webEngineArgs"),QByteArrayLiteral("--use-fake-device-for-media-stream")};
+ QList<const char *> w_argv(argc);
+ for (int i = 0; i < argc; ++i) w_argv[i] = argv[i];
+ for (int i = 0; i < params.size(); ++i) w_argv.append(params[i].data());
+ int w_argc = w_argv.size();
+ Application app(w_argc, const_cast<char **>(w_argv.data()));
- if (!QCoreApplication::instance()) {
- app.reset(new Application(w_argc, const_cast<char **>(w_argv.data())));
- }
- QtWebEngineQuick::initialize();
QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true);
qmlRegisterType<TempDir>("Test.util", 1, 0, "TempDir");
qmlRegisterType<TestInputContext>("Test.util", 1, 0, "TestInputContext");
@@ -283,8 +262,9 @@ int main(int argc, char **argv)
#if QT_CONFIG(ssl)
qmlRegisterSingletonType<HttpsServer>(
- "Test.Shared", 1, 0, "HttpsServer",
- [&](QQmlEngine *, QJSEngine *) { return new HttpsServer(":/resources/server.pem",":/resources/server.key"); });
+ "Test.Shared", 1, 0, "HttpsServer", [&](QQmlEngine *, QJSEngine *) {
+ return new HttpsServer(":/resources/server.pem", ":/resources/server.key", "");
+ });
#endif
Setup setup;
int i = quick_test_main_with_setup(
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt
index 07b184b89..9856ed513 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qquickwebenginedefaultsurfaceformat
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
index 7b993d006..b4c95d671 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "testwindow.h"
#include "quickutil.h"
diff --git a/tests/auto/quick/qquickwebengineview/CMakeLists.txt b/tests/auto/quick/qquickwebengineview/CMakeLists.txt
index b0488048f..307ea36c9 100644
--- a/tests/auto/quick/qquickwebengineview/CMakeLists.txt
+++ b/tests/auto/quick/qquickwebengineview/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qquickwebengineview
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 347f370f7..dbfa1cb33 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -1,33 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#include "testwindow.h"
#include "quickutil.h"
+#include "util.h"
#include <QScopedPointer>
#include <QtCore/qelapsedtimer.h>
@@ -41,6 +19,7 @@
#include <QtGui/private/qinputmethod_p.h>
#include <QtWebEngineQuick/private/qquickwebenginescriptcollection_p.h>
#include <QtWebEngineQuick/private/qquickwebenginesettings_p.h>
+#include <QtWebEngineQuick/private/qquickwebenginedownloadrequest_p.h>
#include <QtWebEngineQuick/private/qquickwebengineview_p.h>
#include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
#include <qpa/qplatforminputcontext.h>
@@ -94,8 +73,13 @@ private Q_SLOTS:
void javascriptClipboard_data();
void javascriptClipboard();
void setProfile();
- void focusChild();
+#if QT_CONFIG(accessibility)
void focusChild_data();
+ void focusChild();
+#endif
+ void htmlSelectPopup();
+ void savePage_data();
+ void savePage();
private:
inline QQuickWebEngineView *newWebEngineView();
@@ -105,6 +89,11 @@ private:
QString m_testSourceDirPath;
QScopedPointer<TestWindow> m_window;
QScopedPointer<QQmlComponent> m_component;
+
+ QPointingDevice *touchDevice() {
+ static auto d = QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
+ return d.get();
+ }
};
tst_QQuickWebEngineView::tst_QQuickWebEngineView()
@@ -442,10 +431,10 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
for (int i = 0; i < image.width(); i++)
for (int j = 0; j < image.height(); j++)
colors.insert(image.pixel(i, j));
- return colors.count() > 1;
+ return colors.size() > 1;
});
- QVERIFY(colors.count() > 1);
+ QVERIFY(colors.size() > 1);
QVERIFY(colors.contains(qRgb(0, 0, 0))); // black
QVERIFY(colors.contains(qRgb(255, 0, 0))); // red
for (auto color : colors) {
@@ -457,7 +446,6 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
void tst_QQuickWebEngineView::inputMethod()
{
m_window->show();
- QTRY_VERIFY(qApp->focusObject());
QQuickItem *input;
QQuickWebEngineView *view = webEngineView();
@@ -465,18 +453,21 @@ void tst_QQuickWebEngineView::inputMethod()
view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
+ QTRY_VERIFY(qobject_cast<QQuickItem *>(qApp->focusObject()));
input = qobject_cast<QQuickItem *>(qApp->focusObject());
QVERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
runJavaScript("document.getElementById('inputField').focus();");
QTRY_COMPARE(activeElementId(view), QStringLiteral("inputField"));
+ QTRY_VERIFY(qobject_cast<QQuickItem *>(qApp->focusObject()));
input = qobject_cast<QQuickItem *>(qApp->focusObject());
QTRY_VERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
runJavaScript("document.getElementById('inputField').blur();");
QTRY_VERIFY(activeElementId(view).isEmpty());
+ QTRY_VERIFY(qobject_cast<QQuickItem *>(qApp->focusObject()));
input = qobject_cast<QQuickItem *>(qApp->focusObject());
QTRY_VERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
@@ -587,9 +578,8 @@ void tst_QQuickWebEngineView::interruptImeTextComposition()
QTest::mouseClick(view->window(), Qt::LeftButton, {}, textInputCenter);
} else if (eventType == "Touch") {
QPoint textInputCenter = elementCenter(view, QStringLiteral("input2"));
- QPointingDevice *touchDevice = QTest::createTouchDevice();
- QTest::touchEvent(view->window(), touchDevice).press(0, textInputCenter, view->window());
- QTest::touchEvent(view->window(), touchDevice).release(0, textInputCenter, view->window());
+ QTest::touchEvent(view->window(), touchDevice()).press(0, textInputCenter, view->window());
+ QTest::touchEvent(view->window(), touchDevice()).release(0, textInputCenter, view->window());
}
QTRY_COMPARE(evaluateJavaScriptSync(view, "document.activeElement.id").toString(), QStringLiteral("input2"));
#ifndef Q_OS_WIN
@@ -617,12 +607,12 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
" <input type='text' id='input1' />"
"</body></html>");
QVERIFY(waitForLoadSucceeded(view));
- QCOMPARE(testContext.infos.count(), 0);
+ QCOMPARE(testContext.infos.size(), 0);
// Set focus on an input field.
QPoint textInputCenter = elementCenter(view, "input1");
QTest::mouseClick(view->window(), Qt::LeftButton, {}, textInputCenter);
- QTRY_COMPARE(testContext.infos.count(), 2);
+ QTRY_COMPARE(testContext.infos.size(), 2);
QCOMPARE(evaluateJavaScriptSync(view, "document.activeElement.id").toString(), QStringLiteral("input1"));
foreach (const InputMethodInfo &info, testContext.infos) {
QCOMPARE(info.cursorPosition, 0);
@@ -634,7 +624,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
// Change content of an input field from JavaScript.
evaluateJavaScriptSync(view, "document.getElementById('input1').value='QtWebEngine';");
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 11);
QCOMPARE(testContext.infos[0].anchorPosition, 11);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine"));
@@ -643,7 +633,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
// Change content of an input field by key press.
QTest::keyClick(view->window(), Qt::Key_Exclam);
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 12);
QCOMPARE(testContext.infos[0].anchorPosition, 12);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
@@ -652,7 +642,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
// Change cursor position.
QTest::keyClick(view->window(), Qt::Key_Left);
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 11);
QCOMPARE(testContext.infos[0].anchorPosition, 11);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
@@ -667,7 +657,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
QInputMethodEvent event("", attributes);
QGuiApplication::sendEvent(qApp->focusObject(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 2);
+ QTRY_COMPARE(testContext.infos.size(), 2);
// As a first step, Chromium moves the cursor to the start of the selection.
// We don't filter this in QtWebEngine because we don't know yet if this is part of a selection.
@@ -691,7 +681,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
QInputMethodEvent event("", attributes);
QGuiApplication::sendEvent(qApp->focusObject(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 0);
QCOMPARE(testContext.infos[0].anchorPosition, 0);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
@@ -704,9 +694,9 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
QInputMethodEvent event("123", attributes);
QGuiApplication::sendEvent(qApp->focusObject(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 1);
- QCOMPARE(testContext.infos[0].cursorPosition, 3);
- QCOMPARE(testContext.infos[0].anchorPosition, 3);
+ QTRY_COMPARE(testContext.infos.size(), 1);
+ QCOMPARE(testContext.infos[0].cursorPosition, 0);
+ QCOMPARE(testContext.infos[0].anchorPosition, 0);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
QCOMPARE(testContext.infos[0].selectedText, QStringLiteral(""));
QCOMPARE(evaluateJavaScriptSync(view, "document.getElementById('input1').value").toString(), QStringLiteral("123QtWebEngine!"));
@@ -718,7 +708,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
QInputMethodEvent event("", attributes);
QGuiApplication::sendEvent(qApp->focusObject(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 2);
+ QTRY_COMPARE(testContext.infos.size(), 2);
foreach (const InputMethodInfo &info, testContext.infos) {
QCOMPARE(info.cursorPosition, 0);
QCOMPARE(info.anchorPosition, 0);
@@ -735,7 +725,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
event.setCommitString(QStringLiteral("123"), 0, 0);
QGuiApplication::sendEvent(qApp->focusObject(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 3);
QCOMPARE(testContext.infos[0].anchorPosition, 3);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("123QtWebEngine!"));
@@ -745,7 +735,7 @@ void tst_QQuickWebEngineView::inputContextQueryInput()
// Focus out.
QTest::keyPress(view->window(), Qt::Key_Tab);
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QTRY_COMPARE(evaluateJavaScriptSync(view, "document.activeElement.id").toString(), QStringLiteral(""));
testContext.infos.clear();
}
@@ -802,20 +792,44 @@ void tst_QQuickWebEngineView::inputMethodHints()
void tst_QQuickWebEngineView::setZoomFactor()
{
QQuickWebEngineView *view = webEngineView();
+ m_window->show();
+ view->setSize(QSizeF(320, 240));
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 1.0));
+ QCOMPARE(view->zoomFactor(), 1.0);
view->setZoomFactor(2.5);
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
- view->setUrl(urlFromTestPath("html/basic_page.html"));
+ const QUrl url1 = urlFromTestPath("html/basic_page.html"), url2 = urlFromTestPath("html/basic_page2.html");
+
+ view->setUrl(url1);
QVERIFY(waitForLoadSucceeded(view));
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
view->setZoomFactor(0.1);
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
view->setZoomFactor(5.5);
- QVERIFY(qFuzzyCompare(view->zoomFactor(), 2.5));
+ QCOMPARE(view->zoomFactor(), 2.5);
+
+ QScopedPointer<QQuickWebEngineView> view2(newWebEngineView());
+ view2->setSize(QSizeF(320, 240));
+ view2->setParentItem(m_window->contentItem());
+
+ // try loading different url and check new values after load
+ for (auto &&p : {
+ qMakePair(view, 2.5), // navigating away to different url should keep zoom
+ qMakePair(view2.get(), 1.0), // same url navigation in diffent page shouldn't be affected
+ }) {
+ auto &&view = p.first; auto zoomFactor = p.second;
+ view->setUrl(url2);
+ QVERIFY(waitForLoadSucceeded(view));
+ QCOMPARE(view->zoomFactor(), zoomFactor);
+ }
+
+ // should have no influence on first page
+ view2->setZoomFactor(3.5);
+ for (auto &&p : { qMakePair(view, 2.5), qMakePair(view2.get(), 3.5), })
+ QCOMPARE(p.first->zoomFactor(), p.second);
}
void tst_QQuickWebEngineView::printToPdf()
@@ -832,7 +846,7 @@ void tst_QQuickWebEngineView::printToPdf()
QSignalSpy savePdfSpy(view, SIGNAL(pdfPrintingFinished(const QString&, bool)));
QString path = tempDir.path() + "/print_success.pdf";
view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait);
- QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal");
+ QTRY_VERIFY2(savePdfSpy.size() == 1, "Printing to PDF file failed without signal");
QList<QVariant> successArguments = savePdfSpy.takeFirst();
QVERIFY2(successArguments.at(0).toString() == path, "File path for first saved PDF does not match arguments");
QVERIFY2(successArguments.at(1).toBool() == true, "Printing to PDF file failed though it should succeed");
@@ -843,7 +857,7 @@ void tst_QQuickWebEngineView::printToPdf()
path = tempDir.path() + "/print_|fail.pdf";
#endif // #if !defined(Q_OS_WIN)
view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait);
- QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal");
+ QTRY_VERIFY2(savePdfSpy.size() == 1, "Printing to PDF file failed without signal");
QList<QVariant> failedArguments = savePdfSpy.takeFirst();
QVERIFY2(failedArguments.at(0).toString() == path, "File path for second saved PDF does not match arguments");
QVERIFY2(failedArguments.at(1).toBool() == false, "Printing to PDF file succeeded though it should fail");
@@ -987,11 +1001,9 @@ void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPress
QTest::mousePress(view->window(), Qt::LeftButton);
QTest::mouseRelease(view->window(), Qt::LeftButton);
- QPointingDevice *device = QTest::createTouchDevice();
-
- QTest::touchEvent(view->window(), device).press(0, QPoint(0,0), view->window());
- QTest::touchEvent(view->window(), device).move(0, QPoint(1, 1), view->window());
- QTest::touchEvent(view->window(), device).release(0, QPoint(1, 1), view->window());
+ QTest::touchEvent(view->window(), touchDevice()).press(0, QPoint(0,0), view->window());
+ QTest::touchEvent(view->window(), touchDevice()).move(0, QPoint(1, 1), view->window());
+ QTest::touchEvent(view->window(), touchDevice()).release(0, QPoint(1, 1), view->window());
// We expect to catch 7 events - click = 2, press + release = 2, touches = 3.
QCOMPARE(item.eventCount(), 7);
@@ -1113,7 +1125,7 @@ void tst_QQuickWebEngineView::javascriptClipboard()
// - return value of queryCommandEnabled and
// - return value of execCommand
// - comparing the clipboard / input field
- QGuiApplication::clipboard()->clear();
+ QGuiApplication::clipboard()->setText(QString());
QCOMPARE(evaluateJavaScriptSync(view, "document.queryCommandEnabled('copy')").toBool(),
copyResult);
QCOMPARE(evaluateJavaScriptSync(view, "document.execCommand('copy')").toBool(), copyResult);
@@ -1140,9 +1152,9 @@ void tst_QQuickWebEngineView::javascriptClipboard()
"if (result.state == 'prompt') accessPrompt = true;"
"})"));
- QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), copyResult);
- QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), !javascriptCanAccessClipboard);
- QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), false);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), javascriptCanAccessClipboard && javascriptCanPaste);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), false);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), !javascriptCanAccessClipboard || !javascriptCanPaste);
evaluateJavaScriptSync(view,
QStringLiteral(
@@ -1156,9 +1168,9 @@ void tst_QQuickWebEngineView::javascriptClipboard()
"if (result.state == 'prompt') accessPrompt = true;"
"})"));
- QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), pasteResult);
- QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), !javascriptCanAccessClipboard || !javascriptCanPaste);
- QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), false);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), javascriptCanAccessClipboard && javascriptCanPaste);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), false);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), !javascriptCanAccessClipboard || !javascriptCanPaste);
}
void tst_QQuickWebEngineView::setProfile() {
@@ -1170,10 +1182,13 @@ void tst_QQuickWebEngineView::setProfile() {
QVERIFY(waitForLoadSucceeded(webEngineView()));
QCOMPARE(loadSpy.size(), 4);
QQuickWebEngineProfile *profile = new QQuickWebEngineProfile();
+ auto oldProfile = webEngineView()->profile();
+ auto sc = qScopeGuard([&] () { webEngineView()->setProfile(oldProfile); delete profile; });
webEngineView()->setProfile(profile);
QTRY_COMPARE(webEngineView()->url() ,urlFromTestPath("html/basic_page2.html"));
}
+#if QT_CONFIG(accessibility)
void tst_QQuickWebEngineView::focusChild_data()
{
QTest::addColumn<QString>("interfaceName");
@@ -1236,9 +1251,121 @@ void tst_QQuickWebEngineView::focusChild()
// <html> -> <body> -> <input>
QCOMPARE(traverseToWebDocumentAccessibleInterface(iface)->child(0)->child(0), iface->focusChild());
}
+#endif // QT_CONFIG(accessibility)
+
+void tst_QQuickWebEngineView::htmlSelectPopup()
+{
+ m_window->show();
+ QQuickWebEngineView &view = *webEngineView();
+ view.settings()->setFocusOnNavigationEnabled(true);
+ view.setSize(QSizeF(640, 480));
+ view.loadHtml("<html><body>"
+ "<select id='select' onchange='console.log(\"option changed to: \" + this.value)'>"
+ "<option value='O1'>O1</option><option value='O2'>O2</option><option value='O3'>O3</option></select>"
+ "</body></html>");
+ QVERIFY(waitForLoadSucceeded(&view));
+
+ auto makeTouch = [this] (QWindow *w, const QPoint &p) {
+ QTest::touchEvent(w, touchDevice()).press(1, p);
+ QTest::touchEvent(w, touchDevice()).release(1, p);
+ };
+ makeTouch(view.window(), elementCenter(&view, "select"));
+ QPointer<QQuickWindow> popup;
+ QTRY_VERIFY((popup = m_window->findChild<QQuickWindow *>()));
+ QCOMPARE(activeElementId(&view), QStringLiteral("select"));
+
+ makeTouch(popup, QPoint(popup->width() / 2, popup->height() / 2));
+ QTRY_VERIFY(!popup);
+ QCOMPARE(evaluateJavaScriptSync(&view, "document.getElementById('select').value").toString(), QStringLiteral("O2"));
+}
+
+void tst_QQuickWebEngineView::savePage_data()
+{
+ QTest::addColumn<QWebEngineDownloadRequest::SavePageFormat>("savePageFormat");
+
+ QTest::newRow("SingleHtmlSaveFormat") << QWebEngineDownloadRequest::SingleHtmlSaveFormat;
+ QTest::newRow("CompleteHtmlSaveFormat") << QWebEngineDownloadRequest::CompleteHtmlSaveFormat;
+ QTest::newRow("MimeHtmlSaveFormat") << QWebEngineDownloadRequest::MimeHtmlSaveFormat;
+}
+
+void tst_QQuickWebEngineView::savePage()
+{
+ QFETCH(QWebEngineDownloadRequest::SavePageFormat, savePageFormat);
+
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_QQuickWebEngineView-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ const QString filePath = tempDir.path() + "/saved_page.html";
+
+ QQuickWebEngineView *view = webEngineView();
+ int acceptedCount = 0;
+ int finishedCount = 0;
+ ScopedConnection sc1 = connect(
+ view->profile(), &QQuickWebEngineProfile::downloadRequested,
+ [&](QQuickWebEngineDownloadRequest *downloadRequest) {
+ QCOMPARE(downloadRequest->state(),
+ QQuickWebEngineDownloadRequest::DownloadInProgress);
+ QCOMPARE(downloadRequest->isSavePageDownload(), true);
+ QCOMPARE(downloadRequest->savePageFormat(), savePageFormat);
+ QCOMPARE(QDir(downloadRequest->downloadDirectory())
+ .filePath(downloadRequest->downloadFileName()),
+ filePath);
+ QCOMPARE(downloadRequest->url(), view->url());
+
+ connect(downloadRequest, &QQuickWebEngineDownloadRequest::isFinishedChanged,
+ [&, downloadRequest]() {
+ QCOMPARE(downloadRequest->state(),
+ QQuickWebEngineDownloadRequest::DownloadCompleted);
+ QCOMPARE(downloadRequest->isSavePageDownload(), true);
+ QCOMPARE(downloadRequest->isFinished(), true);
+ QCOMPARE(downloadRequest->savePageFormat(), savePageFormat);
+ QCOMPARE(downloadRequest->totalBytes(),
+ downloadRequest->receivedBytes());
+ QVERIFY(downloadRequest->receivedBytes() > 0);
+ QCOMPARE(QDir(downloadRequest->downloadDirectory())
+ .filePath(downloadRequest->downloadFileName()),
+ filePath);
+ QCOMPARE(downloadRequest->url(), view->url());
+ finishedCount++;
+ });
+ acceptedCount++;
+ });
+
+ const QString originalData = QStringLiteral("Basic page");
+ view->setUrl(urlFromTestPath("html/basic_page.html"));
+ QVERIFY(waitForLoadSucceeded(view));
+ QCOMPARE(evaluateJavaScriptSync(view, "document.getElementsByTagName('h1')[0].innerText")
+ .toString(),
+ originalData);
+
+ // Save the loaded page as HTML.
+ view->save(filePath, savePageFormat);
+ QTRY_COMPARE(acceptedCount, 1);
+ QTRY_COMPARE(finishedCount, 1);
+ QFile file(filePath);
+ QVERIFY(file.exists());
+
+ // Load something else.
+ view->setUrl(urlFromTestPath("html/basic_page2.html"));
+ QVERIFY(waitForLoadSucceeded(view));
+ QVERIFY(evaluateJavaScriptSync(view, "document.getElementsByTagName('h1')[0].innerText")
+ .toString()
+ != originalData);
+
+ // Load the saved page and compare the contents.
+ view->setUrl(QUrl::fromLocalFile(filePath));
+ QVERIFY(waitForLoadSucceeded(view));
+ QCOMPARE(evaluateJavaScriptSync(view, "document.getElementsByTagName('h1')[0].innerText")
+ .toString(),
+ originalData);
+}
+
+#if QT_CONFIG(accessibility)
static QByteArrayList params = QByteArrayList()
<< "--force-renderer-accessibility";
+#else
+static QByteArrayList params;
+#endif
W_QTEST_MAIN(tst_QQuickWebEngineView, params)
#include "tst_qquickwebengineview.moc"
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt b/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt
index 6bc0bc866..f22408d15 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt
+++ b/tests/auto/quick/qquickwebengineviewgraphics/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qquickwebengineviewgraphics
SOURCES
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
index cfd058159..3644ac481 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
+++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <quickutil.h>
#include <QtTest/QtTest>
@@ -97,6 +72,8 @@ static void verifyGreenSquare(QQuickWindow *window)
bool ok = QTest::qWaitFor([&](){
actual = window->grabWindow();
expected = getGreenSquare(actual.format());
+ if (actual.height() > 150)
+ actual = actual.scaledToHeight(150);
return actual == expected;
}, 10000);
if (!ok) {
@@ -109,7 +86,9 @@ static void verifyGreenSquare(QQuickWindow *window)
void tst_QQuickWebEngineViewGraphics::simpleGraphics()
{
setHtml(greenSquare);
+ m_view->show();
verifyGreenSquare(m_view.data());
+ m_view->hide();
}
void tst_QQuickWebEngineViewGraphics::showHideShow()
@@ -125,12 +104,15 @@ void tst_QQuickWebEngineViewGraphics::showHideShow()
m_view->show();
QVERIFY(exposeSpy.wait());
verifyGreenSquare(m_view.data());
+ m_view->hide();
}
void tst_QQuickWebEngineViewGraphics::simpleAcceleratedLayer()
{
+ m_view->show();
setHtml(acLayerGreenSquare);
verifyGreenSquare(m_view.data());
+ m_view->hide();
}
void tst_QQuickWebEngineViewGraphics::reparentToOtherWindow()
@@ -141,6 +123,8 @@ void tst_QQuickWebEngineViewGraphics::reparentToOtherWindow()
window.create();
m_view->rootObject()->setParentItem(window.contentItem());
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
verifyGreenSquare(&window);
}
diff --git a/tests/auto/quick/qtbug-70248/CMakeLists.txt b/tests/auto/quick/qtbug-70248/CMakeLists.txt
index b1df50211..b177c5309 100644
--- a/tests/auto/quick/qtbug-70248/CMakeLists.txt
+++ b/tests/auto/quick/qtbug-70248/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_qtbug-70248
SOURCES
tst_qtbug-70248.cpp
diff --git a/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp b/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
index 6f48c957f..cf5c187c3 100644
--- a/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
+++ b/tests/auto/quick/qtbug-70248/tst_qtbug-70248.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qtwebenginequickglobal.h"
#include <QQuickWebEngineProfile>
diff --git a/tests/auto/quick/uidelegates/CMakeLists.txt b/tests/auto/quick/uidelegates/CMakeLists.txt
index d8699ccfc..bdf041e04 100644
--- a/tests/auto/quick/uidelegates/CMakeLists.txt
+++ b/tests/auto/quick/uidelegates/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/quick/uidelegates/tst_uidelegates.cpp b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
index 4c2fa3b3c..fb8734f83 100644
--- a/tests/auto/quick/uidelegates/tst_uidelegates.cpp
+++ b/tests/auto/quick/uidelegates/tst_uidelegates.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "testwindow.h"
#include "quickutil.h"
diff --git a/tests/auto/util/CMakeLists.txt b/tests/auto/util/CMakeLists.txt
index fa2f84cec..0af0e5032 100644
--- a/tests/auto/util/CMakeLists.txt
+++ b/tests/auto/util/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(minimal LANGUAGES CXX)
diff --git a/tests/auto/util/qt_webengine_quicktest.h b/tests/auto/util/qt_webengine_quicktest.h
index 0428783bf..bd98693de 100644
--- a/tests/auto/util/qt_webengine_quicktest.h
+++ b/tests/auto/util/qt_webengine_quicktest.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef QT_WEBENGINE_QUICKTEST_H
#define QT_WEBENGINE_QUICKTEST_H
diff --git a/tests/auto/util/quickutil.h b/tests/auto/util/quickutil.h
index 323fe3df4..687cb94dc 100644
--- a/tests/auto/util/quickutil.h
+++ b/tests/auto/util/quickutil.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef UTIL_H
#define UTIL_H
@@ -138,7 +113,7 @@ inline QPoint elementCenter(QQuickWebEngineView *view, const QString &id)
"})()");
QVariantList rectList = evaluateJavaScriptSync(view, jsCode).toList();
- if (rectList.count() != 2) {
+ if (rectList.size() != 2) {
qWarning("elementCenter failed.");
return QPoint();
}
@@ -172,10 +147,11 @@ inline QString activeElementId(QQuickWebEngineView *webEngineView)
int main(int argc, char *argv[]) \
{ \
QtWebEngineQuick::initialize(); \
- \
QList<const char *> w_argv(argc); \
+ QLatin1String arg("--webEngineArgs"); \
for (int i = 0; i < argc; ++i) \
w_argv[i] = argv[i]; \
+ w_argv.append(arg.data()); \
for (int i = 0; i < params.size(); ++i) \
w_argv.append(params[i].data()); \
int w_argc = w_argv.size(); \
diff --git a/tests/auto/util/testwindow.h b/tests/auto/util/testwindow.h
index 958381ff2..f9ffd381a 100644
--- a/tests/auto/util/testwindow.h
+++ b/tests/auto/util/testwindow.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTWINDOW_H
#define TESTWINDOW_H
diff --git a/tests/auto/util/util.cmake b/tests/auto/util/util.cmake
index 84d7f593f..e5142d0b2 100644
--- a/tests/auto/util/util.cmake
+++ b/tests/auto/util/util.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (NOT TARGET Test::Util)
add_library(qtestutil INTERFACE)
target_include_directories(qtestutil INTERFACE ${CMAKE_CURRENT_LIST_DIR})
diff --git a/tests/auto/util/util.h b/tests/auto/util/util.h
index a624a978f..5533eed80 100644
--- a/tests/auto/util/util.h
+++ b/tests/auto/util/util.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// Functions and macros that really need to be in QTestLib
@@ -33,6 +8,8 @@
#endif
#include <QEventLoop>
+#include <QPoint>
+#include <QRect>
#include <QSignalSpy>
#include <QTimer>
#include <qwebenginefindtextresult.h>
@@ -66,7 +43,7 @@ public:
bool ensureSignalEmitted()
{
- bool result = count() > 0;
+ bool result = size() > 0;
if (!result)
result = wait();
clear();
@@ -175,41 +152,27 @@ static inline bool loadSync(QWebEnginePage *page, const QUrl &url, bool ok = tru
return (!spy.empty() || spy.wait(20000)) && (spy.front().value(0).toBool() == ok);
}
-static inline QPoint elementCenter(QWebEnginePage *page, const QString &id)
-{
- const QString jsCode(
- "(function(){"
- " var elem = document.getElementById('" + id + "');"
- " var rect = elem.getBoundingClientRect();"
- " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
- "})()");
- QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList();
-
- if (rectList.count() != 2) {
- qWarning("elementCenter failed.");
- return QPoint();
- }
-
- return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
-}
-
static inline QRect elementGeometry(QWebEnginePage *page, const QString &id)
{
const QString jsCode(
"(function() {"
" var elem = document.getElementById('" + id + "');"
" var rect = elem.getBoundingClientRect();"
- " return [rect.left, rect.top, rect.right, rect.bottom];"
+ " return [rect.left, rect.top, rect.width, rect.height];"
"})()");
QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList();
- if (coords.count() != 4) {
- qWarning("elementGeometry faield.");
+ if (coords.size() != 4) {
+ qWarning("elementGeometry failed.");
return QRect();
}
return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt());
}
+static inline QPoint elementCenter(QWebEnginePage *page, const QString &id)
+{
+ return elementGeometry(page, id).center();
+}
#define W_QSKIP(a, b) QSKIP(a)
diff --git a/tests/auto/util/widgetutil.h b/tests/auto/util/widgetutil.h
index b72b56030..67d09ee4f 100644
--- a/tests/auto/util/widgetutil.h
+++ b/tests/auto/util/widgetutil.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// Functions and macros that really need to be in QTestLib
@@ -36,8 +11,10 @@
int main(int argc, char *argv[]) \
{ \
QList<const char *> w_argv(argc); \
+ QLatin1String arg("--webEngineArgs"); \
for (int i = 0; i < argc; ++i) \
w_argv[i] = argv[i]; \
+ w_argv.append(arg.data()); \
for (int i = 0; i < params.size(); ++i) \
w_argv.append(params[i].data()); \
int w_argc = w_argv.size(); \
diff --git a/tests/auto/widgets/CMakeLists.txt b/tests/auto/widgets/CMakeLists.txt
index bedb00f53..9246be68a 100644
--- a/tests/auto/widgets/CMakeLists.txt
+++ b/tests/auto/widgets/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_subdirectory(defaultsurfaceformat)
add_subdirectory(qwebenginepage)
add_subdirectory(qwebengineprofile)
@@ -13,6 +16,7 @@ add_subdirectory(qwebenginehistory)
add_subdirectory(qwebenginescript)
if(LINUX)
add_subdirectory(offscreen)
+ add_subdirectory(qtbug_110287)
endif()
if(NOT MACOS)
add_subdirectory(touchinput)
diff --git a/tests/auto/widgets/accessibility/BLACKLIST b/tests/auto/widgets/accessibility/BLACKLIST
index 41d3635d2..6fdb0dd58 100644
--- a/tests/auto/widgets/accessibility/BLACKLIST
+++ b/tests/auto/widgets/accessibility/BLACKLIST
@@ -1,2 +1,5 @@
+[roles:ax::mojom::Role::kSvgRoot]
+b2qt
+
[focusChild]
*
diff --git a/tests/auto/widgets/accessibility/CMakeLists.txt b/tests/auto/widgets/accessibility/CMakeLists.txt
index bd04bddd0..f6a08c9d3 100644
--- a/tests/auto/widgets/accessibility/CMakeLists.txt
+++ b/tests/auto/widgets/accessibility/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_webengine_accessibility
@@ -5,5 +8,6 @@ qt_internal_add_test(tst_webengine_accessibility
tst_accessibility.cpp
LIBRARIES
Qt::WebEngineWidgets
+ Qt::WebEngineCorePrivate
Test::Util
)
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index 0aabf0f6d..1579b61e2 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -17,6 +17,7 @@
Boston, MA 02110-1301, USA.
*/
+#include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
#include <qtest.h>
#include <widgetutil.h>
@@ -48,6 +49,9 @@ private Q_SLOTS:
void value();
void roles_data();
void roles();
+ void objectName();
+ void crossTreeParent();
+ void tableCellInterface();
};
// This will be called before the first test function is executed.
@@ -338,7 +342,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("ax::mojom::Role::kAbbr") << QString("<abbr>a</abbr>") << 1 << QAccessible::StaticText;
QTest::newRow("ax::mojom::Role::kAlert") << QString("<div role='alert'>alert</div>") << 0 << QAccessible::AlertMessage;
QTest::newRow("ax::mojom::Role::kAlertDialog") << QString("<div role='alertdialog'>alert</div>") << 0 << QAccessible::AlertMessage;
- QTest::newRow("ax::mojom::Role::kAnchor") << QString("<a id='a'>Chapter a</a>") << 1 << QAccessible::Link;
+ QTest::newRow("ax::mojom::Role::kAnchor") << QString("<a id='a'>Chapter a</a>") << 1 << QAccessible::Section;
QTest::newRow("ax::mojom::Role::kApplication") << QString("<div role='application'>landmark</div>") << 0 << QAccessible::Document;
QTest::newRow("ax::mojom::Role::kArticle") << QString("<article>a</article>") << 0 << QAccessible::Section;
QTest::newRow("ax::mojom::Role::kAudio") << QString("<audio controls><source src='test.mp3' type='audio/mpeg'></audio>") << 1 << QAccessible::Sound;
@@ -424,7 +428,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("ax::mojom::Role::kFigure") << QString("<figure>a</figure>") << 0 << QAccessible::Section;
QTest::newRow("ax::mojom::Role::kFooter") << QString("<footer>a</footer>") << 0 << QAccessible::Section;
QTest::newRow("ax::mojom::Role::kFooterAsNonLandmark") << QString("<article><footer>a</footer><article>") << 1 << QAccessible::Section;
- QTest::newRow("ax::mojom::Role::kForm") << QString("<form></form>") << 0 << QAccessible::Form;
+ QTest::newRow("ax::mojom::Role::kForm") << QString("<form aria-label=Name></form>") << 0 << QAccessible::Form;
QTest::newRow("ax::mojom::Role::kGraphicsDocument") << QString("<div role='graphics-document'></div>") << 0 << QAccessible::Document;
QTest::newRow("ax::mojom::Role::kGraphicsObject") << QString("<div role='graphics-object'></div>") << 0 << QAccessible::Pane;
QTest::newRow("ax::mojom::Role::kGraphicsSymbol") << QString("<div role='graphics-symbol'></div>") << 0 << QAccessible::Graphic;
@@ -473,7 +477,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("ax::mojom::Role::kNote") << QString("<div role='note'>a</div>") << 0 << QAccessible::Note;
//QTest::newRow("ax::mojom::Role::kPane"); // No mapping to ARIA role
QTest::newRow("ax::mojom::Role::kParagraph") << QString("<p>a</p>") << 0 << QAccessible::Paragraph;
- QTest::newRow("ax::mojom::Role::kPopUpButton") << QString("<select><option>a</option></select>") << 1 << QAccessible::ComboBox;
+ QTest::newRow("ax::mojom::Role::kPopUpButton") << QString("<select><option>a</option></select>") << 1 << QAccessible::PopupMenu;
QTest::newRow("ax::mojom::Role::kPre") << QString("<pre>a</pre>") << 0 << QAccessible::Section;
//QTest::newRow("ax::mojom::Role::kPresentational") << QString("<div role='presentation'>a</div>") << 0 << QAccessible::NoRole; // FIXME: Aria role 'presentation' should work
QTest::newRow("ax::mojom::Role::kProgressIndicator") << QString("<div role='progressbar' aria-valuenow='77' aria-valuemin='22' aria-valuemax='99'></div>") << 0 << QAccessible::ProgressBar;
@@ -484,7 +488,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("ax::mojom::Role::kRowGroup") << QString("<table role=table><tbody role=rowgroup><tr><td>a</td></tr></tbody></table>") << 1 << QAccessible::Section;
QTest::newRow("ax::mojom::Role::kRowHeader") << QString("<table role=table><tr><th>a</td><td>b</td></tr></table>") << 2 << QAccessible::RowHeader;
QTest::newRow("ax::mojom::Role::kRuby") << QString("<ruby>a</ruby>") << 1 << QAccessible::Grouping;
- QTest::newRow("ax::mojom::Role::kRubyAnnotation") << QString("<ruby><rt tabindex=0>a</rt></ruby>") << 2 << QAccessible::StaticText;
+ //QTest::newRow("ax::mojom::Role::kRubyAnnotation") // No mapping to ARIA role (presents as property on enclosing ruby element)
QTest::newRow("ax::mojom::Role::kScrollBar") << QString("<div role='scrollbar'>a</a>") << 0 << QAccessible::ScrollBar;
//QTest::newRow("ax::mojom::Role::kScrollView"); // No mapping to ARIA role
QTest::newRow("ax::mojom::Role::kSearch") << QString("<div role='search'>landmark</div>") << 0 << QAccessible::Section;
@@ -498,7 +502,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("ax::mojom::Role::kStatus") << QString("<output>a</output>") << 1 << QAccessible::Indicator;
QTest::newRow("ax::mojom::Role::kStrong") << QString("<strong>a</strong>") << 1 << QAccessible::StaticText;
QTest::newRow("ax::mojom::Role::kSuggestion") << QString("<div role='suggestion'></div>") << 0 << QAccessible::Section;
- QTest::newRow("ax::mojom::Role::kSvgRoot") << QString("<svg width='10' height='10'></svg>") << 1 << QAccessible::Graphic;
+ QTest::newRow("ax::mojom::Role::kSvgRoot") << QString("<svg width='10' height='10'><text font-size='10'>SVG</text></svg>") << 1 << QAccessible::WebDocument;
QTest::newRow("ax::mojom::Role::kSwitch") << QString("<button aria-checked='false'>a</button>") << 1 << QAccessible::Button;
QTest::newRow("ax::mojom::Role::kTable") << QString("<table role=table><td>a</td></table>") << 0 << QAccessible::Table;
//QTest::newRow("ax::mojom::Role::kTableHeaderContainer"); // No mapping to ARIA role
@@ -527,10 +531,10 @@ void tst_Accessibility::roles()
QFETCH(QAccessible::Role, role);
QWebEngineView webView;
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
webView.setHtml("<html><body>" + html + "</body></html>");
webView.show();
- QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
- QVERIFY(spyFinished.wait());
+ QTRY_COMPARE_WITH_TIMEOUT(spyFinished.size(), 1, 20000);
QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
@@ -540,7 +544,7 @@ void tst_Accessibility::roles()
return;
}
- QTRY_COMPARE(view->child(0)->childCount(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(view->child(0)->childCount(), 1, 20000);
QAccessibleInterface *document = view->child(0);
QAccessibleInterface *element = document->child(0);
@@ -552,9 +556,116 @@ void tst_Accessibility::roles()
QCOMPARE(element->role(), role);
}
+void tst_Accessibility::objectName()
+{
+ QWebEngineView webView;
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
+ webView.setHtml("<html><body><p id='my_id'></p></body></html>");
+ webView.show();
+ QVERIFY(spyFinished.wait());
+ QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
+ QAccessibleInterface *document = view->child(0);
+ QTRY_COMPARE(document->childCount(), 1);
+ QAccessibleInterface *p = document->child(0);
+ QVERIFY(p);
+ QVERIFY(p->object());
+ QCOMPARE(p->role(), QAccessible::Paragraph);
+ QCOMPARE(p->object()->objectName(), QStringLiteral("my_id"));
+}
+
+void tst_Accessibility::crossTreeParent()
+{
+ QWebEngineView webView;
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
+ webView.setHtml("<html><body><iframe src='data:text/html,<html><body><p id=my_id></p></body></html>'>Fallback text</iframe></body></html>");
+ webView.show();
+ QVERIFY(spyFinished.wait());
+ QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
+ QAccessibleInterface *document = view->child(0);
+ QCOMPARE(document->role(), QAccessible::WebDocument);
+ QTRY_COMPARE(document->childCount(), 1);
+ QAccessibleInterface *p = document->child(0);
+ QVERIFY(p);
+ QCOMPARE(p->parent(), document);
+ p = p->child(0);
+ QVERIFY(p);
+ QCOMPARE(p->role(), QAccessible::WebDocument);
+ QCOMPARE(p->parent()->parent(), document);
+ QTRY_COMPARE(p->childCount(), 1);
+ p = p->child(0);
+ QVERIFY(p);
+ QAccessibleInterface *subdocument = p;
+ QCOMPARE(p->role(), QAccessible::WebDocument);
+ QCOMPARE(p->parent()->parent()->parent(), document);
+ p = p->child(0);
+ QVERIFY(p);
+ QVERIFY(p->object());
+ QCOMPARE(p->role(), QAccessible::Paragraph);
+ QCOMPARE(p->parent(), subdocument);
+ QCOMPARE(p->parent()->parent()->parent()->parent(), document);
+ QCOMPARE(p->parent()->parent()->parent()->parent()->parent(), view);
+ QCOMPARE(p->object()->objectName(), QStringLiteral("my_id"));
+}
+
+void tst_Accessibility::tableCellInterface()
+{
+ QWebEngineView webView;
+ webView.resize(400, 400);
+ webView.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&webView));
+
+ QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
+ webView.setHtml(QLatin1String(
+ "<html><body>"
+ " <ul>"
+ " <li><a href='#link1' id='link1'>Link in ListItem</a></li>"
+ " </ul>"
+ ""
+ " <div role='rowgroup'>"
+ " <div role='row'>"
+ " <span role='cell'><a href='#link2' id='link2'>Link in Cell</a></span>"
+ " </div>"
+ " </div>"
+ "</body></html>"));
+ QTRY_COMPARE(spyFinished.size(), 1);
+
+ QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
+ QAccessibleInterface *document = view->child(0);
+ QTRY_COMPARE(document->childCount(), 2);
+
+ // ListItem without Table parent.
+ {
+ QAccessibleInterface *list = document->child(0);
+ QAccessibleInterface *listItem = list->child(0);
+ QVERIFY(!listItem->tableCellInterface());
+
+ // Should not crash.
+ QPoint linkCenter = elementCenter(webView.page(), QLatin1String("link1"));
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, linkCenter);
+ QTRY_COMPARE(webView.url().fragment(), QLatin1String("link1"));
+ }
+
+ // Cell without Table parent.
+ {
+ QAccessibleInterface *rowgroup = document->child(1);
+ QAccessibleInterface *row = rowgroup->child(0);
+ QAccessibleInterface *cell = row->child(0);
+ QVERIFY(!cell->tableCellInterface());
+
+ // Should not crash.
+ QPoint linkCenter = elementCenter(webView.page(), QLatin1String("link2"));
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, linkCenter);
+ QTRY_COMPARE(webView.url().fragment(), QLatin1String("link2"));
+ }
+}
+
static QByteArrayList params = QByteArrayList()
<< "--force-renderer-accessibility"
- << "--enable-features=AccessibilityExposeARIAAnnotations";
+ << "--enable-features=AccessibilityExposeARIAAnnotations"
+#if QT_CONFIG(webengine_embedded_build)
+ << "--disable-features=TimedHTMLParserBudget"
+#endif
+ ;
W_QTEST_MAIN(tst_Accessibility, params)
#include "tst_accessibility.moc"
diff --git a/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt b/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt
index 6dd05f58f..d95c1355b 100644
--- a/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt
+++ b/tests/auto/widgets/defaultsurfaceformat/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_defaultsurfaceformat
diff --git a/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp b/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp
index 7a52a372a..c53f6f5b3 100644
--- a/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp
+++ b/tests/auto/widgets/defaultsurfaceformat/tst_defaultsurfaceformat.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <qtest.h>
#include <util.h>
diff --git a/tests/auto/widgets/favicon/CMakeLists.txt b/tests/auto/widgets/favicon/CMakeLists.txt
index 3a2f6f255..0deae6a37 100644
--- a/tests/auto/widgets/favicon/CMakeLists.txt
+++ b/tests/auto/widgets/favicon/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_favicon
diff --git a/tests/auto/widgets/favicon/tst_favicon.cpp b/tests/auto/widgets/favicon/tst_favicon.cpp
index d8b4803c0..c70aa1182 100644
--- a/tests/auto/widgets/favicon/tst_favicon.cpp
+++ b/tests/auto/widgets/favicon/tst_favicon.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTest>
#include <util.h>
+#include <QWebEngineHistory>
#include <QWebEnginePage>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
@@ -49,6 +25,7 @@ private Q_SLOTS:
void faviconLoadFromResources();
void faviconLoadEncodedUrl();
void faviconLoadAfterHistoryNavigation();
+ void faviconLoadPushState();
void noFavicon();
void aboutBlank();
void unavailableFavicon();
@@ -111,9 +88,9 @@ void tst_Favicon::faviconLoad()
+ QLatin1String("/resources/favicon-single.html"));
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(iconUrl, m_page->iconUrl());
@@ -124,7 +101,7 @@ void tst_Favicon::faviconLoad()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 2);
+ QCOMPARE(icon.availableSizes().size(), 2);
QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
}
@@ -138,9 +115,9 @@ void tst_Favicon::faviconLoadFromResources()
QUrl url("qrc:/resources/favicon-single.html");
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(iconUrl, m_page->iconUrl());
@@ -149,7 +126,7 @@ void tst_Favicon::faviconLoadFromResources()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 2);
+ QCOMPARE(icon.availableSizes().size(), 2);
QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
}
@@ -173,9 +150,9 @@ void tst_Favicon::faviconLoadEncodedUrl()
QUrl url(urlString + QLatin1String("?favicon=load should work with#whitespace!"));
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(m_page->iconUrl(), iconUrl);
@@ -186,7 +163,7 @@ void tst_Favicon::faviconLoadEncodedUrl()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 2);
+ QCOMPARE(icon.availableSizes().size(), 2);
QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
}
@@ -198,30 +175,65 @@ void tst_Favicon::faviconLoadAfterHistoryNavigation()
QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
m_page->load(QUrl("qrc:/resources/favicon-single.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qt32.ico"));
m_page->load(QUrl("qrc:/resources/favicon-multi.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 2, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 3);
- QTRY_COMPARE(iconChangedSpy.count(), 3);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 2, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 3);
+ QTRY_COMPARE(iconChangedSpy.size(), 3);
QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qtmulti.ico"));
m_page->triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 5);
- QTRY_COMPARE(iconChangedSpy.count(), 5);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 3, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 5);
+ QTRY_COMPARE(iconChangedSpy.size(), 5);
QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qt32.ico"));
m_page->triggerAction(QWebEnginePage::Forward);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 4, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 7);
- QTRY_COMPARE(iconChangedSpy.count(), 7);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 4, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 7);
+ QTRY_COMPARE(iconChangedSpy.size(), 7);
QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qtmulti.ico"));
}
+void tst_Favicon::faviconLoadPushState()
+{
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+ QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
+
+ QUrl url("qrc:/resources/favicon-single.html");
+ m_page->load(url);
+
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QCOMPARE(iconUrl, m_page->iconUrl());
+ QCOMPARE(iconUrl, QUrl("qrc:/resources/icons/qt32.ico"));
+
+ const QIcon &icon = m_page->icon();
+ QVERIFY(!icon.isNull());
+
+ iconUrlChangedSpy.clear();
+ iconChangedSpy.clear();
+
+ // pushState() is a same document navigation and should not reset or
+ // update favicon.
+ QCOMPARE(m_page->history()->count(), 1);
+ evaluateJavaScriptSync(m_page, "history.pushState('', '')");
+ QTRY_COMPARE(m_page->history()->count(), 2);
+
+ // Favicon change is not expected.
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
+ QCOMPARE(m_page->iconUrl(), QUrl("qrc:/resources/icons/qt32.ico"));
+}
+
void tst_Favicon::noFavicon()
{
if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
@@ -239,9 +251,9 @@ void tst_Favicon::noFavicon()
+ QLatin1String("/resources/test1.html"));
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -256,9 +268,9 @@ void tst_Favicon::aboutBlank()
QUrl url("about:blank");
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -281,9 +293,9 @@ void tst_Favicon::unavailableFavicon()
+ QLatin1String("/resources/favicon-unavailable.html"));
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -300,9 +312,9 @@ void tst_Favicon::errorPageEnabled()
QUrl url("http://url.invalid");
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -319,9 +331,9 @@ void tst_Favicon::errorPageDisabled()
QUrl url("http://url.invalid");
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -344,9 +356,9 @@ void tst_Favicon::touchIcon()
+ QLatin1String("/resources/favicon-touch.html"));
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -375,9 +387,9 @@ void tst_Favicon::multiIcon()
m_page->settings()->setAttribute(QWebEngineSettings::TouchIconsEnabled, false);
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(m_page->iconUrl(), iconUrl);
@@ -387,14 +399,14 @@ void tst_Favicon::multiIcon()
icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 2);
+ QCOMPARE(icon.availableSizes().size(), 2);
QVERIFY(icon.availableSizes().contains(QSize(16, 16)));
QVERIFY(icon.availableSizes().contains(QSize(32, 32)));
// Reset
loadFinishedSpy.clear();
m_page->load(QUrl("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
iconUrlChangedSpy.clear();
iconChangedSpy.clear();
loadFinishedSpy.clear();
@@ -404,9 +416,9 @@ void tst_Favicon::multiIcon()
m_page->settings()->setAttribute(QWebEngineSettings::TouchIconsEnabled, true);
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(m_page->iconUrl(), iconUrl);
@@ -416,7 +428,7 @@ void tst_Favicon::multiIcon()
icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 1);
+ QCOMPARE(icon.availableSizes().size(), 1);
QVERIFY(icon.availableSizes().contains(QSize(64, 64)));
}
@@ -442,9 +454,9 @@ void tst_Favicon::downloadIconsDisabled()
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QCOMPARE(iconUrlChangedSpy.count(), 0);
- QCOMPARE(iconChangedSpy.count(), 0);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QCOMPARE(iconUrlChangedSpy.size(), 0);
+ QCOMPARE(iconChangedSpy.size(), 0);
QVERIFY(m_page->iconUrl().isEmpty());
QVERIFY(m_page->icon().isNull());
@@ -479,9 +491,9 @@ void tst_Favicon::downloadTouchIconsEnabled()
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
const QUrl &iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
QCOMPARE(m_page->iconUrl(), iconUrl);
@@ -490,7 +502,7 @@ void tst_Favicon::downloadTouchIconsEnabled()
const QIcon &icon = m_page->icon();
QVERIFY(!icon.isNull());
- QCOMPARE(icon.availableSizes().count(), 1);
+ QCOMPARE(icon.availableSizes().size(), 1);
QCOMPARE(icon.availableSizes().first(), expectedIconSize);
}
@@ -512,9 +524,9 @@ void tst_Favicon::dynamicFavicon()
"<link rel='icon' type='image/png' "
"href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='/>"
"</html>");
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
QCOMPARE(m_page->icon().pixmap(1, 1).toImage().pixelColor(0, 0), QColor(Qt::black));
@@ -523,7 +535,7 @@ void tst_Favicon::dynamicFavicon()
evaluateJavaScriptSync(
m_page,
"document.getElementsByTagName('link')[0].href = 'data:image/png;base64," + colors[color] + "';");
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
QTRY_COMPARE(m_page->iconUrl().toString(),
QString("data:image/png;base64," + colors[color]));
QCOMPARE(m_page->icon().pixmap(1, 1).toImage().pixelColor(0, 0), QColor(color));
@@ -543,13 +555,13 @@ void tst_Favicon::touchIconWithSameURL()
"<link rel='icon' type='image/png' href='" + icon + "'/>"
"<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>"
"</html>");
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
// The default favicon has to be loaded even if its URL is also set as a touch icon while touch
// icons are disabled.
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
QCOMPARE(m_page->iconUrl().toString(), icon);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
loadFinishedSpy.clear();
iconUrlChangedSpy.clear();
@@ -558,13 +570,13 @@ void tst_Favicon::touchIconWithSameURL()
m_page->setHtml("<html>"
"<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>"
"</html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
// This page only has a touch icon. With disabled touch icons we don't expect any icon to be
// shown even if the same icon was loaded previously.
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
QVERIFY(m_page->iconUrl().toString().isEmpty());
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
}
void tst_Favicon::iconDatabaseOTR()
@@ -580,9 +592,9 @@ void tst_Favicon::iconDatabaseOTR()
page->load(QUrl("qrc:/resources/favicon-misc.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
{
bool iconRequestDone = false;
@@ -635,15 +647,15 @@ void tst_Favicon::requestIconForIconURL()
page->load(QUrl("qrc:/resources/favicon-misc.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
page->load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 2);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
- QTRY_COMPARE(iconChangedSpy.count(), 2);
+ QTRY_COMPARE(loadFinishedSpy.size(), 2);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 2);
+ QTRY_COMPARE(iconChangedSpy.size(), 2);
QVERIFY(page->icon().isNull());
QVERIFY(page->iconUrl().isEmpty());
@@ -705,15 +717,15 @@ void tst_Favicon::requestIconForPageURL()
page->load(QUrl("qrc:/resources/favicon-misc.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
page->load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 2);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
- QTRY_COMPARE(iconChangedSpy.count(), 2);
+ QTRY_COMPARE(loadFinishedSpy.size(), 2);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 2);
+ QTRY_COMPARE(iconChangedSpy.size(), 2);
QVERIFY(page->icon().isNull());
QVERIFY(page->iconUrl().isEmpty());
@@ -758,15 +770,15 @@ void tst_Favicon::desiredSize()
page->load(QUrl("qrc:/resources/favicon-multi.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
page->load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 2);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
- QTRY_COMPARE(iconChangedSpy.count(), 2);
+ QTRY_COMPARE(loadFinishedSpy.size(), 2);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 2);
+ QTRY_COMPARE(iconChangedSpy.size(), 2);
QVERIFY(page->icon().isNull());
QVERIFY(page->iconUrl().isEmpty());
}
@@ -801,15 +813,15 @@ void tst_Favicon::desiredSize()
page->load(QUrl("qrc:/resources/favicon-multi.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
- QTRY_COMPARE(iconChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 1);
+ QTRY_COMPARE(iconChangedSpy.size(), 1);
page->load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 2);
- QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
- QTRY_COMPARE(iconChangedSpy.count(), 2);
+ QTRY_COMPARE(loadFinishedSpy.size(), 2);
+ QTRY_COMPARE(iconUrlChangedSpy.size(), 2);
+ QTRY_COMPARE(iconChangedSpy.size(), 2);
QVERIFY(page->icon().isNull());
QVERIFY(page->iconUrl().isEmpty());
}
diff --git a/tests/auto/widgets/loadsignals/CMakeLists.txt b/tests/auto/widgets/loadsignals/CMakeLists.txt
index 5de957148..bbd0387d9 100644
--- a/tests/auto/widgets/loadsignals/CMakeLists.txt
+++ b/tests/auto/widgets/loadsignals/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
index 0daf0ce05..6140b3766 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTest>
@@ -136,7 +111,7 @@ void tst_LoadSignals::init()
if (!view.url().isEmpty()) {
loadFinishedSpy.clear();
view.load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
}
resetSpies();
page.reset();
@@ -233,26 +208,28 @@ void tst_LoadSignals::rejectNavigationRequest_data()
QTest::addColumn<QUrl>("rejectedUrl");
QTest::addColumn<int>("expectedNavigations");
QTest::addColumn<QList<int>>("expectedSignals");
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<QWebEngineLoadingInfo::ErrorDomain>("errorDomain");
QTest::newRow("Simple")
<< QUrl("qrc:///resources/page1.html")
<< QUrl("qrc:///resources/page1.html")
- << 1 << SignalsOrderOnceFailure;
+ << 1 << SignalsOrderOnceFailure << -3 << QWebEngineLoadingInfo::InternalErrorDomain;
QTest::newRow("SamePageImmediate")
<< QUrl("qrc:///resources/page5.html")
<< QUrl("qrc:///resources/page5.html#anchor")
- << 1 << SignalsOrderOnce;
+ << 1 << SignalsOrderOnce << 200 << QWebEngineLoadingInfo::HttpStatusCodeDomain;
QTest::newRow("SamePageDeferred")
<< QUrl("qrc:///resources/page3.html")
<< QUrl("qrc:///resources/page3.html#anchor")
- << 1 << SignalsOrderOnce;
+ << 1 << SignalsOrderOnce << 200 << QWebEngineLoadingInfo::HttpStatusCodeDomain;
QTest::newRow("OtherPageImmediate")
<< QUrl("qrc:///resources/page6.html")
<< QUrl("qrc:///resources/page2.html#anchor")
- << 2 << SignalsOrderOnceFailure;
+ << 2 << SignalsOrderOnceFailure << -3 << QWebEngineLoadingInfo::InternalErrorDomain;
QTest::newRow("OtherPageDeferred")
<< QUrl("qrc:///resources/page7.html")
<< QUrl("qrc:///resources/page2.html#anchor")
- << 2 << SignalsOrderTwiceWithFailure;
+ << 2 << SignalsOrderTwiceWithFailure << -3 << QWebEngineLoadingInfo::InternalErrorDomain;
}
/**
@@ -267,6 +244,8 @@ void tst_LoadSignals::rejectNavigationRequest()
QFETCH(QUrl, rejectedUrl);
QFETCH(int, expectedNavigations);
QFETCH(QList<int>, expectedSignals);
+ QFETCH(int, errorCode);
+ QFETCH(QWebEngineLoadingInfo::ErrorDomain, errorDomain);
page.blacklist.insert(rejectedUrl);
page.load(initialUrl);
@@ -281,6 +260,8 @@ void tst_LoadSignals::rejectNavigationRequest()
// No further loadStarted should have occurred within this time
QCOMPARE(loadStartedSpy.size(), expectedLoadCount);
QCOMPARE(loadFinishedSpy.size(), expectedLoadCount);
+ QCOMPARE(page.loadingInfos.last().errorCode(), errorCode);
+ QCOMPARE(page.loadingInfos.last().errorDomain(), errorDomain);
}
/**
@@ -296,7 +277,7 @@ void tst_LoadSignals::monotonicity()
QVERIFY(server.start());
view.load(server.url("/loadprogress/main.html"));
- QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 10000);
QVERIFY(loadFinishedSpy[0][0].toBool());
QVERIFY(page.loadProgress.size() >= 3);
@@ -368,6 +349,8 @@ void tst_LoadSignals::fileDownload()
QTRY_LOOP_IMPL(loadStartedSpy.size() != 2 || loadFinishedSpy.size() != 2, 1000, 100);
QCOMPARE(page.signalsOrder, SignalsOrderTwiceWithFailure);
+ QCOMPARE(page.loadingInfos[3].errorCode(), -3);
+ QCOMPARE(page.loadingInfos[3].errorDomain(), QWebEngineLoadingInfo::InternalErrorDomain);
}
void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame_data()
@@ -406,21 +389,27 @@ void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame()
resetSpies();
QTRY_LOOP_IMPL(loadStartedSpy.size() || loadFinishedSpy.size(), 1000, 100);
QCOMPARE(page.signalsOrder, SignalsOrderOnce);
+ QCOMPARE(page.loadingInfos[1].errorCode(), 200);
+ QCOMPARE(page.loadingInfos[1].errorDomain(), QWebEngineLoadingInfo::HttpStatusCodeDomain);
}
void tst_LoadSignals::loadFinishedAfterNotFoundError_data()
{
QTest::addColumn<bool>("rfcInvalid");
QTest::addColumn<bool>("withServer");
- QTest::addRow("rfc_invalid") << true << false;
- QTest::addRow("non_existent") << false << false;
- QTest::addRow("server_404") << false << true;
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<int>("errorDomain");
+ QTest::addRow("rfc_invalid") << true << false << -105 << int(QWebEngineLoadingInfo::ConnectionErrorDomain);
+ QTest::addRow("non_existent") << false << false << -105 << int(QWebEngineLoadingInfo::ConnectionErrorDomain);
+ QTest::addRow("server_404") << false << true << 404 << int(QWebEngineLoadingInfo::HttpStatusCodeDomain);
}
void tst_LoadSignals::loadFinishedAfterNotFoundError()
{
- QFETCH(bool, withServer);
QFETCH(bool, rfcInvalid);
+ QFETCH(bool, withServer);
+ QFETCH(int, errorCode);
+ QFETCH(int, errorDomain);
QScopedPointer<HttpServer> server;
if (withServer) {
@@ -432,27 +421,53 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError()
? server->url("/not-found-page.html")
: QUrl(rfcInvalid ? "http://some.invalid" : "http://non.existent/url");
view.load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
QVERIFY(!loadFinishedSpy.at(0).at(0).toBool());
QCOMPARE(toPlainTextSync(view.page()), QString());
- QCOMPARE(loadFinishedSpy.count(), 1);
- QCOMPARE(loadStartedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.size(), 1);
+ QCOMPARE(loadStartedSpy.size(), 1);
QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
page.loadProgress.clear();
+ { auto &&loadStart = page.loadingInfos[0], &&loadFinish = page.loadingInfos[1];
+ QCOMPARE(loadStart.status(), QWebEngineLoadingInfo::LoadStartedStatus);
+ QCOMPARE(loadStart.isErrorPage(), false);
+ QCOMPARE(loadStart.errorCode(), 0);
+ QCOMPARE(loadStart.errorDomain(), QWebEngineLoadingInfo::NoErrorDomain);
+ QCOMPARE(loadStart.errorString(), QString());
+ QCOMPARE(loadFinish.status(), QWebEngineLoadingInfo::LoadFailedStatus);
+ QCOMPARE(loadFinish.isErrorPage(), false);
+ QCOMPARE(loadFinish.errorCode(), errorCode);
+ QCOMPARE(loadFinish.errorDomain(), errorDomain);
+ QVERIFY(!loadFinish.errorString().isEmpty());
+ }
+
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
url = server
? server->url("/another-missing-one.html")
: QUrl(rfcInvalid ? "http://some.other.invalid" : "http://another.non.existent/url");
view.load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 2, 20000);
QVERIFY(!loadFinishedSpy.at(1).at(0).toBool());
- QCOMPARE(loadStartedSpy.count(), 2);
+ QCOMPARE(loadStartedSpy.size(), 2);
QEXPECT_FAIL("", "No more loads (like separate load for error pages) are expected", Continue);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 1000);
- QCOMPARE(loadStartedSpy.count(), 2);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 3, 1000);
+ QCOMPARE(loadStartedSpy.size(), 2);
QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end()));
+
+ { auto &&loadStart = page.loadingInfos[2], &&loadFinish = page.loadingInfos[3];
+ QCOMPARE(loadStart.status(), QWebEngineLoadingInfo::LoadStartedStatus);
+ QCOMPARE(loadStart.isErrorPage(), false);
+ QCOMPARE(loadStart.errorCode(), 0);
+ QCOMPARE(loadStart.errorDomain(), QWebEngineLoadingInfo::NoErrorDomain);
+ QCOMPARE(loadStart.errorString(), QString());
+ QCOMPARE(loadFinish.status(), QWebEngineLoadingInfo::LoadFailedStatus);
+ QCOMPARE(loadFinish.isErrorPage(), true);
+ QCOMPARE(loadFinish.errorCode(), errorCode);
+ QCOMPARE(loadFinish.errorDomain(), errorDomain);
+ QVERIFY(!loadFinish.errorString().isEmpty());
+ }
}
void tst_LoadSignals::errorPageTriggered_data()
@@ -460,10 +475,12 @@ void tst_LoadSignals::errorPageTriggered_data()
QTest::addColumn<QString>("urlPath");
QTest::addColumn<bool>("loadSucceed");
QTest::addColumn<bool>("triggersErrorPage");
- QTest::newRow("/content/200") << QStringLiteral("/content/200") << true << false;
- QTest::newRow("/empty/200") << QStringLiteral("/content/200") << true << false;
- QTest::newRow("/content/404") << QStringLiteral("/content/404") << false << false;
- QTest::newRow("/empty/404") << QStringLiteral("/empty/404") << false << true;
+ QTest::addColumn<int>("errorCode");
+ QTest::addColumn<QWebEngineLoadingInfo::ErrorDomain>("errorDomain");
+ QTest::newRow("/content/200") << QStringLiteral("/content/200") << true << false << 200 << QWebEngineLoadingInfo::HttpStatusCodeDomain;
+ QTest::newRow("/empty/200") << QStringLiteral("/content/200") << true << false << 200 << QWebEngineLoadingInfo::HttpStatusCodeDomain;
+ QTest::newRow("/content/404") << QStringLiteral("/content/404") << false << false << 404 << QWebEngineLoadingInfo::HttpStatusCodeDomain;
+ QTest::newRow("/empty/404") << QStringLiteral("/empty/404") << false << true << 404 << QWebEngineLoadingInfo::HttpStatusCodeDomain;
}
void tst_LoadSignals::errorPageTriggered()
@@ -471,7 +488,7 @@ void tst_LoadSignals::errorPageTriggered()
HttpServer server;
connect(&server, &HttpServer::newRequest, [] (HttpReqRep *rr) {
QList<QByteArray> parts = rr->requestPath().split('/');
- if (parts.length() != 3) {
+ if (parts.size() != 3) {
// For example, /favicon.ico
rr->sendResponse(404);
return;
@@ -490,6 +507,8 @@ void tst_LoadSignals::errorPageTriggered()
QFETCH(QString, urlPath);
QFETCH(bool, loadSucceed);
QFETCH(bool, triggersErrorPage);
+ QFETCH(int, errorCode);
+ QFETCH(QWebEngineLoadingInfo::ErrorDomain, errorDomain);
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
view.load(server.url(urlPath));
@@ -499,6 +518,8 @@ void tst_LoadSignals::errorPageTriggered()
QVERIFY(toPlainTextSync(view.page()).contains("HTTP ERROR 404"));
else
QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ QCOMPARE(page.loadingInfos[1].errorCode(), errorCode);
+ QCOMPARE(page.loadingInfos[1].errorDomain(), errorDomain);
loadFinishedSpy.clear();
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
@@ -506,6 +527,8 @@ void tst_LoadSignals::errorPageTriggered()
QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy[0][0].toBool(), loadSucceed);
QVERIFY(toPlainTextSync(view.page()).isEmpty());
+ QCOMPARE(page.loadingInfos[3].errorCode(), errorCode);
+ QCOMPARE(page.loadingInfos[3].errorDomain(), errorDomain);
loadFinishedSpy.clear();
}
diff --git a/tests/auto/widgets/offscreen/CMakeLists.txt b/tests/auto/widgets/offscreen/CMakeLists.txt
index d51459a3e..756e53c43 100644
--- a/tests/auto/widgets/offscreen/CMakeLists.txt
+++ b/tests/auto/widgets/offscreen/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_offscreen
SOURCES
tst_offscreen.cpp
diff --git a/tests/auto/widgets/offscreen/tst_offscreen.cpp b/tests/auto/widgets/offscreen/tst_offscreen.cpp
index 81cbe95f3..553dc653b 100644
--- a/tests/auto/widgets/offscreen/tst_offscreen.cpp
+++ b/tests/auto/widgets/offscreen/tst_offscreen.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QSignalSpy>
@@ -51,7 +26,7 @@ void tst_OffScreen::offscreen()
page.load(QUrl("qrc:/test.html"));
view.show();
QTRY_COMPARE(view.isVisible(), true);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count() > 0, true, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size() > 0, true, 20000);
QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), true);
}
diff --git a/tests/auto/widgets/printing/CMakeLists.txt b/tests/auto/widgets/printing/CMakeLists.txt
index e61b8cc89..baa3cf747 100644
--- a/tests/auto/widgets/printing/CMakeLists.txt
+++ b/tests/auto/widgets/printing/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
find_package(PkgConfig)
@@ -8,18 +11,15 @@ endif()
qt_internal_add_test(tst_printing
SOURCES
tst_printing.cpp
- PUBLIC_LIBRARIES
- Qt::WebEngineWidgets
LIBRARIES
Qt::CorePrivate
+ Qt::WebEngineWidgets
Qt::WebEngineCorePrivate
Test::Util
)
qt_internal_extend_target(tst_printing
- CONDITION POPPLER_CPP_FOUND
- DEFINES
- POPPLER_CPP
+ CONDITION POPPLER_CPP_FOUND AND QT_FEATURE_webengine_system_poppler
LIBRARIES
PkgConfig::POPPLER_CPP
)
diff --git a/tests/auto/widgets/printing/tst_printing.cpp b/tests/auto/widgets/printing/tst_printing.cpp
index 0559fb787..605fb57b5 100644
--- a/tests/auto/widgets/printing/tst_printing.cpp
+++ b/tests/auto/widgets/printing/tst_printing.cpp
@@ -1,39 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
+#include <QtWebEngineCore/qtwebenginecore-config.h>
+#include <QWebEngineSettings>
#include <QWebEngineView>
#include <QTemporaryDir>
#include <QTest>
#include <QSignalSpy>
#include <util.h>
-#if defined(POPPLER_CPP)
+#if QT_CONFIG(webengine_system_poppler)
#include <poppler-document.h>
#include <poppler-page.h>
#endif
@@ -44,9 +21,11 @@ class tst_Printing : public QObject
private slots:
void printToPdfBasic();
void printRequest();
-#if defined(POPPLER_CPP) && defined(Q_OS_LINUX) && defined(__GLIBCXX__)
+#if QT_CONFIG(webengine_system_poppler)
void printToPdfPoppler();
+ void printFromPdfViewer();
#endif
+ void interruptPrinting();
};
void tst_Printing::printToPdfBasic()
@@ -56,13 +35,13 @@ void tst_Printing::printToPdfBasic()
QWebEngineView view;
QSignalSpy spy(&view, &QWebEngineView::loadFinished);
view.load(QUrl("qrc:///resources/basic_printing_page.html"));
- QTRY_VERIFY(spy.count() == 1);
+ QTRY_VERIFY(spy.size() == 1);
QSignalSpy savePdfSpy(view.page(), &QWebEnginePage::pdfPrintingFinished);
QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0.0, 0.0, 0.0, 0.0));
QString path = tempDir.path() + "/print_1_success.pdf";
view.page()->printToPdf(path, layout);
- QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal");
+ QTRY_VERIFY2(savePdfSpy.size() == 1, "Printing to PDF file failed without signal");
QList<QVariant> successArguments = savePdfSpy.takeFirst();
QVERIFY2(successArguments.at(0).toString() == path, "File path for first saved PDF does not match arguments");
@@ -74,7 +53,7 @@ void tst_Printing::printToPdfBasic()
path = tempDir.path() + "/print_|2_failed.pdf";
#endif
view.page()->printToPdf(path, QPageLayout());
- QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal");
+ QTRY_VERIFY2(savePdfSpy.size() == 1, "Printing to PDF file failed without signal");
QList<QVariant> failedArguments = savePdfSpy.takeFirst();
QVERIFY2(failedArguments.at(0).toString() == path, "File path for second saved PDF does not match arguments");
@@ -82,11 +61,11 @@ void tst_Printing::printToPdfBasic()
CallbackSpy<QByteArray> successfulSpy;
view.page()->printToPdf(successfulSpy.ref(), layout);
- QVERIFY(successfulSpy.waitForResult().length() > 0);
+ QVERIFY(successfulSpy.waitForResult().size() > 0);
CallbackSpy<QByteArray> failedInvalidLayoutSpy;
view.page()->printToPdf(failedInvalidLayoutSpy.ref(), QPageLayout());
- QCOMPARE(failedInvalidLayoutSpy.waitForResult().length(), 0);
+ QCOMPARE(failedInvalidLayoutSpy.waitForResult().size(), 0);
}
void tst_Printing::printRequest()
@@ -100,17 +79,17 @@ void tst_Printing::printRequest()
CallbackSpy<QByteArray> resultSpy;
view.load(QUrl("qrc:///resources/basic_printing_page.html"));
- QTRY_VERIFY(loadFinishedSpy.count() == 1);
+ QTRY_VERIFY(loadFinishedSpy.size() == 1);
view.page()->runJavaScript("window.print()");
- QTRY_VERIFY(printRequestedSpy.count() == 1);
- QVERIFY(printRequestedSpy2.count() == 1);
+ QTRY_VERIFY(printRequestedSpy.size() == 1);
+ QVERIFY(printRequestedSpy2.size() == 1);
//check if printing still works
view.printToPdf(resultSpy.ref(), layout);
const QByteArray data = resultSpy.waitForResult();
- QVERIFY(data.length() > 0);
+ QVERIFY(data.size() > 0);
}
-#if defined(POPPLER_CPP) && defined(Q_OS_LINUX) && defined(__GLIBCXX__)
+#if QT_CONFIG(webengine_system_poppler)
void tst_Printing::printToPdfPoppler()
{
// check if generated pdf is correct by searching for a know string on the page
@@ -139,8 +118,65 @@ void tst_Printing::printToPdfPoppler()
QVERIFY2(pdfPage->search(ustring::from_latin1("Hello Paper World"), rect, page::search_from_top,
case_sensitive ), "Could not find text");
}
+
+void tst_Printing::printFromPdfViewer()
+{
+ using namespace poppler;
+
+ QWebEngineView view;
+ view.page()->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
+ view.page()->settings()->setAttribute(QWebEngineSettings::PdfViewerEnabled, true);
+
+ // Load a basic HTML
+ QSignalSpy spy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("qrc:///resources/basic_printing_page.html"));
+ QTRY_COMPARE(spy.size(), 1);
+
+ // Create a PDF
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_printing-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ QString path = tempDir.path() + "/basic_page.pdf";
+ QSignalSpy savePdfSpy(view.page(), &QWebEnginePage::pdfPrintingFinished);
+ view.page()->printToPdf(path);
+ QTRY_COMPARE(savePdfSpy.size(), 1);
+
+ // Open the new file with the PDF viewer plugin
+ view.load(QUrl("file://" + path));
+ QTRY_COMPARE(spy.size(), 2);
+
+ // Print from the plugin
+ // loadFinished signal is not reliable when loading a PDF file, because it has multiple phases.
+ // Workaround: Try to print it a couple of times until the result matches the expected.
+ CallbackSpy<QByteArray> resultSpy;
+ bool ok = QTest::qWaitFor([&]() -> bool {
+ view.printToPdf(resultSpy.ref());
+ QByteArray data = resultSpy.waitForResult();
+
+ // Check if the result contains text from the original basic HTML
+ // This catches all the typical issues: empty result or printing the WebUI without PDF content.
+ QScopedPointer<document> pdf(document::load_from_raw_data(data.constData(), data.length()));
+ QScopedPointer<page> pdfPage(pdf->create_page(0));
+ rectf rect;
+ return pdfPage->search(ustring::from_latin1("Hello Paper World"), rect, page::search_from_top,
+ case_sensitive);
+ }, 10000);
+ QVERIFY(ok);
+}
#endif
+void tst_Printing::interruptPrinting()
+{
+ QWebEngineView view;
+ QSignalSpy spy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("qrc:///resources/basic_printing_page.html"));
+ QTRY_VERIFY(spy.size() == 1);
+
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
+ QVERIFY(tempDir.isValid());
+ view.page()->printToPdf(tempDir.path() + "/file.pdf");
+ // Navigation stop interrupts print job, preferably do this without crash/assert
+ view.page()->triggerAction(QWebEnginePage::Stop);
+}
QTEST_MAIN(tst_Printing)
#include "tst_printing.moc"
diff --git a/tests/auto/widgets/proxy/CMakeLists.txt b/tests/auto/widgets/proxy/CMakeLists.txt
index 03af3c35f..95dc903ed 100644
--- a/tests/auto/widgets/proxy/CMakeLists.txt
+++ b/tests/auto/widgets/proxy/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
qt_internal_add_test(tst_webengine_proxy
diff --git a/tests/auto/widgets/proxy/tst_proxy.cpp b/tests/auto/widgets/proxy/tst_proxy.cpp
index c3e3c88a4..3dc72618c 100644
--- a/tests/auto/widgets/proxy/tst_proxy.cpp
+++ b/tests/auto/widgets/proxy/tst_proxy.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "proxy_server.h"
#include <QTest>
@@ -33,7 +8,7 @@
#include <QWebEnginePage>
#include <QWebEngineView>
#include <QWebEngineUrlRequestInterceptor>
-
+#include <QWebEngineLoadingInfo>
struct Interceptor : public QWebEngineUrlRequestInterceptor
{
@@ -53,6 +28,7 @@ public:
private slots:
void proxyAuthentication();
void forwardCookie();
+ void invalidHostName();
};
@@ -74,7 +50,7 @@ void tst_Proxy::proxyAuthentication()
QWebEnginePage page;
QSignalSpy successSpy(&server, &ProxyServer::authenticationSuccess);
page.load(QUrl("http://www.qt.io"));
- QTRY_VERIFY2(successSpy.count() > 0, "Could not get authentication token");
+ QTRY_VERIFY2(successSpy.size() > 0, "Could not get authentication token");
}
void tst_Proxy::forwardCookie()
@@ -94,7 +70,20 @@ void tst_Proxy::forwardCookie()
page.setUrlRequestInterceptor(&interceptor);
QSignalSpy cookieSpy(&server, &ProxyServer::cookieMatch);
page.load(QUrl("http://www.qt.io"));
- QTRY_VERIFY2(cookieSpy.count() > 0, "Could not get cookie");
+ QTRY_VERIFY2(cookieSpy.size() > 0, "Could not get cookie");
+}
+
+// Crash test ( https://bugreports.qt.io/browse/QTBUG-113992 )
+void tst_Proxy::invalidHostName()
+{
+ QNetworkProxy proxy;
+ proxy.setType(QNetworkProxy::HttpProxy);
+ proxy.setHostName("999.0.0.0");
+ QNetworkProxy::setApplicationProxy(proxy);
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl("http://www.qt.io"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
}
#include "tst_proxy.moc"
diff --git a/tests/auto/widgets/proxypac/CMakeLists.txt b/tests/auto/widgets/proxypac/CMakeLists.txt
index 1dd2c8bec..f27160cb6 100644
--- a/tests/auto/widgets/proxypac/CMakeLists.txt
+++ b/tests/auto/widgets/proxypac/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
qt_internal_add_test(tst_proxypac_file
@@ -21,6 +24,22 @@ set_tests_properties(tst_proxypac_file PROPERTIES
ENVIRONMENT QTWEBENGINE_CHROMIUM_FLAGS=${fileEnvArg}
)
+if(NOT (LINUX AND CMAKE_CROSSCOMPILING))
+ set(fileEnvArg "--single-process ${fileEnvArg}")
+
+ qt_internal_add_test(tst_proxypac_single_process
+ SOURCES
+ tst_proxypac.cpp
+ LIBRARIES
+ Qt::WebEngineCore
+ Test::HttpServer
+ )
+
+ set_tests_properties(tst_proxypac_single_process PROPERTIES
+ ENVIRONMENT QTWEBENGINE_CHROMIUM_FLAGS=${fileEnvArg}
+ )
+endif()
+
qt_internal_add_test(tst_proxypac_qrc
SOURCES
tst_proxypac.cpp
@@ -40,8 +59,6 @@ set_tests_properties(tst_proxypac_qrc PROPERTIES
)
qt_internal_add_resource(tst_proxypac_qrc "proxypac"
- PREFIX
- "/"
- FILES
- "proxy.pac"
+ PREFIX "/"
+ FILES "proxy.pac"
)
diff --git a/tests/auto/widgets/proxypac/proxy.pac b/tests/auto/widgets/proxypac/proxy.pac
index 1d29847b9..966c37ba5 100644
--- a/tests/auto/widgets/proxypac/proxy.pac
+++ b/tests/auto/widgets/proxypac/proxy.pac
@@ -2,6 +2,6 @@ function FindProxyForURL(url, host)
{
if (shExpMatch(host, "*.proxy1.com")) return "PROXY localhost:5551";
if (shExpMatch(host, "*.proxy2.com")) return "PROXY localhost:5552";
- return "PROXY proxy.url:8080";
+ return "DIRECT";
}
diff --git a/tests/auto/widgets/proxypac/proxyserver.cpp b/tests/auto/widgets/proxypac/proxyserver.cpp
index 4d38c87c9..f7a859747 100644
--- a/tests/auto/widgets/proxypac/proxyserver.cpp
+++ b/tests/auto/widgets/proxypac/proxyserver.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "proxyserver.h"
#include <QDataStream>
diff --git a/tests/auto/widgets/proxypac/proxyserver.h b/tests/auto/widgets/proxypac/proxyserver.h
index ea68286a2..c95856da9 100644
--- a/tests/auto/widgets/proxypac/proxyserver.h
+++ b/tests/auto/widgets/proxypac/proxyserver.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PROXY_SERVER_H
#define PROXY_SERVER_H
diff --git a/tests/auto/widgets/proxypac/tst_proxypac.cpp b/tests/auto/widgets/proxypac/tst_proxypac.cpp
index 223c995e0..43ccbf028 100644
--- a/tests/auto/widgets/proxypac/tst_proxypac.cpp
+++ b/tests/auto/widgets/proxypac/tst_proxypac.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "proxy_server.h"
#include <QTest>
@@ -33,7 +8,6 @@
#include <QWebEnginePage>
#include <QNetworkProxy>
-
class tst_ProxyPac : public QObject {
Q_OBJECT
public:
@@ -64,11 +38,20 @@ void tst_ProxyPac::proxypac()
QWebEngineProfile profile;
QWebEnginePage page(&profile);
+
+ const bool v8_proxy_resolver_enabled = !fromEnv.contains("--single-process");
page.load(QUrl("http://test.proxy1.com"));
- QTRY_COMPARE(proxySpy1.count() >= 1, true);
- QVERIFY(proxySpy2.count() == 0);
+ QTRY_COMPARE(proxySpy1.size() >= 1, v8_proxy_resolver_enabled);
+ QVERIFY(proxySpy2.size() == 0);
page.load(QUrl("http://test.proxy2.com"));
- QTRY_COMPARE(proxySpy2.count() >= 1 , true);
+ QTRY_COMPARE(proxySpy2.size() >= 1, v8_proxy_resolver_enabled);
+
+ // check for crash
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ page.load(QUrl("https://contribute.qt-project.org"));
+
+ QTRY_VERIFY_WITH_TIMEOUT(!spyFinished.isEmpty(), 200000);
+
}
#include "tst_proxypac.moc"
diff --git a/tests/auto/widgets/qtbug_110287/CMakeLists.txt b/tests/auto/widgets/qtbug_110287/CMakeLists.txt
new file mode 100644
index 000000000..ac7926dc0
--- /dev/null
+++ b/tests/auto/widgets/qtbug_110287/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_test(tst_qtbug_110287
+ SOURCES
+ tst_qtbug_110287.cpp
+ LIBRARIES
+ Qt::Network
+ Qt::WebEngineWidgets
+)
+target_link_options(tst_qtbug_110287 PRIVATE "-Wl,--as-needed")
diff --git a/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp b/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp
new file mode 100644
index 000000000..9453ae9b8
--- /dev/null
+++ b/tests/auto/widgets/qtbug_110287/tst_qtbug_110287.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QSignalSpy>
+#include <QTest>
+#include <QWebEngineView>
+
+class tst_qtbug_110287 : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qtbug_110287() { }
+
+private slots:
+ void getAddrInfo();
+};
+
+void tst_qtbug_110287::getAddrInfo()
+{
+ QNetworkAccessManager nam;
+ QSignalSpy namSpy(&nam, &QNetworkAccessManager::finished);
+
+ QString address("http://www.example.com");
+ QScopedPointer<QNetworkReply> reply(nam.get(QNetworkRequest(address)));
+
+ if (!namSpy.wait(25000) || reply->error() != QNetworkReply::NoError)
+ QSKIP("Couldn't load page from network, skipping test.");
+
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+
+ // load() will trigger system DNS resolution that uses getaddrinfo()
+ view.load(QUrl(address));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size() > 0, true, 30000);
+ QTRY_COMPARE(loadFinishedSpy[0][0].toBool(), true);
+}
+
+#include "tst_qtbug_110287.moc"
+QTEST_MAIN(tst_qtbug_110287)
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt b/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
index 3a8244c0f..5b76909b1 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginedownloadrequest/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
index 1f24928ab..c81a27b3a 100644
--- a/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
+++ b/tests/auto/widgets/qwebenginedownloadrequest/tst_qwebenginedownloadrequest.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <util.h>
@@ -133,8 +108,8 @@ void tst_QWebEngineDownloadRequest::cleanup()
for (QWebEngineDownloadRequest *item : m_finishedDownloads) {
item->deleteLater();
}
- QTRY_COMPARE(m_requestedDownloads.count(), 0);
- QCOMPARE(m_finishedDownloads.count(), 0);
+ QTRY_COMPARE(m_requestedDownloads.size(), 0);
+ QCOMPARE(m_finishedDownloads.size(), 0);
QVERIFY(m_server->stop());
// Set download path to default.
m_profile->setDownloadPath("");
@@ -153,15 +128,18 @@ void tst_QWebEngineDownloadRequest::saveLink(QPoint linkPos)
// Simulate right-clicking on link and choosing "save link as" from menu.
QSignalSpy menuSpy(m_view, &QWebEngineView::customContextMenuRequested);
m_view->setContextMenuPolicy(Qt::CustomContextMenu);
- auto event1 = new QContextMenuEvent(QContextMenuEvent::Mouse, linkPos);
- auto event2 = new QMouseEvent(QEvent::MouseButtonPress, linkPos, Qt::RightButton, {}, {});
- auto event3 = new QMouseEvent(QEvent::MouseButtonRelease, linkPos, Qt::RightButton, {}, {});
+ auto event1 =
+ new QContextMenuEvent(QContextMenuEvent::Mouse, linkPos, m_view->mapToGlobal(linkPos));
+ auto event2 = new QMouseEvent(QEvent::MouseButtonPress, linkPos, m_view->mapToGlobal(linkPos),
+ Qt::RightButton, {}, {});
+ auto event3 = new QMouseEvent(QEvent::MouseButtonRelease, linkPos, m_view->mapToGlobal(linkPos),
+ Qt::RightButton, {}, {});
QTRY_VERIFY(m_view->focusWidget());
QWidget *renderWidget = m_view->focusWidget();
QCoreApplication::postEvent(renderWidget, event1);
QCoreApplication::postEvent(renderWidget, event2);
QCoreApplication::postEvent(renderWidget, event3);
- QTRY_COMPARE(menuSpy.count(), 1);
+ QTRY_COMPARE(menuSpy.size(), 1);
m_page->triggerAction(QWebEnginePage::DownloadLinkToDisk);
}
@@ -199,8 +177,8 @@ void tst_QWebEngineDownloadRequest::downloadLink_data()
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.txt")
/* fileContents */ << QByteArrayLiteral("")
- /* fileMimeTypeDeclared */ << QByteArrayLiteral("")
- /* fileMimeTypeDetected */ << QByteArrayLiteral("")
+ /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain")
+ /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
/* fileAction */ << FileIsDownloaded;
@@ -437,7 +415,7 @@ void tst_QWebEngineDownloadRequest::downloadLink()
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *item) {
QCOMPARE(item->state(), QWebEngineDownloadRequest::DownloadRequested);
QCOMPARE(item->isFinished(), false);
- QCOMPARE(item->totalBytes(), -1);
+ QCOMPARE(item->totalBytes(), fileContents.size());
QCOMPARE(item->receivedBytes(), 0);
QCOMPARE(item->interruptReason(), QWebEngineDownloadRequest::NoReason);
QCOMPARE(item->isSavePageDownload(), false);
@@ -475,7 +453,7 @@ void tst_QWebEngineDownloadRequest::downloadLink()
// attribute or not.
QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
m_view->load(m_server->url());
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
QCOMPARE(indexRequestCount, 1);
@@ -483,7 +461,7 @@ void tst_QWebEngineDownloadRequest::downloadLink()
// If file is expected to be displayed and not downloaded then end test
if (fileAction == FileIsDisplayed) {
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
QCOMPARE(acceptedCount, 0);
return;
@@ -548,7 +526,7 @@ void tst_QWebEngineDownloadRequest::downloadTwoLinks()
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadRequest *item) {
QCOMPARE(item->state(), QWebEngineDownloadRequest::DownloadRequested);
QCOMPARE(item->isFinished(), false);
- QCOMPARE(item->totalBytes(), -1);
+ QCOMPARE(item->totalBytes(), 5); // strlen("fileN")
QCOMPARE(item->receivedBytes(), 0);
QCOMPARE(item->interruptReason(), QWebEngineDownloadRequest::NoReason);
QCOMPARE(item->savePageFormat(), QWebEngineDownloadRequest::UnknownSaveFormat);
@@ -573,7 +551,7 @@ void tst_QWebEngineDownloadRequest::downloadTwoLinks()
QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
m_view->load(m_server->url());
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
// Trigger downloads
@@ -665,7 +643,7 @@ void tst_QWebEngineDownloadRequest::downloadPage()
// Load some HTML
QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
m_page->load(m_server->url());
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
QCOMPARE(indexRequestCount, 1);
@@ -710,8 +688,8 @@ void tst_QWebEngineDownloadRequest::downloadViaSetUrl()
QSignalSpy urlSpy(m_page, &QWebEnginePage::urlChanged);
const QUrl indexUrl = m_server->url();
m_page->setUrl(indexUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl);
@@ -721,9 +699,9 @@ void tst_QWebEngineDownloadRequest::downloadViaSetUrl()
for (int i = 0; i != 3; ++i) {
m_page->setUrl(fileUrl);
QCOMPARE(m_page->url(), fileUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(urlSpy.count(), 2);
- QTRY_COMPARE(downloadUrls.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QTRY_COMPARE(urlSpy.size(), 2);
+ QTRY_COMPARE(downloadUrls.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), fileUrl);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl);
@@ -1154,21 +1132,21 @@ void tst_QWebEngineDownloadRequest::downloadToDirectoryWithFileName()
const QString &originalFileName = item->downloadFileName();
item->setDownloadDirectory(downloadDirectory);
QCOMPARE(item->downloadDirectory(), downloadDirectory);
- QCOMPARE(directorySpy.count(), 1);
+ QCOMPARE(directorySpy.size(), 1);
isUniquifiedFileName = (originalFileName != item->downloadFileName());
- QCOMPARE(fileNameSpy.count(), isUniquifiedFileName ? 1 : 0);
+ QCOMPARE(fileNameSpy.size(), isUniquifiedFileName ? 1 : 0);
}
if (!downloadFileName.isEmpty()) {
item->setDownloadFileName(downloadFileName);
QCOMPARE(item->downloadFileName(), downloadFileName);
- QCOMPARE(fileNameSpy.count(), isUniquifiedFileName ? 2 : 1);
+ QCOMPARE(fileNameSpy.size(), isUniquifiedFileName ? 2 : 1);
}
if (!downloadDirectory.isEmpty() && !setDirectoryFirst) {
item->setDownloadDirectory(downloadDirectory);
QCOMPARE(item->downloadDirectory(), downloadDirectory);
- QCOMPARE(directorySpy.count(), 1);
+ QCOMPARE(directorySpy.size(), 1);
}
item->accept();
@@ -1296,7 +1274,7 @@ void tst_QWebEngineDownloadRequest::downloadDataUrls()
QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
m_view->load(m_server->url());
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
// Trigger download
diff --git a/tests/auto/widgets/qwebenginehistory/CMakeLists.txt b/tests/auto/widgets/qwebenginehistory/CMakeLists.txt
index b91281a45..e277a7326 100644
--- a/tests/auto/widgets/qwebenginehistory/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginehistory/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebenginehistory
diff --git a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
index f67c2e03d..ad66e972c 100644
--- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
+++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp
@@ -39,7 +39,7 @@ protected :
{
loadFinishedSpy->clear();
page->load(QUrl("qrc:/resources/page" + QString::number(nr) + ".html"));
- QTRY_COMPARE(loadFinishedSpy->count(), 1);
+ QTRY_COMPARE(loadFinishedSpy->size(), 1);
loadFinishedSpy->clear();
}
@@ -150,8 +150,8 @@ void tst_QWebEngineHistory::back()
for (int i = histsize;i > 1;i--) {
QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), histsize-i+1);
- QTRY_COMPARE(titleChangedSpy.count(), histsize-i+1);
+ QTRY_COMPARE(loadFinishedSpy->size(), histsize-i+1);
+ QTRY_COMPARE(titleChangedSpy.size(), histsize-i+1);
}
//try one more time (too many). crash test
hist->back();
@@ -168,15 +168,15 @@ void tst_QWebEngineHistory::forward()
while (hist->canGoBack()) {
hist->back();
histBackCount++;
- QTRY_COMPARE(loadFinishedSpy->count(), histBackCount);
+ QTRY_COMPARE(loadFinishedSpy->size(), histBackCount);
}
QSignalSpy titleChangedSpy(page, SIGNAL(titleChanged(const QString&)));
for (int i = 1;i < histsize;i++) {
QTRY_COMPARE(toPlainTextSync(page), QString("page") + QString::number(i));
hist->forward();
- QTRY_COMPARE(loadFinishedSpy->count(), i+histBackCount);
- QTRY_COMPARE(titleChangedSpy.count(), i);
+ QTRY_COMPARE(loadFinishedSpy->size(), i+histBackCount);
+ QTRY_COMPARE(titleChangedSpy.size(), i);
}
//try one more time (too many). crash test
hist->forward();
@@ -205,15 +205,15 @@ void tst_QWebEngineHistory::goToItem()
QWebEngineHistoryItem current = hist->currentItem();
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), 1);
+ QTRY_COMPARE(loadFinishedSpy->size(), 1);
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), 2);
+ QTRY_COMPARE(loadFinishedSpy->size(), 2);
QVERIFY(hist->currentItem().title() != current.title());
hist->goToItem(current);
- QTRY_COMPARE(loadFinishedSpy->count(), 2);
+ QTRY_COMPARE(loadFinishedSpy->size(), 2);
QTRY_COMPARE(hist->currentItem().title(), current.title());
}
@@ -225,7 +225,7 @@ void tst_QWebEngineHistory::items()
{
QList<QWebEngineHistoryItem> items = hist->items();
//check count
- QTRY_COMPARE(histsize, items.count());
+ QTRY_COMPARE(histsize, items.size());
//check order
for (int i = 1;i <= histsize;i++) {
@@ -236,10 +236,10 @@ void tst_QWebEngineHistory::items()
void tst_QWebEngineHistory::backForwardItems()
{
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), 1);
+ QTRY_COMPARE(loadFinishedSpy->size(), 1);
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), 2);
+ QTRY_COMPARE(loadFinishedSpy->size(), 2);
QTRY_COMPARE(hist->items().size(), 5);
QTRY_COMPARE(hist->backItems(100).size(), 2);
@@ -297,9 +297,9 @@ void tst_QWebEngineHistory::serialize_2()
hist->back();
QTRY_VERIFY(evaluateJavaScriptSync(page, "location.hash").toString().isEmpty());
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), 1);
+ QTRY_COMPARE(loadFinishedSpy->size(), 1);
hist->back();
- QTRY_COMPARE(loadFinishedSpy->count(), 2);
+ QTRY_COMPARE(loadFinishedSpy->size(), 2);
//check if current index was changed (make sure that it is not last item)
QVERIFY(hist->currentItemIndex() != initialCurrentIndex);
//save current index
@@ -310,18 +310,18 @@ void tst_QWebEngineHistory::serialize_2()
load >> *hist;
QVERIFY(load.status() == QDataStream::Ok);
// Restoring the history will trigger a load.
- QTRY_COMPARE(loadFinishedSpy->count(), 3);
+ QTRY_COMPARE(loadFinishedSpy->size(), 3);
//check current index
QTRY_COMPARE(hist->currentItemIndex(), oldCurrentIndex);
hist->forward();
- QTRY_COMPARE(loadFinishedSpy->count(), 4);
+ QTRY_COMPARE(loadFinishedSpy->size(), 4);
hist->forward();
- QTRY_COMPARE(loadFinishedSpy->count(), 5);
+ QTRY_COMPARE(loadFinishedSpy->size(), 5);
hist->forward();
// In-page navigation, the last url was the page5.html
- QTRY_COMPARE(loadFinishedSpy->count(), 5);
+ QTRY_COMPARE(loadFinishedSpy->size(), 5);
QTRY_COMPARE(hist->currentItemIndex(), initialCurrentIndex);
}
@@ -429,7 +429,7 @@ void tst_QWebEngineHistory::saveAndRestore_crash_4()
QSignalSpy loadFinishedSpy2(page2.data(), SIGNAL(loadFinished(bool)));
QDataStream load(&buffer, QIODevice::ReadOnly);
load >> *page2->history();
- QTRY_COMPARE(loadFinishedSpy2.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy2.size(), 1);
}
void tst_QWebEngineHistory::saveAndRestore_InternalPage()
@@ -468,7 +468,7 @@ void tst_QWebEngineHistory::popPushState()
QWebEnginePage page;
QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));
page.setHtml("<html><body>long live Qt!</body></html>");
- QTRY_COMPARE(spyLoadFinished.count(), 1);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
evaluateJavaScriptSync(&page, script);
}
@@ -487,9 +487,9 @@ void tst_QWebEngineHistory::clear()
QWebEnginePage page2(this);
QWebEngineHistory* hist2 = page2.history();
- QVERIFY(hist2->count() == 0);
+ QCOMPARE(hist2->count(), 0);
hist2->clear();
- QVERIFY(hist2->count() == 0); // Do not change anything.
+ QCOMPARE(hist2->count(), 0); // Do not change anything.
}
void tst_QWebEngineHistory::historyItemFromDeletedPage()
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 0c84b8de1..52def48d1 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -5,5 +5,11 @@ osx
windows
macos # Can't move cursor (QTBUG-76312)
-[acceptNavigationRequestNavigationType]
-b2qt arm
+[comboBoxPopupPositionAfterMove]
+macos
+
+[comboBoxPopupPositionAfterChildMove]
+macos
+
+[backgroundColor]
+macos
diff --git a/tests/auto/widgets/qwebenginepage/CMakeLists.txt b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
index bb31d9a97..f63d6211c 100644
--- a/tests/auto/widgets/qwebenginepage/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
@@ -5,6 +8,9 @@ qt_internal_add_test(tst_qwebenginepage
SOURCES
tst_qwebenginepage.cpp
LIBRARIES
+ Qt::CorePrivate
+ Qt::NetworkPrivate
+ Qt::WebEngineCorePrivate
Qt::WebEngineWidgets
Test::HttpServer
Test::Util
@@ -18,6 +24,7 @@ set(tst_qwebenginepage_resource_files
"resources/content.html"
"resources/dynamicFrame.html"
"resources/foo.txt"
+ "resources/fontaccess.html"
"resources/frame_a.html"
"resources/frame_c.html"
"resources/framedindex.html"
diff --git a/tests/auto/widgets/qwebenginepage/resources/fontaccess.html b/tests/auto/widgets/qwebenginepage/resources/fontaccess.html
new file mode 100644
index 000000000..1a0fe8af9
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/fontaccess.html
@@ -0,0 +1,14 @@
+<html>
+<body onkeypress='onKeyPress()'>
+<a>This is test content</a>
+<script>
+var done = false;
+var fonts;
+var activated = false;
+function onKeyPress() {
+ activated = true;
+ window.queryLocalFonts().then(f => { fonts = f; done = true; });
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/resources/reload.html b/tests/auto/widgets/qwebenginepage/resources/reload.html
index d9c33dfcd..062d06807 100644
--- a/tests/auto/widgets/qwebenginepage/resources/reload.html
+++ b/tests/auto/widgets/qwebenginepage/resources/reload.html
@@ -1,6 +1,6 @@
<html>
<head>
-<meta http-equiv="refresh" content="2">
+<meta http-equiv="refresh" content="2;url=qrc:///resources/content.html">
</head>
<body>
This is test content
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8a44af3fb..39a28759c 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2016 The Qt Company Ltd.
+ Copyright (C) 2023 The Qt Company Ltd.
Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
Copyright (C) 2010 Holger Hans Peter Freyther
@@ -20,7 +20,9 @@
*/
#include <widgetutil.h>
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtWebEngineCore/qtwebenginecore-config.h>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QByteArray>
#include <QClipboard>
#include <QDir>
@@ -34,6 +36,7 @@
#include <QPaintEngine>
#include <QPushButton>
#include <QScreen>
+#include <QWheelEvent>
#if defined(QT_STATEMACHINE_LIB)
# include <QStateMachine>
#endif
@@ -47,7 +50,10 @@
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
+#include <qwebengineclienthints.h>
#include <qwebenginedownloadrequest.h>
+#include <qwebenginedesktopmediarequest.h>
+#include <qwebenginefilesystemaccessrequest.h>
#include <qwebenginefindtextresult.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
@@ -61,17 +67,21 @@
#include <qwebenginescript.h>
#include <qwebenginescriptcollection.h>
#include <qwebenginesettings.h>
+#include <qwebengineurlrequestinterceptor.h>
#include <qwebengineurlrequestjob.h>
#include <qwebengineurlscheme.h>
#include <qwebengineurlschemehandler.h>
#include <qwebengineview.h>
#include <qimagewriter.h>
+#include <QColorSpace>
+#include <QQuickRenderControl>
+#include <QQuickWindow>
static void removeRecursive(const QString& dirname)
{
QDir dir(dirname);
QFileInfoList entries(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
- for (int i = 0; i < entries.count(); ++i)
+ for (int i = 0; i < entries.size(); ++i)
if (entries[i].isDir())
removeRecursive(entries[i].filePath());
else
@@ -79,6 +89,13 @@ static void removeRecursive(const QString& dirname)
QDir().rmdir(dirname);
}
+struct TestBasePage : QWebEnginePage
+{
+ explicit TestBasePage(QWebEngineProfile *profile, QObject *parent = nullptr) : QWebEnginePage(profile, parent) { }
+ explicit TestBasePage(QObject *parent = nullptr) : QWebEnginePage(parent) { }
+ QSignalSpy loadSpy { this, &QWebEnginePage::loadFinished };
+};
+
class tst_QWebEnginePage : public QObject
{
Q_OBJECT
@@ -95,13 +112,17 @@ public Q_SLOTS:
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
+ void comboBoxPopupPositionAfterMove_data();
void comboBoxPopupPositionAfterMove();
+ void comboBoxPopupPositionAfterChildMove_data();
void comboBoxPopupPositionAfterChildMove();
void acceptNavigationRequest();
void acceptNavigationRequestNavigationType();
void acceptNavigationRequestRelativeToNothing();
+#ifndef Q_OS_MACOS
void geolocationRequestJS_data();
void geolocationRequestJS();
+#endif
void loadFinished();
void actionStates();
void pasteImage();
@@ -142,7 +163,7 @@ private Q_SLOTS:
#endif
void openWindowDefaultSize();
-#ifdef Q_OS_MAC
+#ifdef Q_OS_MACOS
void macCopyUnicodeToClipboard();
#endif
@@ -150,7 +171,8 @@ private Q_SLOTS:
void runJavaScriptDisabled();
void runJavaScriptFromSlot();
void fullScreenRequested();
- void quotaRequested();
+ void requestQuota_data();
+ void requestQuota();
// Tests from tst_QWebEngineFrame
@@ -212,7 +234,13 @@ private Q_SLOTS:
void notificationPermission_data();
void notificationPermission();
void sendNotification();
+ void clipboardReadWritePermissionInitialState_data();
+ void clipboardReadWritePermissionInitialState();
+ void clipboardReadWritePermission_data();
+ void clipboardReadWritePermission();
void contentsSize();
+ void localFontAccessPermission_data();
+ void localFontAccessPermission();
void setLifecycleState();
void setVisible();
@@ -247,20 +275,50 @@ private Q_SLOTS:
void testChooseFilesParameters();
void fileSystemAccessDialog();
+ void localToRemoteNavigation();
+ void clientHints_data();
+ void clientHints();
+ void childFrameInput();
+ void openLinkInNewPageWithWebWindowType_data();
+ void openLinkInNewPageWithWebWindowType();
+ void keepInterceptorAfterNewWindowRequested();
+ void chooseDesktopMedia();
+
private:
- static QPoint elementCenter(QWebEnginePage *page, const QString &id);
static bool isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
static bool isTrueJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
static bool isEmptyListJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
QWebEngineView* m_view;
QWebEnginePage* m_page;
+ QScopedPointer<QPointingDevice> s_touchDevice =
+ QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
+
QString tmpDirPath() const
{
static QString tmpd = QDir::tempPath() + "/tst_qwebenginepage-"
+ QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss"));
return tmpd;
}
+
+ void makeClick(const QPointer<QWindow> window, bool withTouch = false,
+ const QPoint &p = QPoint())
+ {
+ QVERIFY2(window, "window is gone");
+ if (!withTouch) {
+ QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), p);
+ } else {
+ QTest::touchEvent(window, s_touchDevice.get()).press(1, p);
+ QTest::touchEvent(window, s_touchDevice.get()).release(1, p);
+ }
+ };
+
+ void makeScroll(QWidget *target, QPointF pos, QPoint globalPos, QPoint angleDelta)
+ {
+ QWheelEvent ev(pos, globalPos, QPoint(0, 0), angleDelta, Qt::NoButton, Qt::NoModifier,
+ Qt::NoScrollPhase, false);
+ QGuiApplication::sendEvent(target, &ev);
+ }
};
tst_QWebEnginePage::tst_QWebEnginePage()
@@ -306,6 +364,14 @@ void tst_QWebEnginePage::initTestCase()
QWebEngineUrlScheme echo("echo");
echo.setSyntax(QWebEngineUrlScheme::Syntax::Path);
QWebEngineUrlScheme::registerScheme(echo);
+
+ QWebEngineUrlScheme local("local");
+ local.setFlags(QWebEngineUrlScheme::LocalScheme);
+ QWebEngineUrlScheme::registerScheme(local);
+
+ QWebEngineUrlScheme remote("remote");
+ remote.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(remote);
}
void tst_QWebEnginePage::cleanupTestCase()
@@ -358,15 +424,15 @@ void tst_QWebEnginePage::acceptNavigationRequest()
page.setHtml(QString("<html><body><form name='tstform' action='foo' method='get'>"
"<input type='text'><input type='submit'></form></body></html>"),
QUrl("echo:/"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
evaluateJavaScriptSync(&page, "tstform.submit();");
- QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.size(), 2);
// Content hasn't changed so the form submit will still work
page.m_acceptNavigationRequest = true;
evaluateJavaScriptSync(&page, "tstform.submit();");
- QTRY_COMPARE(loadSpy.count(), 3);
+ QTRY_COMPARE(loadSpy.size(), 3);
// Now the content has changed
QCOMPARE(toPlainTextSync(&page), QString("/foo?"));
@@ -402,6 +468,7 @@ private:
bool m_allowGeolocation;
};
+#ifndef Q_OS_MACOS
void tst_QWebEnginePage::geolocationRequestJS_data()
{
QTest::addColumn<bool>("allowed");
@@ -424,7 +491,7 @@ void tst_QWebEnginePage::geolocationRequestJS()
QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
newPage->setHtml(QString("<html><body>test</body></html>"), QUrl("qrc://secure/origin"));
- QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.size(), 1, 20000);
// Geolocation is only enabled for visible WebContents.
view.show();
@@ -441,6 +508,7 @@ void tst_QWebEnginePage::geolocationRequestJS()
QEXPECT_FAIL("", "No location service available.", Continue);
QCOMPARE(result, errorCode);
}
+#endif
void tst_QWebEnginePage::loadFinished()
{
@@ -451,19 +519,19 @@ void tst_QWebEnginePage::loadFinished()
page.load(QUrl("data:text/html,<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>"));
- QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.size(), 1, 20000);
QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(spyLoadStarted.count() > 1, 100);
+ QTRY_VERIFY_WITH_TIMEOUT(spyLoadStarted.size() > 1, 100);
QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(spyLoadFinished.count() > 1, 100);
+ QTRY_VERIFY_WITH_TIMEOUT(spyLoadFinished.size() > 1, 100);
spyLoadFinished.clear();
page.load(QUrl("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
"foo \"><frame src=\"data:text/html,bar\"></frameset>"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QCOMPARE(spyLoadFinished.count(), 1);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
+ QCOMPARE(spyLoadFinished.size(), 1);
}
void tst_QWebEnginePage::actionStates()
@@ -520,6 +588,7 @@ void tst_QWebEnginePage::pasteImage()
QByteArray data = evaluateJavaScriptSync(page, "window.myImageDataURL").toByteArray();
data.remove(0, data.indexOf(";base64,") + 8);
QImage image = QImage::fromData(QByteArray::fromBase64(data), "PNG");
+ image.setColorSpace(origImage.colorSpace());
if (image.format() == QImage::Format_RGB32)
image.reinterpretAsFormat(QImage::Format_ARGB32);
QCOMPARE(image, origImage);
@@ -549,7 +618,7 @@ void tst_QWebEnginePage::consoleOutput()
ConsolePage page;
// We don't care about the result but want this to be synchronous
evaluateJavaScriptSync(&page, "this is not valid JavaScript");
- QCOMPARE(page.messages.count(), 1);
+ QCOMPARE(page.messages.size(), 1);
QCOMPARE(page.lineNumbers.at(0), 1);
}
@@ -608,40 +677,40 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl("qrc:///resources/script.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
- QTRY_COMPARE(page.navigations.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+ QTRY_COMPARE(page.navigations.size(), 1);
page.load(QUrl("qrc:///resources/content.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
- QTRY_COMPARE(page.navigations.count(), 2);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 2, 20000);
+ QTRY_COMPARE(page.navigations.size(), 2);
page.triggerAction(QWebEnginePage::Stop);
QVERIFY(page.history()->canGoBack());
page.triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_COMPARE(page.navigations.count(), 3);
+ QTRY_COMPARE(loadSpy.size(), 3);
+ QTRY_COMPARE(page.navigations.size(), 3);
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy.count(), 4);
- QTRY_COMPARE(page.navigations.count(), 4);
-
- page.load(QUrl("qrc:///resources/reload.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 6, 20000);
- QTRY_COMPARE(page.navigations.count(), 6);
+ QTRY_COMPARE(loadSpy.size(), 4);
+ QTRY_COMPARE(page.navigations.size(), 4);
QList<QWebEngineNavigationRequest::NavigationType> expectedList;
expectedList << QWebEngineNavigationRequest::TypedNavigation
<< QWebEngineNavigationRequest::TypedNavigation
<< QWebEngineNavigationRequest::BackForwardNavigation
- << QWebEngineNavigationRequest::ReloadNavigation
- << QWebEngineNavigationRequest::TypedNavigation
- << QWebEngineNavigationRequest::RedirectNavigation;
+ << QWebEngineNavigationRequest::ReloadNavigation;
// client side redirect
+ page.load(QUrl("qrc:///resources/reload.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 6, 20000);
+ QTRY_COMPARE(page.navigations.size(), 6);
+ expectedList += { QWebEngineNavigationRequest::TypedNavigation, QWebEngineNavigationRequest::RedirectNavigation };
+
+
page.load(QUrl("qrc:///resources/redirect.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 7, 20000);
- QTRY_COMPARE(page.navigations.count(), 8);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 7, 20000);
+ QTRY_COMPARE(page.navigations.size(), 8);
expectedList += { QWebEngineNavigationRequest::TypedNavigation, QWebEngineNavigationRequest::RedirectNavigation };
// server side redirect
@@ -662,18 +731,18 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
});
QVERIFY(server.start());
page.load(QUrl(server.url("/redirect1.html")));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 8, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 8, 20000);
expectedList += {
QWebEngineNavigationRequest::TypedNavigation,
QWebEngineNavigationRequest::RedirectNavigation,
QWebEngineNavigationRequest::RedirectNavigation
};
- for (int i = 0; i < expectedList.count(); ++i) {
- QTRY_VERIFY(i < page.navigations.count());
+ for (int i = 0; i < expectedList.size(); ++i) {
+ QTRY_VERIFY(i < page.navigations.size());
QCOMPARE(page.navigations[i].type, expectedList[i]);
}
- QVERIFY(expectedList.count() == page.navigations.count());
+ QVERIFY(expectedList.size() == page.navigations.size());
}
// Relative url without base url.
@@ -686,18 +755,18 @@ void tst_QWebEnginePage::acceptNavigationRequestRelativeToNothing()
page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
/* baseUrl: */ QUrl());
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 2, 20000);
page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
/* baseUrl: */ QString("qrc:/"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 3, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 3, 20000);
page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 4, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 4, 20000);
// The two setHtml and the second click are counted, while the
// first click is ignored due to the empty base url.
- QCOMPARE(page.navigations.count(), 3);
+ QCOMPARE(page.navigations.size(), 3);
QCOMPARE(page.navigations[0].type, QWebEngineNavigationRequest::TypedNavigation);
QCOMPARE(page.navigations[1].type, QWebEngineNavigationRequest::TypedNavigation);
QCOMPARE(page.navigations[2].type, QWebEngineNavigationRequest::LinkClickedNavigation);
@@ -716,20 +785,19 @@ void tst_QWebEnginePage::popupFormSubmission()
page.setHtml("<form name='form1' method=get action='' target='myNewWin'>"
" <input type='hidden' name='foo' value='bar'>"
"</form>", QUrl("echo:"));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
page.runJavaScript("window.open('', 'myNewWin', 'width=500,height=300,toolbar=0');");
evaluateJavaScriptSync(&page, "document.form1.submit();");
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
// The number of popup created should be one.
QVERIFY(page.createdWindows.size() == 1);
QTRY_VERIFY(!page.createdWindows[0]->url().isEmpty());
- QString url = page.createdWindows[0]->url().toString();
// Check if the form submission was OK.
- QVERIFY(url.contains("?foo=bar"));
+ QTRY_VERIFY(page.createdWindows[0]->url().toString().contains("?foo=bar"));
}
class TestNetworkManager : public QNetworkAccessManager
@@ -770,16 +838,16 @@ void tst_QWebEnginePage::multipleProfilesAndLocalStorage()
page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.count(), 1, 20000);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.size(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.size(), 1, 20000);
evaluateJavaScriptSync(&page1, "localStorage.setItem('test', 'value1');");
evaluateJavaScriptSync(&page2, "localStorage.setItem('test', 'value2');");
page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
- QTRY_COMPARE(loadSpy1.count(), 2);
- QTRY_COMPARE(loadSpy2.count(), 2);
+ QTRY_COMPARE(loadSpy1.size(), 2);
+ QTRY_COMPARE(loadSpy2.size(), 2);
QVariant s1 = evaluateJavaScriptSync(&page1, "localStorage.getItem('test')");
QCOMPARE(s1.toString(), QString("value1"));
@@ -828,7 +896,7 @@ void tst_QWebEnginePage::textSelection()
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(content);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
// these actions must exist
QVERIFY(page.action(QWebEnginePage::SelectAll) != 0);
@@ -855,7 +923,7 @@ void tst_QWebEnginePage::textSelection()
// navigate away and check that selection is cleared
page.load(QUrl("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.size(), 2);
QVERIFY(!page.hasSelection());
QVERIFY(page.selectedText().isEmpty());
@@ -876,7 +944,7 @@ void tst_QWebEnginePage::backActionUpdate()
QVERIFY(!action->isEnabled());
page->load(QUrl("qrc:///resources/framedindex.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
QVERIFY(!action->isEnabled());
auto firstAnchorCenterInFrame = [](QWebEnginePage *page, const QString &frameName) {
@@ -888,7 +956,7 @@ void tst_QWebEnginePage::backActionUpdate()
"return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
"})()").toList();
- if (rectList.count() != 2) {
+ if (rectList.size() != 2) {
qWarning("firstAnchorCenterInFrame failed.");
return QPoint();
}
@@ -915,8 +983,8 @@ void tst_QWebEnginePage::localStorageVisibility()
QSignalSpy loadSpy2(&webPage2, &QWebEnginePage::loadFinished);
webPage1.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
webPage2.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.count(), 1, 20000);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.size(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.size(), 1, 20000);
// The attribute determines the visibility of the window.localStorage object.
QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
@@ -929,13 +997,14 @@ void tst_QWebEnginePage::localStorageVisibility()
// ...first check second page (for storage to appear) as applying settings is batched and done asynchronously
QTRY_VERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
// Switching the feature off does not actively remove the object from webPage1.
- QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+// FIXME: 94-based: now it does
+// QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
// The object disappears only after reloading.
webPage1.triggerAction(QWebEnginePage::Reload);
webPage2.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy1.count(), 2);
- QTRY_COMPARE(loadSpy2.count(), 2);
+ QTRY_COMPARE(loadSpy1.size(), 2);
+ QTRY_COMPARE(loadSpy2.size(), 2);
QVERIFY(!evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
}
@@ -1036,7 +1105,7 @@ void tst_QWebEnginePage::testJSPrompt()
bool res;
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(QStringLiteral("<html><body></body></html>"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
// OK + QString()
res = evaluateJavaScriptSync(&page,
@@ -1070,7 +1139,7 @@ void tst_QWebEnginePage::findText()
// Showing is required, otherwise all find operations fail.
m_view->show();
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// Select whole page contents.
QTRY_VERIFY(m_view->page()->action(QWebEnginePage::SelectAll)->isEnabled());
@@ -1084,7 +1153,7 @@ void tst_QWebEnginePage::findText()
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("", {}, callbackSpy.ref());
QVERIFY(callbackSpy.wasCalled());
- QCOMPARE(signalSpy.count(), 1);
+ QCOMPARE(signalSpy.size(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo bar"));
}
@@ -1095,7 +1164,7 @@ void tst_QWebEnginePage::findText()
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("Will not be found", {}, callbackSpy.ref());
QCOMPARE(callbackSpy.waitForResult().numberOfMatches(), 0);
- QTRY_COMPARE(signalSpy.count(), 1);
+ QTRY_COMPARE(signalSpy.size(), 1);
auto result = signalSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 0);
QTRY_VERIFY(m_view->selectedText().isEmpty());
@@ -1112,7 +1181,7 @@ void tst_QWebEnginePage::findText()
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("foo", {}, callbackSpy.ref());
QVERIFY(callbackSpy.waitForResult().numberOfMatches() > 0);
- QTRY_COMPARE(signalSpy.count(), 1);
+ QTRY_COMPARE(signalSpy.size(), 1);
QTRY_VERIFY(m_view->selectedText().isEmpty());
}
@@ -1123,7 +1192,7 @@ void tst_QWebEnginePage::findText()
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("", {}, callbackSpy.ref());
QTRY_VERIFY(callbackSpy.wasCalled());
- QTRY_COMPARE(signalSpy.count(), 1);
+ QTRY_COMPARE(signalSpy.size(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo"));
}
@@ -1133,7 +1202,7 @@ void tst_QWebEnginePage::findText()
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("foo", {});
m_view->findText("foo", {});
- QTRY_COMPARE(signalSpy.count(), 2);
+ QTRY_COMPARE(signalSpy.size(), 2);
QTRY_VERIFY(m_view->selectedText().isEmpty());
QCOMPARE(signalSpy.at(0).value(0).value<QWebEngineFindTextResult>().numberOfMatches(), 0);
@@ -1145,7 +1214,7 @@ void tst_QWebEnginePage::findTextResult()
{
QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished);
auto signalResult = [&findTextSpy]() -> QList<int> {
- if (findTextSpy.count() != 1)
+ if (findTextSpy.size() != 1)
return QList<int>({-1, -1});
auto r = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
return QList<int>({ r.numberOfMatches(), r.activeMatch() });
@@ -1157,7 +1226,7 @@ void tst_QWebEnginePage::findTextResult()
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(findTextSync(m_page, ""), false);
QCOMPARE(signalResult(), QList<int>({0, 0}));
@@ -1186,7 +1255,7 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
CallbackSpy<QWebEngineFindTextResult> spy5;
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
m_view->setHtml(QString("<html><head></head><body><div>abcdefg abcdefg abcdefg abcdefg abcdefg</div></body></html>"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
m_page->findText("abcde", {}, spy1.ref());
m_page->findText("abcd", {}, spy2.ref());
m_page->findText("abc", {}, spy3.ref());
@@ -1208,7 +1277,7 @@ void tst_QWebEnginePage::findTextCalledOnMatch()
m_view->resize(800, 600);
m_view->show();
m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// CALLBACK
bool callbackCalled = false;
@@ -1245,12 +1314,12 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
m_view->resize(800, 600);
m_view->show();
m_view->setHtml(QString("<html><head></head><body><div>foo bar foo bar foo</div></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// Iterate over all "foo" matches.
for (int i = 1; i <= 3; ++i) {
m_view->page()->findText("foo", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
QCOMPARE(result.activeMatch(), i);
@@ -1258,28 +1327,28 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
// The last match is followed by the fist one.
m_view->page()->findText("foo", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
QCOMPARE(result.activeMatch(), 1);
// The first match is preceded by the last one.
m_view->page()->findText("foo", QWebEnginePage::FindBackward);
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
QCOMPARE(result.activeMatch(), 3);
// Finding another word resets the activeMatch.
m_view->page()->findText("bar", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 2);
QCOMPARE(result.activeMatch(), 1);
// If no match activeMatch is 0.
m_view->page()->findText("bla", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 0);
QCOMPARE(result.activeMatch(), 0);
@@ -1289,45 +1358,60 @@ static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
{
const auto tlws = QGuiApplication::topLevelWindows();
for (auto w : tlws) {
- if (!oldTopLevelWindows.contains(w)) {
+ // note 'offscreen' window is a top-level window
+ if (!oldTopLevelWindows.contains(w)
+ && !QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(w))) {
return w;
}
}
return nullptr;
}
+void tst_QWebEnginePage::comboBoxPopupPositionAfterMove_data()
+{
+ QTest::addColumn<bool>("withTouch");
+ QTest::addRow("mouse") << false;
+ QTest::addRow("touch") << true;
+}
+
void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
{
+#if defined(Q_OS_MACOS) && (defined(__arm64__) || defined(__aarch64__))
+ QSKIP("This test crashes for Apple M1");
+#endif
QWebEngineView view;
+ QTRY_VERIFY(QGuiApplication::primaryScreen());
view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
view.resize(640, 480);
view.show();
-
- QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QSignalSpy spyLoadFinished(&view, SIGNAL(loadFinished(bool)));
view.setHtml(QLatin1String("<html><head></head><body><select id='foo'>"
"<option>fran</option><option>troz</option>"
"</select></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
const auto oldTlws = QGuiApplication::topLevelWindows();
- QWindow *window = view.windowHandle();
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- elementCenter(view.page(), "foo"));
-
+ QFETCH(bool, withTouch);
+ QPointer<QWindow> window = view.windowHandle();
+ auto pos = elementCenter(view.page(), "foo");
+ makeClick(window, withTouch, pos);
QWindow *popup = nullptr;
- QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
-
+ QPointer<QWindow> pw(popup);
// Close the popup by clicking somewhere into the page.
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
+ makeClick(window, withTouch, QPoint(1, 1));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
-
+ QTRY_VERIFY(!pw);
auto jsViewPosition = [&view]() {
QLatin1String script("(function() { return [window.screenX, window.screenY]; })()");
QVariantList posList = evaluateJavaScriptSync(view.page(), script).toList();
- if (posList.count() != 2) {
+ if (posList.size() != 2) {
qWarning("jsViewPosition failed.");
return QPoint();
}
@@ -1339,18 +1423,28 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
const QPoint offset(12, 13);
view.move(view.pos() + offset);
QTRY_COMPARE(jsViewPosition(), view.pos());
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- elementCenter(view.page(), "foo"));
- QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ makeClick(window, withTouch, elementCenter(view.page(), "foo"));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + offset, popup->position());
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
+ makeClick(window, withTouch, QPoint(1, 1));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
}
+void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove_data()
+{
+ QTest::addColumn<bool>("withTouch");
+ QTest::addRow("mouse") << false;
+ QTest::addRow("touch") << true;
+}
+
void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
{
+#if defined(Q_OS_MACOS) && (defined(__arm64__) || defined(__aarch64__))
+ QSKIP("This test crashes for Apple M1");
+#endif
QWidget mainWidget;
mainWidget.setLayout(new QHBoxLayout);
@@ -1361,29 +1455,33 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
mainWidget.layout()->addWidget(&view);
QScreen *screen = QGuiApplication::primaryScreen();
+ Q_ASSERT(screen);
mainWidget.move(screen->availableGeometry().topLeft());
mainWidget.resize(640, 480);
mainWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWidget));
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(QLatin1String("<html><head></head><body><select autofocus id='foo'>"
"<option value=\"narf\">narf</option><option>zort</option>"
"</select></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
const auto oldTlws = QGuiApplication::topLevelWindows();
- QWindow *window = view.window()->windowHandle();
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- view.mapTo(view.window(), elementCenter(view.page(), "foo")));
+
+ QFETCH(bool, withTouch);
+ QPointer<QWindow> window = view.window()->windowHandle();
+ makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo")));
QWindow *popup = nullptr;
- QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
// Close the popup by clicking somewhere into the page.
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- view.mapTo(view.window(), QPoint(1, 1)));
+ makeClick(window, withTouch, view.mapTo(view.window(), QPoint(1, 1)));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
int originalViewWidth = view.size().width();
@@ -1393,19 +1491,25 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
return viewWidth;
};
+ QCOMPARE(jsViewWidth(), originalViewWidth);
+
// Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView.
const int offset = 50;
spacer.setMinimumWidth(spacer.size().width() + offset);
+
QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset);
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- view.mapTo(view.window(), elementCenter(view.page(), "foo")));
- QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo")));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(!popup->position().isNull());
- QCOMPARE(popupPos + QPoint(50, 0), popup->position());
+ QCOMPARE(popupPos + QPoint(offset, 0), popup->position());
+ makeClick(window, withTouch, QPoint(1, 1));
+ QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
}
-#ifdef Q_OS_MAC
+#ifdef Q_OS_MACOS
void tst_QWebEnginePage::macCopyUnicodeToClipboard()
{
QString unicodeText = QString::fromUtf8("αβγδεζηθικλμπ");
@@ -1799,14 +1903,14 @@ void tst_QWebEnginePage::openWindowDefaultSize()
page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
view.setUrl(QUrl("about:blank"));
view.show();
- QTRY_COMPARE(spyFinished.count(), 1);
+ QTRY_COMPARE(spyFinished.size(), 1);
// Open a default window.
page.runJavaScript("window.open()");
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
// Open a too small window.
evaluateJavaScriptSync(&page, "window.open('','about:blank','width=10,height=10')");
- QTRY_COMPARE(windowCreatedSpy.count(), 2);
+ QTRY_COMPARE(windowCreatedSpy.size(), 2);
// The number of popups created should be two.
QCOMPARE(page.createdWindows.size(), 2);
@@ -1877,7 +1981,7 @@ void tst_QWebEnginePage::runJavaScriptDisabled()
// Settings changes take effect asynchronously. The load and wait ensure
// that the settings are applied by the time we start to execute JavaScript.
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, QStringLiteral("1+1"), QWebEngineScript::MainWorld),
QVariant());
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, QStringLiteral("1+1"), QWebEngineScript::ApplicationWorld),
@@ -1894,7 +1998,7 @@ void tst_QWebEnginePage::runJavaScriptFromSlot()
page.setHtml("<html><body>"
" <input type='text' id='input1' value='QtWebEngine' size='50' />"
"</body></html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
bool done = false;
connect(&page, &QWebEnginePage::selectionChanged, [&]() {
@@ -1918,7 +2022,7 @@ void tst_QWebEnginePage::fullScreenRequested()
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
page->load(QUrl("qrc:///resources/fullscreen.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QTRY_VERIFY(isTrueJavaScriptResult(page, "document.webkitFullscreenEnabled"));
QVERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
@@ -1935,7 +2039,7 @@ void tst_QWebEnginePage::fullScreenRequested()
QTest::mouseMove(view.windowHandle(), QPoint(10,10));
QTest::mouseClick(view.windowHandle(), Qt::RightButton);
- QTRY_COMPARE(view.findChildren<QMenu *>().count(), 1);
+ QTRY_COMPARE(view.findChildren<QMenu *>().size(), 1);
auto menu = view.findChildren<QMenu *>().first();
QVERIFY(menu->actions().contains(page->action(QWebEnginePage::ExitFullScreen)));
@@ -1949,8 +2053,18 @@ void tst_QWebEnginePage::fullScreenRequested()
QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
}
-void tst_QWebEnginePage::quotaRequested()
+void tst_QWebEnginePage::requestQuota_data()
+{
+ QTest::addColumn<QString>("storage");
+ QTest::addRow("webkitPersistentStorage") << "navigator.webkitPersistentStorage";
+ QTest::addRow("webkitTemporaryStorage") << "navigator.webkitTemporaryStorage";
+
+}
+
+void tst_QWebEnginePage::requestQuota()
{
+ QFETCH(QString, storage);
+
ConsolePage page;
QWebEngineView view;
view.setPage(&page);
@@ -1958,35 +2072,23 @@ void tst_QWebEnginePage::quotaRequested()
page.load(QUrl("qrc:///resources/content.html"));
QVERIFY(loadFinishedSpy.wait());
- connect(&page, &QWebEnginePage::quotaRequested,
- [] (QWebEngineQuotaRequest request)
- {
- if (request.requestedSize() <= 5000)
- request.accept();
- else
- request.reject();
- });
-
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.requestQuota(1024, function(grantedSize) {" \
- "console.log(grantedSize);" \
- "});");
- QTRY_COMPARE(page.messages.count(), 1);
+ evaluateJavaScriptSync(&page, QString(
+ "var storage = %1;"
+ "storage.requestQuota(1024, function(grantedSize) {"
+ " console.log(grantedSize);"
+ "});").arg(storage));
+ QTRY_COMPARE(page.messages.size(), 1);
QTRY_COMPARE(page.messages[0], QString("1024"));
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.requestQuota(6000, function(grantedSize) {" \
- "console.log(grantedSize);" \
- "});");
- QTRY_COMPARE(page.messages.count(), 2);
- QTRY_COMPARE(page.messages[1], QString("1024"));
-
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.queryUsageAndQuota(function(usedBytes, grantedBytes) {" \
- "console.log(usedBytes + ', ' + grantedBytes);" \
- "});");
- QTRY_COMPARE(page.messages.count(), 3);
- QTRY_COMPARE(page.messages[2], QString("0, 1024"));
+ evaluateJavaScriptSync(&page, QString(
+ "var storage = %1;"
+ "storage.queryUsageAndQuota(function(usedBytes, grantedBytes) {"
+ " console.log(usedBytes);"
+ " console.log(grantedBytes);"
+ "});").arg(storage));
+ QTRY_COMPARE(page.messages.size(), 3);
+ QTRY_COMPARE(page.messages[1], QString("0"));
+ QTRY_VERIFY(page.messages[2].toLongLong() >= 1024);
}
void tst_QWebEnginePage::symmetricUrl()
@@ -2008,7 +2110,7 @@ void tst_QWebEnginePage::symmetricUrl()
// loading is _not_ immediate, so the text isn't set just yet.
QVERIFY(toPlainTextSync(view.page()).isEmpty());
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
QCOMPARE(view.history()->count(), 1);
QCOMPARE(toPlainTextSync(view.page()), QString("Test"));
@@ -2022,8 +2124,8 @@ void tst_QWebEnginePage::symmetricUrl()
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);
+ QTRY_VERIFY(loadFinishedSpy.size() >= 2);
+ QTRY_VERIFY(loadFinishedSpy.size() <= 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.
@@ -2101,7 +2203,7 @@ public:
setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html"));
QTimer::singleShot(0, this, SLOT(continueRedirect()));
}
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) {
setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error!"));
QTimer::singleShot(0, this, SLOT(continueError()));
@@ -2158,7 +2260,7 @@ protected:
{
QString url = request.url().toString();
if (op == QNetworkAccessManager::GetOperation) {
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
if (url == "qrc:/fake-ssl-error.html") {
FakeReply* reply = new FakeReply(request, this);
QList<QSslError> errors;
@@ -2182,7 +2284,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
const QUrl first("http://abcdef.abcdef/");
page.setUrl(first);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QCOMPARE(page.url(), first);
QCOMPARE(page.requestedUrl(), first);
QVERIFY(!spy.at(0).first().toBool());
@@ -2191,7 +2293,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
QVERIFY(first != second);
page.load(second);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
QCOMPARE(page.url(), first);
QCOMPARE(page.requestedUrl(), second);
QVERIFY(!spy.at(1).first().toBool());
@@ -2237,7 +2339,7 @@ void tst_QWebEnginePage::setHtmlWithImageResource()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(html, QUrl("file:///path/to/file"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 12000);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
@@ -2246,7 +2348,7 @@ void tst_QWebEnginePage::setHtmlWithImageResource()
// Now we test the opposite: without a baseUrl as a local file, we can still request qrc resources.
page.setHtml(html);
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.size(), 2);
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);
@@ -2309,7 +2411,7 @@ void tst_QWebEnginePage::setHtmlWithBaseURL()
QString("%1/foo.html").arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath())));
QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QVERIFY(spyFinished.wait());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
@@ -2372,7 +2474,7 @@ void tst_QWebEnginePage::setHtmlWithModuleImport()
QWebEnginePage page;
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
page.setHtml(html, server.url());
- QVERIFY(spy.count() || spy.wait());
+ QVERIFY(spy.size() || spy.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "fib7"), QVariant(13));
}
@@ -2408,7 +2510,7 @@ void tst_QWebEnginePage::baseUrl()
QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
m_page->setHtml(html, loadUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 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);
@@ -2417,7 +2519,8 @@ void tst_QWebEnginePage::baseUrl()
void tst_QWebEnginePage::scrollPosition()
{
// 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>");
+ QString html(
+ "<html><body><img src='qrc:/resources/image.png' height=500 width=500/></body></html>");
QWebEngineView view;
view.setFixedSize(200,200);
@@ -2427,12 +2530,12 @@ void tst_QWebEnginePage::scrollPosition()
QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// try to set the scroll offset programmatically
view.page()->runJavaScript("window.scrollTo(23, 29);");
- QTRY_COMPARE(view.page()->scrollPosition().x(), 23 * view.windowHandle()->devicePixelRatio());
- QCOMPARE(view.page()->scrollPosition().y(), 29 * view.windowHandle()->devicePixelRatio());
+ QTRY_COMPARE(view.page()->scrollPosition().x(), 23);
+ QCOMPARE(view.page()->scrollPosition().y(), 29);
int x = evaluateJavaScriptSync(view.page(), "window.scrollX").toInt();
int y = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt();
@@ -2453,7 +2556,7 @@ void tst_QWebEnginePage::scrollbarsOff()
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool());
}
@@ -2488,7 +2591,7 @@ void tst_QWebEnginePage::evaluateWillCauseRepaint()
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
evaluateJavaScriptSync(view.page(), "document.getElementById('junk').style.display = 'none';");
QSignalSpy repaintSpy(&view, &WebView::repaintRequested);
@@ -2582,7 +2685,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
expectedLoadFinishedCount++;
QVERIFY(spy.wait());
- QCOMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), url);
QCOMPARE(page.requestedUrl(), url);
QCOMPARE(baseUrlSync(&page), url);
@@ -2591,7 +2694,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
page.setUrl(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), aboutBlank);
QCOMPARE(page.requestedUrl(), QUrl());
QCOMPARE(baseUrlSync(&page), aboutBlank);
@@ -2600,7 +2703,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
page.setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), url);
QCOMPARE(page.requestedUrl(), url);
QCOMPARE(baseUrlSync(&page), url);
@@ -2609,7 +2712,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
page.load(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), aboutBlank);
QCOMPARE(page.requestedUrl(), QUrl());
QCOMPARE(baseUrlSync(&page), aboutBlank);
@@ -2664,9 +2767,9 @@ void tst_QWebEnginePage::setUrlToBadDomain()
page.setUrl(url1);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE_WITH_TIMEOUT(titleSpy.count(), 1, 20000);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(titleSpy.size(), 1, 20000);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.host());
@@ -2677,9 +2780,9 @@ void tst_QWebEnginePage::setUrlToBadDomain()
page.setUrl(url2);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE_WITH_TIMEOUT(titleSpy.count(), 1, 20000);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(titleSpy.size(), 1, 20000);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.host());
@@ -2703,9 +2806,9 @@ void tst_QWebEnginePage::setUrlToBadPort()
page.setUrl(url1);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE(titleSpy.count(), 2);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(titleSpy.size(), 2);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.authority());
@@ -2717,9 +2820,9 @@ void tst_QWebEnginePage::setUrlToBadPort()
page.setUrl(url2);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE(titleSpy.count(), 2);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(titleSpy.size(), 2);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.authority());
@@ -2750,7 +2853,7 @@ void tst_QWebEnginePage::setUrlHistory()
m_page->setUrl(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), 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.
@@ -2759,7 +2862,7 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("http://url.invalid/");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), expectedLoadFinishedCount, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), expectedLoadFinishedCount, 20000);
// 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);
@@ -2770,14 +2873,14 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), 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);
+ QTRY_COMPARE(spy.size(), 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.
@@ -2789,7 +2892,7 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
// The history count DOES change since the about:blank is in the list.
@@ -2802,7 +2905,7 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("qrc:/resources/test2.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
@@ -2817,6 +2920,7 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
{
QUrl url;
QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
int expectedUrlChangeCount = 0;
QCOMPARE(m_page->history()->count(), 0);
@@ -2824,20 +2928,22 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
+ QCOMPARE(m_page->url(), url);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(m_page->url(), url);
- QTRY_COMPARE(m_page->history()->count(), 1);
+ QCOMPARE(m_page->history()->count(), 1);
evaluateJavaScriptSync(m_page, "window.history.pushState(null, 'push', 'navigate/to/here')");
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), 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++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/another/location"));
QCOMPARE(m_page->history()->count(), 2);
QVERIFY(!m_page->history()->canGoForward());
@@ -2845,7 +2951,7 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
evaluateJavaScriptSync(m_page, "window.history.back()");
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/test1.html"));
QVERIFY(m_page->history()->canGoForward());
QVERIFY(!m_page->history()->canGoBack());
@@ -2874,9 +2980,9 @@ void tst_QWebEnginePage::setUrlThenLoads()
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);
+ QTRY_COMPARE(startedSpy.size(), 1);
+ QTRY_COMPARE(urlChangedSpy.size(), 1);
+ QTRY_COMPARE(finishedSpy.size(), 1);
QVERIFY(finishedSpy.at(0).first().toBool());
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
@@ -2890,11 +2996,11 @@ void tst_QWebEnginePage::setUrlThenLoads()
QTRY_COMPARE(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);
+ QTRY_COMPARE(startedSpy.size(), 2);
// After first URL changed.
- QTRY_COMPARE(urlChangedSpy.count(), 2);
- QTRY_COMPARE(finishedSpy.count(), 2);
+ QTRY_COMPARE(urlChangedSpy.size(), 2);
+ QTRY_COMPARE(finishedSpy.size(), 2);
QVERIFY(finishedSpy.at(1).first().toBool());
QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
@@ -2904,11 +3010,11 @@ void tst_QWebEnginePage::setUrlThenLoads()
QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
- QTRY_COMPARE(startedSpy.count(), 3);
+ QTRY_COMPARE(startedSpy.size(), 3);
// After second URL changed.
- QTRY_COMPARE(urlChangedSpy.count(), 3);
- QTRY_COMPARE(finishedSpy.count(), 3);
+ QTRY_COMPARE(urlChangedSpy.size(), 3);
+ QTRY_COMPARE(finishedSpy.size(), 3);
QVERIFY(finishedSpy.at(2).first().toBool());
QCOMPARE(m_page->url(), urlToLoad2);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
@@ -2996,7 +3102,7 @@ void tst_QWebEnginePage::loadInSignalHandlers()
URLSetter setter(m_page, signal, type, urlForSetter);
QSignalSpy spy(&setter, &URLSetter::finished);
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_VERIFY_WITH_TIMEOUT(spy.size() >= 1, 20000);
QCOMPARE(m_page->url(), urlForSetter);
}
@@ -3007,31 +3113,31 @@ void tst_QWebEnginePage::loadFromQrc()
// Standard case.
page.load(QStringLiteral("qrc:///resources/foo.txt"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("foo\n"));
// Query and fragment parts are ignored.
page.load(QStringLiteral("qrc:///resources/bar.txt?foo=1#bar"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("bar\n"));
// Literal spaces are OK.
page.load(QStringLiteral("qrc:///resources/path with spaces.txt"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));
// Escaped spaces are OK too.
page.load(QStringLiteral("qrc:///resources/path%20with%20spaces.txt"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));
// Resource not found, loading fails.
page.load(QStringLiteral("qrc:///nope"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 10000);
QCOMPARE(spy.takeFirst().value(0).toBool(), false);
}
@@ -3048,7 +3154,7 @@ void tst_QWebEnginePage::restoreHistory()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl(QStringLiteral("qrc:/resources/test1.html")));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(page.webChannel(), &channel);
QVERIFY(page.scripts().contains(script));
@@ -3058,7 +3164,7 @@ void tst_QWebEnginePage::restoreHistory()
out << *page.history();
QDataStream in(&data, QIODevice::ReadOnly);
in >> *page.history();
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.size(), 2);
QCOMPARE(page.webChannel(), &channel);
QVERIFY(page.scripts().contains(script));
@@ -3081,42 +3187,59 @@ void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
QSignalSpy spy(page.data(), SIGNAL(loadFinished(bool)));
page->load(QUrl("data:text/plain,foobarbaz"));
- QTRY_VERIFY(spy.count() == 1);
+ QTRY_VERIFY(spy.size() == 1);
QCOMPARE(toPlainTextSync(page.data()), QString("foobarbaz"));
page->load(QUrl("http://fail.invalid/"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
QString s = toPlainTextSync(page.data());
QVERIFY(s.contains("foobarbaz") == !enableErrorPage);
page->load(QUrl("data:text/plain,lalala"));
- QTRY_COMPARE(spy.count(), 3);
+ QTRY_COMPARE(spy.size(), 3);
QTRY_COMPARE(toPlainTextSync(page.data()), QString("lalala"));
page.reset();
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
}
void tst_QWebEnginePage::setZoomFactor()
{
- QWebEnginePage page;
+ TestBasePage page, page2;
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 1.0));
+ QCOMPARE(page.zoomFactor(), 1.0);
page.setZoomFactor(2.5);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ QCOMPARE(page.zoomFactor(), 2.5);
- const QUrl urlToLoad("qrc:/resources/test1.html");
+ const QUrl url1("qrc:/resources/test1.html"), url2(QUrl("qrc:/resources/test2.html"));
- QSignalSpy finishedSpy(&page, SIGNAL(loadFinished(bool)));
- page.load(urlToLoad);
- QTRY_COMPARE(finishedSpy.count(), 1);
- QVERIFY(finishedSpy.at(0).first().toBool());
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ page.load(url1);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.at(0).first().toBool());
+ QCOMPARE(page.zoomFactor(), 2.5);
- page.setZoomFactor(5.5);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ page.setZoomFactor(5.5); // max accepted zoom: kMaximumPageZoomFactor = 5.0
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ page.setZoomFactor(0.1); // min accepted zoom: kMinimumPageZoomFactor = 0.25
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ // try loading different url and check new values after load
+ page.loadSpy.clear();
+ for (auto &&p : {
+ qMakePair(&page, 2.5), // navigating away to different url should keep zoom
+ qMakePair(&page2, 1.0), // same url navigation in diffent page shouldn't be affected
+ }) {
+ auto &&page = *p.first; auto zoomFactor = p.second;
+ page.load(url2);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.last().first().toBool());
+ QCOMPARE(page.zoomFactor(), zoomFactor);
+ }
- page.setZoomFactor(0.1);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ // should have no influence on first page
+ page2.setZoomFactor(3.5);
+ for (auto &&p : { qMakePair(&page, 2.5), qMakePair(&page2, 3.5), })
+ QCOMPARE(p.first->zoomFactor(), p.second);
}
void tst_QWebEnginePage::mouseButtonTranslation()
@@ -3136,17 +3259,20 @@ void tst_QWebEnginePage::mouseButtonTranslation()
view.resize(640, 480);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QTRY_VERIFY(spy.count() == 1);
+ QTRY_VERIFY(spy.size() == 1);
QVERIFY(view.focusProxy() != nullptr);
- QMouseEvent evpres(QEvent::MouseButtonPress, view.rect().center(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ const QPoint mousePos = view.rect().center();
+ QMouseEvent evpres(QEvent::MouseButtonPress, mousePos, view.mapToGlobal(mousePos),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(view.focusProxy(), &evpres);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 0);
QCOMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.buttons").toInt(), 1);
- QMouseEvent evpres2(QEvent::MouseButtonPress, view.rect().center(), Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
+ QMouseEvent evpres2(QEvent::MouseButtonPress, mousePos, view.mapToGlobal(mousePos),
+ Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
QGuiApplication::sendEvent(view.focusProxy(), &evpres2);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 2);
@@ -3175,34 +3301,17 @@ void tst_QWebEnginePage::mouseMovementProperties()
loadFinishedSpy.wait();
QTest::mouseMove(&view, QPoint(20, 20));
- QTRY_COMPARE(page.messages.count(), 1);
+ QTRY_COMPARE(page.messages.size(), 1);
QTest::mouseMove(&view, QPoint(30, 30));
- QTRY_COMPARE(page.messages.count(), 2);
+ QTRY_COMPARE(page.messages.size(), 2);
QTRY_COMPARE(page.messages[1], QString("10, 10"));
QTest::mouseMove(&view, QPoint(20, 20));
- QTRY_COMPARE(page.messages.count(), 3);
+ QTRY_COMPARE(page.messages.size(), 3);
QTRY_COMPARE(page.messages[2], QString("-10, -10"));
}
-QPoint tst_QWebEnginePage::elementCenter(QWebEnginePage *page, const QString &id)
-{
- QVariantList rectList = evaluateJavaScriptSync(page,
- "(function(){"
- "var elem = document.getElementById('" + id + "');"
- "var rect = elem.getBoundingClientRect();"
- "return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
- "})()").toList();
-
- if (rectList.count() != 2) {
- qWarning("elementCenter failed.");
- return QPoint();
- }
-
- return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
-}
-
void tst_QWebEnginePage::viewSource()
{
TestPage page;
@@ -3211,12 +3320,12 @@ void tst_QWebEnginePage::viewSource()
const QUrl url("qrc:/resources/test1.html");
page.load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(page.title(), QStringLiteral("Test page 1"));
QVERIFY(page.action(QWebEnginePage::ViewSource)->isEnabled());
page.triggerAction(QWebEnginePage::ViewSource);
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
QCOMPARE(page.createdWindows.size(), 1);
QTRY_COMPARE(page.createdWindows[0]->url().toString(), QStringLiteral("view-source:%1").arg(url.toString()));
@@ -3271,7 +3380,7 @@ void tst_QWebEnginePage::viewSourceURL()
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.load(userInputUrl);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 12000);
QList<QVariant> arguments = loadFinishedSpy.takeFirst();
QCOMPARE(arguments.at(0).toBool(), loadSucceed);
@@ -3306,7 +3415,7 @@ void tst_QWebEnginePage::viewSourceCredentials()
QVERIFY(page.action(QWebEnginePage::ViewSource)->isEnabled());
page.triggerAction(QWebEnginePage::ViewSource);
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
QCOMPARE(page.createdWindows.size(), 1);
QTRY_COMPARE(page.createdWindows[0]->url().toString(), QString("view-source:" + url.toDisplayString(QUrl::RemoveUserInfo)));
@@ -3328,7 +3437,7 @@ void tst_QWebEnginePage::proxyConfigWithUnexpectedHostPortPair()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
m_page->load(QStringLiteral("http://127.0.0.1:245/"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
}
void tst_QWebEnginePage::registerProtocolHandler_data()
@@ -3361,7 +3470,7 @@ void tst_QWebEnginePage::registerProtocolHandler()
QSignalSpy permissionSpy(&page, &QWebEnginePage::registerProtocolHandlerRequested);
page.setUrl(server.url("/"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
QString callFormat = QStringLiteral("window.navigator.registerProtocolHandler(\"%1\", \"%2\", \"%3\")");
@@ -3371,7 +3480,7 @@ void tst_QWebEnginePage::registerProtocolHandler()
QString call = callFormat.arg(scheme).arg(url).arg(title);
page.runJavaScript(call);
- QTRY_COMPARE(permissionSpy.count(), 1);
+ QTRY_COMPARE(permissionSpy.size(), 1);
auto request = permissionSpy.takeFirst().value(0).value<QWebEngineRegisterProtocolHandlerRequest>();
QCOMPARE(request.origin(), QUrl(url));
QCOMPARE(request.scheme(), scheme);
@@ -3382,7 +3491,7 @@ void tst_QWebEnginePage::registerProtocolHandler()
page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), permission);
QCOMPARE(mailRequestCount, permission ? 1 : 0);
QVERIFY(server.stop());
@@ -3398,7 +3507,7 @@ void tst_QWebEnginePage::dataURLFragment()
m_page->setHtml("<html><body>"
"<a id='link' href='#anchor'>anchor</a>"
"</body></html>", QUrl("http://test.qt.io/mytest.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
QVERIFY(urlChangedSpy.wait());
@@ -3422,7 +3531,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage1);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 90000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(&inspectedPage2);
@@ -3434,7 +3543,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage2);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 90000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(nullptr);
@@ -3445,6 +3554,8 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(inspectedPage2.inspectedPage(), nullptr);
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), nullptr);
+
+ QVERIFY(!inspectedPage1.devToolsId().isEmpty());
}
void tst_QWebEnginePage::openLinkInDifferentProfile()
@@ -3466,11 +3577,11 @@ void tst_QWebEnginePage::openLinkInDifferentProfile()
page1.setHtml("<html><body>"
"<a id='link' href='hello'>link</a>"
"</body></html>", QUrl("echo:/"));
- QTRY_COMPARE(spy1.count(), 1);
+ QTRY_COMPARE(spy1.size(), 1);
QVERIFY(spy1.takeFirst().value(0).toBool());
targetPage = &page2;
QTest::mouseClick(view.focusProxy(), Qt::MiddleButton, {}, elementCenter(&page1, "link"));
- QTRY_COMPARE(spy2.count(), 1);
+ QTRY_COMPARE(spy2.size(), 1);
QVERIFY(spy2.takeFirst().value(0).toBool());
}
@@ -3580,7 +3691,7 @@ void tst_QWebEnginePage::openLinkInNewPage()
page1.setHtml("<html><body>"
"<a id='link' href='hello' target='_blank'>link</a>"
"</body></html>", QUrl("echo:/"));
- QTRY_COMPARE(page1.spy.count(), 1);
+ QTRY_COMPARE(page1.spy.size(), 1);
QVERIFY(page1.spy.takeFirst().value(0).toBool());
switch (decision) {
@@ -3595,7 +3706,7 @@ void tst_QWebEnginePage::openLinkInNewPage()
break;
}
- Qt::MouseButton button;
+ Qt::MouseButton button = Qt::NoButton;
switch (cause) {
case Cause::TargetBlank:
button = Qt::LeftButton;
@@ -3610,13 +3721,13 @@ void tst_QWebEnginePage::openLinkInNewPage()
case Effect::Blocked:
// Test nothing new loaded
QTest::qWait(500);
- QCOMPARE(page1.spy.count(), 0);
- QCOMPARE(page2.spy.count(), 0);
+ QCOMPARE(page1.spy.size(), 0);
+ QCOMPARE(page2.spy.size(), 0);
break;
case Effect::LoadInSelf:
- QTRY_COMPARE(page1.spy.count(), 1);
+ QTRY_COMPARE(page1.spy.size(), 1);
QVERIFY(page1.spy.takeFirst().value(0).toBool());
- QCOMPARE(page2.spy.count(), 0);
+ QCOMPARE(page2.spy.size(), 0);
if (decision == Decision::ReturnSelf && cause == Cause::TargetBlank)
// History was discarded due to AddNewContents
QCOMPARE(page1.history()->count(), 1);
@@ -3625,9 +3736,9 @@ void tst_QWebEnginePage::openLinkInNewPage()
QCOMPARE(page2.history()->count(), 0);
break;
case Effect::LoadInOther:
- QTRY_COMPARE(page2.spy.count(), 1);
+ QTRY_COMPARE(page2.spy.size(), 1);
QVERIFY(page2.spy.takeFirst().value(0).toBool());
- QCOMPARE(page1.spy.count(), 0);
+ QCOMPARE(page1.spy.size(), 0);
QCOMPARE(page1.history()->count(), 1);
QCOMPARE(page2.history()->count(), 1);
break;
@@ -3649,7 +3760,7 @@ void tst_QWebEnginePage::dynamicFrame()
page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
page.load(QStringLiteral("qrc:/resources/dynamicFrame.html"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(toPlainTextSync(&page).trimmed(), QStringLiteral("foo"));
}
@@ -3725,7 +3836,7 @@ void tst_QWebEnginePage::notificationPermission()
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));
@@ -3783,6 +3894,149 @@ void tst_QWebEnginePage::sendNotification()
QTRY_VERIFY2(page.messages.contains("onclose"), page.messages.join("\n").toLatin1().constData());
}
+static QString clipboardPermissionQuery(QString variableName, QString permissionName)
+{
+ return QString("var %1; navigator.permissions.query({ name:'%2' }).then((p) => { %1 = p.state; "
+ "});")
+ .arg(variableName)
+ .arg(permissionName);
+}
+
+
+void tst_QWebEnginePage::clipboardReadWritePermissionInitialState_data()
+{
+ QTest::addColumn<bool>("canAccessClipboard");
+ QTest::addColumn<bool>("canPaste");
+ QTest::addColumn<QString>("permission");
+ QTest::newRow("access and paste should grant") << true << true << "granted";
+ QTest::newRow("no access should prompt") << false << true << "prompt";
+ QTest::newRow("no paste should prompt") << true << false << "prompt";
+ QTest::newRow("no access or paste should prompt") << false << false << "prompt";
+}
+
+void tst_QWebEnginePage::clipboardReadWritePermissionInitialState()
+{
+ QFETCH(bool, canAccessClipboard);
+ QFETCH(bool, canPaste);
+ QFETCH(QString, permission);
+
+ QWebEngineProfile otr;
+ QWebEngineView view(&otr);
+ QWebEnginePage &page = *view.page();
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard,
+ canAccessClipboard);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanPaste, canPaste);
+
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+ QUrl baseUrl("https://www.example.com/somepage.html");
+ page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
+ QTRY_COMPARE(spy.size(), 1);
+
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("readPermission", "clipboard-read"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("readPermission")), permission);
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("writePermission", "clipboard-write"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("writePermission")), permission);
+}
+
+void tst_QWebEnginePage::clipboardReadWritePermission_data()
+{
+ QTest::addColumn<bool>("canAccessClipboard");
+ QTest::addColumn<QWebEnginePage::PermissionPolicy>("initialPolicy");
+ QTest::addColumn<QString>("initialPermission");
+ QTest::addColumn<QWebEnginePage::PermissionPolicy>("requestPolicy");
+ QTest::addColumn<QString>("finalPermission");
+
+ QTest::newRow("noAccessGrantGrant")
+ << false << QWebEnginePage::PermissionGrantedByUser << "granted"
+ << QWebEnginePage::PermissionGrantedByUser << "granted";
+ QTest::newRow("noAccessGrantDeny")
+ << false << QWebEnginePage::PermissionGrantedByUser << "granted"
+ << QWebEnginePage::PermissionDeniedByUser << "denied";
+ QTest::newRow("noAccessDenyGrant")
+ << false << QWebEnginePage::PermissionDeniedByUser << "denied"
+ << QWebEnginePage::PermissionGrantedByUser << "granted";
+ QTest::newRow("noAccessDenyDeny") << false << QWebEnginePage::PermissionDeniedByUser << "denied"
+ << QWebEnginePage::PermissionDeniedByUser << "denied";
+ QTest::newRow("noAccessAskGrant") << false << QWebEnginePage::PermissionUnknown << "prompt"
+ << QWebEnginePage::PermissionGrantedByUser << "granted";
+
+ // All policies are ignored and overridden by setting JsCanAccessClipboard and JsCanPaste to
+ // true
+ QTest::newRow("accessGrantGrant")
+ << true << QWebEnginePage::PermissionGrantedByUser << "granted"
+ << QWebEnginePage::PermissionGrantedByUser << "granted";
+ QTest::newRow("accessDenyDeny") << true << QWebEnginePage::PermissionDeniedByUser << "granted"
+ << QWebEnginePage::PermissionDeniedByUser << "granted";
+ QTest::newRow("accessAskAsk") << true << QWebEnginePage::PermissionUnknown << "granted"
+ << QWebEnginePage::PermissionUnknown << "granted";
+}
+
+void tst_QWebEnginePage::clipboardReadWritePermission()
+{
+ QFETCH(bool, canAccessClipboard);
+ QFETCH(QWebEnginePage::PermissionPolicy, initialPolicy);
+ QFETCH(QString, initialPermission);
+ QFETCH(QWebEnginePage::PermissionPolicy, requestPolicy);
+ QFETCH(QString, finalPermission);
+
+ QWebEngineProfile otr;
+ QWebEngineView view(&otr);
+ QWebEnginePage &page = *view.page();
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard,
+ canAccessClipboard);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanPaste, true);
+
+ QUrl baseUrl("https://www.example.com/somepage.html");
+
+ int permissionRequestCount = 0;
+ bool errorState = false;
+
+ // if JavascriptCanAccessClipboard is true, this never fires
+ connect(&page, &QWebEnginePage::featurePermissionRequested, &page,
+ [&](const QUrl &o, QWebEnginePage::Feature f) {
+ if (f != QWebEnginePage::ClipboardReadWrite)
+ return;
+ if (o != baseUrl.url(QUrl::RemoveFilename)) {
+ qWarning() << "Unexpected case. Can't proceed." << o;
+ errorState = true;
+ return;
+ }
+ permissionRequestCount++;
+ page.setFeaturePermission(o, f, requestPolicy);
+ });
+
+ page.setFeaturePermission(baseUrl, QWebEnginePage::ClipboardReadWrite, initialPolicy);
+
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+ page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
+ QTRY_COMPARE(spy.size(), 1);
+
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("readPermission", "clipboard-read"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("readPermission")), initialPermission);
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("writePermission", "clipboard-write"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("writePermission")), initialPermission);
+
+ auto triggerRequest = [&page](QString variableName, QString apiCall)
+ {
+ auto js = QString("var %1; navigator.clipboard.%2.then((v) => { %1 = 'granted' }, (v) => { %1 = "
+ "'denied' });")
+ .arg(variableName)
+ .arg(apiCall);
+ evaluateJavaScriptSync(&page, js);
+ };
+
+ // permission is not 'remembered' from api standpoint, hence is not suppressed on explicit call
+ // from JS
+ triggerRequest("readState", "readText()");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "readState"), finalPermission);
+ triggerRequest("writeState", "writeText('foo')");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "writeState"), finalPermission);
+ QCOMPARE(permissionRequestCount, canAccessClipboard ? 0 : 2);
+ QVERIFY(!errorState);
+}
+
void tst_QWebEnginePage::contentsSize()
{
m_view->resize(800, 600);
@@ -3793,8 +4047,8 @@ void tst_QWebEnginePage::contentsSize()
m_view->setHtml(QString("<html><body style=\"width: 1600px; height: 1200px;\"><p>hi</p></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(contentsSizeChangedSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QTRY_COMPARE(contentsSizeChangedSpy.size(), 1);
// Verify the page's contents size is not limited by the view's size.
QCOMPARE(m_page->contentsSize().width(), 1608);
@@ -3811,6 +4065,60 @@ void tst_QWebEnginePage::contentsSize()
QCOMPARE(m_page->contentsSize().height(), 1216);
}
+void tst_QWebEnginePage::localFontAccessPermission_data()
+{
+ QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
+ QTest::addColumn<bool>("ignore");
+ QTest::addColumn<bool>("shouldBeEmpty");
+
+ QTest::newRow("ignore") << QWebEnginePage::PermissionDeniedByUser << true << true;
+ QTest::newRow("setDeny") << QWebEnginePage::PermissionDeniedByUser << false << true;
+ QTest::newRow("setGrant") << QWebEnginePage::PermissionGrantedByUser << false << false;
+}
+
+void tst_QWebEnginePage::localFontAccessPermission() {
+ QFETCH(QWebEnginePage::PermissionPolicy, policy);
+ QFETCH(bool, ignore);
+ QFETCH(bool, shouldBeEmpty);
+
+ QWebEngineView view;
+ QWebEnginePage page(&view);
+ view.setPage(&page);
+
+ connect(&page, &QWebEnginePage::featurePermissionRequested, &page, [&] (const QUrl &o, QWebEnginePage::Feature f) {
+ if (f != QWebEnginePage::LocalFontsAccess)
+ return;
+
+ if (!ignore)
+ page.setFeaturePermission(o, f, policy);
+ });
+
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+ page.load(QUrl("qrc:///resources/fontaccess.html"));
+ QTRY_COMPARE(spy.size(), 1);
+
+ // Font access is only enabled for visible WebContents.
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ if (evaluateJavaScriptSync(&page, QStringLiteral("!window.queryLocalFonts")).toBool())
+ W_QSKIP("Local fonts access is not supported.", SkipSingle);
+
+ // Access to the API requires recent user interaction
+ QTest::keyPress(view.focusProxy(), Qt::Key_Space);
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("activated")).toBool(), true);
+
+ if (ignore) {
+ QTRY_COMPARE_NE_WITH_TIMEOUT(evaluateJavaScriptSync(&page, QStringLiteral("done")).toBool(), true, 1000);
+ } else {
+ QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(&page, QStringLiteral("done")).toBool() == true, 1000);
+ QVERIFY((evaluateJavaScriptSync(&page, QStringLiteral("fonts.length")).toInt() == 0) == shouldBeEmpty);
+ }
+
+ // Reset permission, since otherwise it will be stored between runs
+ page.setFeaturePermission(QUrl("qrc:///resources/fontaccess.html"), QWebEnginePage::LocalFontsAccess, QWebEnginePage::PermissionUnknown);
+}
+
void tst_QWebEnginePage::setLifecycleState()
{
qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
@@ -3822,64 +4130,64 @@ void tst_QWebEnginePage::setLifecycleState()
QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
// Active -> Frozen
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(1));
// Frozen -> Active
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
// Active -> Discarded
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant());
QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant());
- QCOMPARE(loadSpy.count(), 0);
+ QCOMPARE(loadSpy.size(), 0);
// Discarded -> Frozen (illegal!)
QTest::ignoreMessage(QtWarningMsg,
"setLifecycleState: failed to transition from Discarded to Frozen state: "
"illegal transition");
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
// Discarded -> Active
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
@@ -3888,21 +4196,21 @@ void tst_QWebEnginePage::setLifecycleState()
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 3);
+ QCOMPARE(lifecycleSpy.size(), 3);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
// Reload clears document.wasDiscarded
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
}
@@ -3918,18 +4226,18 @@ void tst_QWebEnginePage::setVisible()
QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
// hidden -> visible
page.setVisible(true);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(page.isVisible(), true);
@@ -3938,28 +4246,28 @@ void tst_QWebEnginePage::setVisible()
QtWarningMsg,
"setLifecycleState: failed to transition from Active to Frozen state: page is visible");
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
// visible -> hidden
page.setVisible(false);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
QCOMPARE(page.isVisible(), false);
// Active -> Frozen
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
// hidden -> visible (triggers Frozen -> Active)
page.setVisible(true);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(page.isVisible(), true);
@@ -3968,31 +4276,31 @@ void tst_QWebEnginePage::setVisible()
"setLifecycleState: failed to transition from Active to Discarded state: "
"page is visible");
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
// visible -> hidden
page.setVisible(false);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
QCOMPARE(page.isVisible(), false);
// Active -> Discarded
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
// hidden -> visible (triggers Discarded -> Active)
page.setVisible(true);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(page.isVisible(), true);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
}
@@ -4003,7 +4311,7 @@ void tst_QWebEnginePage::discardPreservesProperties()
QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
// Change as many properties as possible to non-default values
@@ -4040,7 +4348,7 @@ void tst_QWebEnginePage::discardPreservesProperties()
// Discard + undiscard
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
// Property changes should be preserved
@@ -4079,7 +4387,7 @@ void tst_QWebEnginePage::automaticUndiscard()
QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
// setUrl
@@ -4104,16 +4412,16 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
// Ensure pages are initialized
inspectedPage.load(QStringLiteral("about:blank"));
devToolsPage.load(QStringLiteral("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.size(), 1, 90000);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// Open DevTools with Frozen inspectedPage
inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
inspectedPage.setDevToolsPage(&devToolsPage);
QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
inspectedPage.setDevToolsPage(nullptr);
@@ -4121,9 +4429,9 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
inspectedPage.setDevToolsPage(&devToolsPage);
QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
- QTRY_COMPARE(inspectedSpy.count(), 1);
+ QTRY_COMPARE(inspectedSpy.size(), 1);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
inspectedPage.setDevToolsPage(nullptr);
@@ -4131,7 +4439,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
devToolsPage.setInspectedPage(nullptr);
@@ -4139,7 +4447,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// keep DevTools open
@@ -4177,35 +4485,35 @@ void tst_QWebEnginePage::discardPreservesCommittedLoad()
QString url = QStringLiteral("qrc:/resources/lifecycle.html");
page.setUrl(url);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.size(), 1);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url)));
QCOMPARE(page.url(), url);
- QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.size(), 2);
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url));
QString title = QStringLiteral("Lifecycle");
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
QCOMPARE(page.title(), title);
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(loadStartedSpy.count(), 0);
- QCOMPARE(loadFinishedSpy.count(), 0);
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(loadStartedSpy.size(), 0);
+ QCOMPARE(loadFinishedSpy.size(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), QUrl(url));
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.title(), title);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), url);
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.title(), title);
}
@@ -4222,21 +4530,21 @@ void tst_QWebEnginePage::discardAbortsPendingLoad()
[&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
QUrl url = QStringLiteral("qrc:/resources/lifecycle.html");
page.setUrl(url);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
- QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.size(), 2);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(url));
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl()));
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.url(), QUrl());
QCOMPARE(page.title(), QString());
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(loadStartedSpy.count(), 0);
- QCOMPARE(loadFinishedSpy.count(), 0);
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(loadStartedSpy.size(), 0);
+ QCOMPARE(loadFinishedSpy.size(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), QUrl());
QCOMPARE(page.title(), QString());
}
@@ -4252,14 +4560,14 @@ void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
QString url1 = QStringLiteral("qrc:/resources/lifecycle.html");
page.setUrl(url1);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.size(), 1);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
QCOMPARE(page.url(), url1);
- QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.size(), 2);
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url1));
QString title = QStringLiteral("Lifecycle");
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
@@ -4269,21 +4577,21 @@ void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
[&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
QString url2 = QStringLiteral("about:blank");
page.setUrl(url2);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
- QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.size(), 2);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url2)));
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.url(), url1);
QCOMPARE(page.title(), title);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(loadStartedSpy.count(), 0);
- QCOMPARE(loadFinishedSpy.count(), 0);
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(loadStartedSpy.size(), 0);
+ QCOMPARE(loadFinishedSpy.size(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), url1);
QCOMPARE(page.title(), title);
}
@@ -4379,32 +4687,32 @@ void tst_QWebEnginePage::recommendedStateAuto()
connect(&page, &QWebEnginePage::recommendedStateChanged, &page, &QWebEnginePage::setLifecycleState);
page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
- QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QTRY_COMPARE(lifecycleSpy.size(), 2);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
page.setVisible(true);
- QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QTRY_COMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
page.setVisible(false);
- QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QTRY_COMPARE(lifecycleSpy.size(), 2);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(lifecycleSpy.count(), 3);
+ QTRY_COMPARE(lifecycleSpy.size(), 3);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QWebEnginePage devTools;
page.setDevToolsPage(&devTools);
- QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QTRY_COMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
page.setDevToolsPage(nullptr);
- QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QTRY_COMPARE(lifecycleSpy.size(), 2);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
}
@@ -4419,33 +4727,33 @@ void tst_QWebEnginePage::setLifecycleStateAndReload()
QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
page.triggerAction(QWebEnginePage::Reload);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
page.triggerAction(QWebEnginePage::Reload);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
}
@@ -4464,20 +4772,20 @@ void tst_QWebEnginePage::editActionsWithExplicitFocus()
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
// Still no focus because focus on navigation is disabled. Edit actions don't do anything (should not crash).
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QCOMPARE(page->hasSelection(), false);
// Focus content by focusing window from JavaScript. Edit actions should be enabled and functional.
evaluateJavaScriptSync(page, "window.focus();");
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
}
@@ -4497,13 +4805,13 @@ void tst_QWebEnginePage::editActionsWithInitialFocus()
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
// Content gets initial focus.
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
}
@@ -4523,15 +4831,15 @@ void tst_QWebEnginePage::editActionsWithFocusOnIframe()
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
page->load(QUrl("qrc:///resources/iframe2.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
// Focusing an iframe.
evaluateJavaScriptSync(page, "document.getElementsByTagName('iframe')[0].contentWindow.focus()");
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("inner"));
}
@@ -4547,8 +4855,8 @@ void tst_QWebEnginePage::editActionsWithoutSelection()
QSignalSpy actionChangedSpy(page->action(QWebEnginePage::SelectAll), &QAction::changed);
page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(!page->action(QWebEnginePage::Cut)->isEnabled());
QVERIFY(!page->action(QWebEnginePage::Copy)->isEnabled());
@@ -4560,7 +4868,7 @@ void tst_QWebEnginePage::editActionsWithoutSelection()
QVERIFY(!page->action(QWebEnginePage::Unselect)->isEnabled());
page->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
@@ -4620,12 +4928,12 @@ void tst_QWebEnginePage::customUserAgentInNewTab()
page.setHtml(QString("<html><body><a id='link' target='_blank' href='") +
server.url("/test1").toEncoded() +
QString("'>link</a></body></html>"));
- QTRY_COMPARE(page.loadSpy.count(), 1);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
QVERIFY(page.loadSpy.takeFirst().value(0).toBool());
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
QTRY_VERIFY(page.newPage);
- QTRY_COMPARE(page.newPage->loadSpy.count(), 1);
+ QTRY_COMPARE(page.newPage->loadSpy.size(), 1);
QTRY_VERIFY(!lastUserAgent.isEmpty());
QCOMPARE(lastUserAgent, expectedUserAgent);
QCOMPARE(evaluateJavaScriptSync(page.newPage.get(), QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
@@ -4639,11 +4947,11 @@ void tst_QWebEnginePage::customUserAgentInNewTab()
page.setHtml(QString("<html><body><a id='link' target='_blank' href='") +
server.url("/test2").toEncoded() +
QString("'>link</a></body></html>"));
- QTRY_COMPARE(page.loadSpy.count(), 1);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
QVERIFY(page.loadSpy.takeFirst().value(0).toBool());
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
QTRY_VERIFY(page.newPage);
- QTRY_COMPARE(page.newPage->loadSpy.count(), 1);
+ QTRY_COMPARE(page.newPage->loadSpy.size(), 1);
QTRY_VERIFY(!lastUserAgent.isEmpty());
QCOMPARE(lastUserAgent, expectedUserAgent);
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
@@ -4676,7 +4984,7 @@ void tst_QWebEnginePage::openNewTabInDifferentProfile()
QVERIFY(QTest::qWaitForWindowExposed(&view));
page.setHtml(QString("<html><body><a id='link' target='_blank' href='%1'>link</a></body></html>").arg(server.url("/first.html").toEncoded()));
- QTRY_COMPARE(page.loadSpy.count(), 1);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
QVERIFY(page.loadSpy.takeFirst().value(0).toBool());
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
@@ -4728,17 +5036,17 @@ void tst_QWebEnginePage::renderProcessPid()
class FileSelectionTestPage : public QWebEnginePage {
public:
- FileSelectionTestPage()
- { }
+ FileSelectionTestPage() : m_tempDir(QDir::tempPath() + "/tst_qwebenginepage-XXXXXX") { }
QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) override
{
Q_UNUSED(oldFiles);
chosenFileSelectionMode = mode;
chosenAcceptedMimeTypes = acceptedMimeTypes;
- return QStringList();
+ return QStringList() << (m_tempDir.path() + "/file.txt");
}
+ QTemporaryDir m_tempDir;
int chosenFileSelectionMode = -1;
QStringList chosenAcceptedMimeTypes;
};
@@ -4757,6 +5065,8 @@ void tst_QWebEnginePage::testChooseFilesParameters_data()
<< QWebEnginePage::FileSelectOpenMultiple << QStringList();
QTest::addRow("Folder upload") << QString("multiple webkitdirectory") << QString()
<< QWebEnginePage::FileSelectUploadFolder << QStringList();
+ QTest::addRow("Save file") << QString("") << QString()
+ << QWebEnginePage::FileSelectSave << QStringList();
mimeTypes = QStringList() << "audio/*";
QTest::addRow("MIME type: audio") << QString() << QString("accept='%1'").arg(mimeTypes.join(','))
<< QWebEnginePage::FileSelectOpen << mimeTypes;
@@ -4790,11 +5100,18 @@ void tst_QWebEnginePage::testChooseFilesParameters()
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- page.setHtml(QString("<html><body>"
- "<input id='filePicker' type='file' name='filePicker' %1 %2 />"
- "</body></html>").arg(uploadAttribute, mimeTypeAttribute));
+ if (expectedFileSelectionMode != QWebEnginePage::FileSelectSave) {
+ page.setHtml(QString("<html><body>"
+ "<input id='filePicker' type='file' name='filePicker' %1 %2 />"
+ "</body></html>").arg(uploadAttribute, mimeTypeAttribute));
+ } else {
+ page.setHtml(QString("<html><body>"
+ "<button id='filePicker' value='trigger' "
+ "onclick='window.showSaveFilePicker()'"
+ "</body></html>"), QString("qrc:/"));
+ }
QVERIFY(spyFinished.wait());
- QTRY_COMPARE(spyFinished.count(), 1);
+ QTRY_COMPARE(spyFinished.size(), 1);
evaluateJavaScriptSync(view.page(), "document.getElementById('filePicker').focus()");
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("filePicker"));
@@ -4815,20 +5132,40 @@ void tst_QWebEnginePage::fileSystemAccessDialog()
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- page.setHtml(QString("<html><body>"
+ connect(&page, &QWebEnginePage::fileSystemAccessRequested,
+ [](QWebEngineFileSystemAccessRequest request) {
+ QCOMPARE(request.accessFlags(),
+ QWebEngineFileSystemAccessRequest::Read
+ | QWebEngineFileSystemAccessRequest::Write);
+ request.accept();
+ });
+
+ page.setHtml(QString("<html><head><script>"
+ "async function getTemporaryDir() {"
+ " const newHandle = await window.showSaveFilePicker();"
+ " const writable = await newHandle.createWritable();"
+ " await writable.write(new Blob(['New value']));"
+ " await writable.close();"
+ ""
+ " const fileData = await newHandle.getFile();"
+ " document.title = await fileData.text();"
+ "}"
+ "</script></head><body>"
"<button id='triggerDialog' value='trigger' "
- "onclick='window.showDirectoryPicker()'>"
+ "onclick='getTemporaryDir()'"
"</body></html>"),
QString("qrc:/"));
QVERIFY(spyFinished.wait());
- QTRY_COMPARE(spyFinished.count(), 1);
+ QTRY_COMPARE(spyFinished.size(), 1);
evaluateJavaScriptSync(view.page(), "document.getElementById('triggerDialog').focus()");
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(),
QStringLiteral("triggerDialog"));
QTest::keyClick(view.focusProxy(), Qt::Key_Enter);
- QTRY_COMPARE(page.chosenFileSelectionMode, QWebEnginePage::FileSelectUploadFolder);
+ QTRY_COMPARE(page.title(), "New value");
+
+ QTRY_COMPARE(page.chosenFileSelectionMode, QWebEnginePage::FileSelectSave);
QTRY_COMPARE(page.chosenAcceptedMimeTypes, QStringList());
}
@@ -4885,11 +5222,11 @@ void tst_QWebEnginePage::audioMuted()
page.setAudioMuted(true);
loadSync(&page, QUrl("about:blank"));
QCOMPARE(page.isAudioMuted(), true);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy[0][0], QVariant(true));
page.setAudioMuted(false);
QCOMPARE(page.isAudioMuted(), false);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QCOMPARE(spy[1][0], QVariant(false));
}
@@ -4899,9 +5236,9 @@ void tst_QWebEnginePage::closeContents()
QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QSignalSpy windowCreatedSpy(&page, &TestPage::windowCreated);
page.setUrl(QUrl("about:blank"));
- QTRY_COMPARE(spyFinished.count(), 1);
+ QTRY_COMPARE(spyFinished.size(), 1);
page.runJavaScript("var dialog = window.open('', '', 'width=100, height=100');");
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
QWebEngineView *dialogView = new QWebEngineView;
QWebEnginePage *dialogPage = page.createdWindows[0];
@@ -4928,8 +5265,8 @@ void tst_QWebEnginePage::isSafeRedirect_data()
fileScheme += "/";
#endif
- QString tempDir(fileScheme + QDir::tempPath());
- QTest::newRow(qPrintable(tempDir)) << QUrl(tempDir) << QUrl(tempDir + "/");
+ QString tempDir(fileScheme + QDir::tempPath() + "/");
+ QTest::newRow(qPrintable(tempDir)) << QUrl(tempDir) << QUrl(tempDir);
QTest::newRow(qPrintable(tempDir + QString("/foo/bar"))) << QUrl(tempDir + "/foo/bar") << QUrl(tempDir + "/foo/bar");
QTest::newRow("filesystem:http://foo.com/bar") << QUrl("filesystem:http://foo.com/bar") << QUrl("filesystem:http://foo.com/bar/");
}
@@ -4942,11 +5279,452 @@ void tst_QWebEnginePage::isSafeRedirect()
TestPage page;
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(requestedUrl);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QCOMPARE(page.url(), expectedUrl);
spy.clear();
}
+class LocalRemoteUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ LocalRemoteUrlSchemeHandler(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ }
+ ~LocalRemoteUrlSchemeHandler() = default;
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QBuffer *buffer = new QBuffer(job);
+ buffer->setData("<html><body><a href='remote://test.html' id='link'>Click link</a></body></html>");
+ job->reply("text/html", buffer);
+ loaded = true;
+ }
+ bool loaded = false;
+};
+
+void tst_QWebEnginePage::localToRemoteNavigation()
+{
+ LocalRemoteUrlSchemeHandler local;
+ LocalRemoteUrlSchemeHandler remote;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("local", &local);
+ profile.installUrlSchemeHandler("remote", &remote);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+ view.setPage(&page);
+ page.setUrl(QUrl("local://test.html"));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+ QVERIFY(local.loaded);
+
+ // Should navigate:
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 2, 20000);
+ QVERIFY(remote.loaded);
+ local.loaded = false;
+ remote.loaded = false;
+
+ page.setUrl(QUrl("local://test.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 3, 20000);
+ QVERIFY(local.loaded && !remote.loaded);
+
+ // Should not navigate:
+ page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
+ QTest::qWait(500);
+ QVERIFY(!remote.loaded);
+}
+
+void tst_QWebEnginePage::clientHints_data()
+{
+ QTest::addColumn<bool>("clientHintsEnabled");
+ QTest::addColumn<QString>("arch");
+ QTest::addColumn<QString>("platform");
+ QTest::addColumn<QString>("model");
+ QTest::addColumn<bool>("isMobile");
+ QTest::addColumn<QString>("fullVersion");
+ QTest::addColumn<QString>("platformVersion");
+ QTest::addColumn<QString>("bitness");
+ QTest::addColumn<bool>("isWOW64");
+ QTest::addColumn<QHash<QString, QString>>("fullVersionList");
+
+ QTest::newRow("Modify values") << true << "Abc" << "AmigaOS" << "Ultra" << true << "1.99" << "3" << "x64" << true << QHash<QString, QString>({{"APITest", "1.0.0"}, {"App", "5.0"}});
+ QTest::newRow("Empty values") << true << "" << "" << "" << false << "" << "" << "" << false << QHash<QString, QString>();
+ QTest::newRow("Disable headers") << false << "" << "" << "" << false << "" << "" << "" << false << QHash<QString, QString>();
+}
+
+void tst_QWebEnginePage::clientHints()
+{
+ QFETCH(bool, clientHintsEnabled);
+ QFETCH(QString, arch);
+ QFETCH(QString, platform);
+ QFETCH(QString, model);
+ QFETCH(bool, isMobile);
+ QFETCH(QString, fullVersion);
+ QFETCH(QString, platformVersion);
+ QFETCH(QString, bitness);
+ QFETCH(bool, isWOW64);
+ typedef QHash<QString, QString> brandVersionPairs;
+ QFETCH(brandVersionPairs, fullVersionList);
+
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ QWebEngineClientHints *clientHints = page.profile()->clientHints();
+ clientHints->setAllClientHintsEnabled(clientHintsEnabled);
+
+ HttpServer server;
+ int requestCount = 0;
+ connect(&server, &HttpServer::newRequest, [&] (HttpReqRep *r) {
+ // Platform and Mobile hints are always sent and can't be disabled with this API
+ QVERIFY(r->hasRequestHeader("Sec-CH-UA-Platform"));
+ QVERIFY(r->hasRequestHeader("Sec-CH-UA-Mobile"));
+ if (!clientHintsEnabled) {
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Arch"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Model"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Full-Version"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Platform-Version"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Bitness"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Wow64"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Full-Version-List"));
+ }
+
+ // The first request header won't contain any hints, only after a response with "Accept-CH"
+ if (requestCount > 1 && clientHintsEnabled) {
+ // All hint values are lower case in the headers
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Arch")).remove("\""), arch.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Platform")).remove("\""), platform.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Model")).remove("\""), model.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Mobile")).remove("\""), isMobile ? "?1" : "?0");
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Full-Version")).remove("\""), fullVersion.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Platform-Version")).remove("\""), platformVersion.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Bitness")).remove("\""), bitness.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Wow64")).remove("\""), isWOW64 ? "?1" : "?0");
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ QVERIFY(QString(r->requestHeader("Sec-CH-UA-Full-Version-List")).contains(i.key().toLower()));
+ }
+
+ r->setResponseHeader("Accept-CH", "Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform-Version, Sec-CH-UA-Platform, Sec-CH-UA-Wow64, Sec-CH-UA");
+ r->sendResponse();
+ requestCount++;
+ });
+ QVERIFY(server.start());
+
+ clientHints->setArch(arch);
+ clientHints->setPlatform(platform);
+ clientHints->setModel(model);
+ clientHints->setIsMobile(isMobile);
+ clientHints->setFullVersion(fullVersion);
+ clientHints->setPlatformVersion(platformVersion);
+ clientHints->setBitness(bitness);
+ clientHints->setIsWow64(isWOW64);
+ clientHints->setFullVersionList(fullVersionList);
+
+ page.setUrl(server.url());
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QVERIFY(loadSpy.takeFirst().value(0).toBool());
+
+ QCOMPARE(clientHints->arch(), arch);
+ QCOMPARE(clientHints->platform(), platform);
+ QCOMPARE(clientHints->model(), model);
+ QCOMPARE(clientHints->isMobile(), isMobile);
+ QCOMPARE(clientHints->fullVersion(), fullVersion);
+ QCOMPARE(clientHints->platformVersion(), platformVersion);
+ QCOMPARE(clientHints->bitness(), bitness);
+ QCOMPARE(clientHints->isWow64(), isWOW64);
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ QCOMPARE(clientHints->fullVersionList()[i.key()], i.value());
+
+ // A new user agent string should not override/disable client hints
+ page.profile()->setHttpUserAgent(QStringLiteral("Custom user agent"));
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ // Reset all to default values
+ clientHints->resetAll();
+ QCOMPARE_NE(clientHints->arch(), arch);
+#ifdef Q_OS_LINUX
+ QCOMPARE(clientHints->platform().toLower(), "linux");
+#elif defined (Q_OS_MACOS)
+ QCOMPARE(clientHints->platform().toLower(), "macos");
+#elif defined (Q_OS_WIN)
+ QCOMPARE(clientHints->platform().toLower(), "windows");
+#endif
+ QCOMPARE_NE(clientHints->fullVersion(), fullVersion);
+ QCOMPARE_NE(clientHints->platformVersion(), platformVersion);
+ QCOMPARE_NE(clientHints->bitness(), bitness);
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ QVERIFY(!clientHints->fullVersionList().contains(i.key()));
+ QVERIFY(clientHints->fullVersionList().contains("Chromium"));
+}
+
+void tst_QWebEnginePage::childFrameInput()
+{
+ HttpServer server;
+ server.setHostDomain("localhost");
+
+ // The cross-origin policy blocks scripting this frame with QWebEnginePage::runJavaScript.
+ // Use console messages to validate events.
+ QString innerHtml(
+ "<html><head><style>body{height:1200px;width:1200px;}</style></head><body>test<script>"
+ " let lastX, lastY = 0;"
+ " document.onscroll = (e) => {"
+ " if (window.scrollY > lastY) console.log(\"Down\");"
+ " if (window.scrollY < lastY) console.log(\"Up\");"
+ " if (window.scrollX > lastX) console.log(\"Right\");"
+ " if (window.scrollX < lastX) console.log(\"Left\");"
+ " lastX = window.scrollX;"
+ " lastY = window.scrollY;"
+ " };"
+ " window.onload = () => {console.log('loaded');};"
+ "</script></body></html>");
+
+ QVERIFY(server.start());
+ connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestPath() == "/main.html") {
+ // the Origin-Agent-Cluster header enables dedicated processes for origins
+ rr->setResponseHeader("Origin-Agent-Cluster", "?1");
+ // the same-site-cross-origin page forces to create the frame in a different process
+ server.setHostDomain("sub.localhost");
+ rr->setResponseBody(("<html><body>"
+ "<iframe id=\"iframe\" width=90% height=90% src=\""
+ + server.url().toString().toUtf8()
+ + "inner.html\"></iframe>"
+ "</body></html>"));
+ }
+ if (rr->requestPath() == "/inner.html")
+ rr->setResponseBody(innerHtml.toUtf8());
+ rr->sendResponse();
+ });
+
+ QWebEngineView view;
+ ConsolePage page;
+ view.setPage(&page);
+ view.resize(640, 480);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ page.load(server.url("/main.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_VERIFY(evaluateJavaScriptSync(&page, "window.originAgentCluster").toBool());
+
+ // make sure the frame is loaded
+ QTRY_COMPARE(page.messages.size(), 1);
+ QTRY_COMPARE(page.messages[0], QString("loaded"));
+
+ // focus
+ evaluateJavaScriptSync(&page, "document.getElementById('iframe').contentWindow.focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "document.activeElement.id").toString(),
+ QStringLiteral("iframe"));
+
+ QPoint globalPos = view.windowHandle()->position();
+ QPoint p = elementCenter(&page, QString("iframe"));
+
+ // Even if the document is loaded, it is not necessarily drawn.
+ // Hit-testing (in Viz) for pointer events will be flacky in this scenario.
+ // Send keyClick events first so the target frame will be cached for wheel events.
+ QTest::keyClick(view.focusProxy(), Qt::Key_Down);
+ QTRY_COMPARE(page.messages.size(), 2);
+ QTRY_COMPARE(page.messages[1], QString("Down"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Up);
+ QTRY_COMPARE(page.messages.size(), 3);
+ QTRY_COMPARE(page.messages[2], QString("Up"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Right);
+ QTRY_COMPARE(page.messages.size(), 4);
+ QTRY_COMPARE(page.messages[3], QString("Right"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Left);
+ QTRY_COMPARE(page.messages.size(), 5);
+ QTRY_COMPARE(page.messages[4], QString("Left"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(0, -120));
+ QTRY_COMPARE(page.messages.size(), 6);
+ QTRY_COMPARE(page.messages[5], QString("Down"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(0, 120));
+ QTRY_COMPARE(page.messages.size(), 7);
+ QTRY_COMPARE(page.messages[6], QString("Up"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(-120, 0));
+ QTRY_COMPARE(page.messages.size(), 8);
+ QTRY_COMPARE(page.messages[7], QString("Right"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(120, 0));
+ QTRY_COMPARE(page.messages.size(), 9);
+ QTRY_COMPARE(page.messages[8], QString("Left"));
+}
+
+void tst_QWebEnginePage::openLinkInNewPageWithWebWindowType_data()
+{
+ QTest::addColumn<QWebEnginePage::WebWindowType>("webWindowType");
+ QTest::addColumn<QString>("elementId");
+ QTest::addColumn<Qt::MouseButton>("button");
+ QTest::addColumn<Qt::KeyboardModifier>("keyboardModififer");
+ QTest::newRow("webBrowserWindow")
+ << QWebEnginePage::WebBrowserWindow << "link" << Qt::LeftButton << Qt::ShiftModifier;
+ QTest::newRow("webBrowserTab")
+ << QWebEnginePage::WebBrowserTab << "link" << Qt::LeftButton << Qt::NoModifier;
+ QTest::newRow("webDialog") << QWebEnginePage::WebDialog << "openWindow" << Qt::LeftButton
+ << Qt::NoModifier;
+ QTest::newRow("webBrowserBackgroundTab") << QWebEnginePage::WebBrowserBackgroundTab << "link"
+ << Qt::MiddleButton << Qt::NoModifier;
+}
+
+class WebWindowTypeTestPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ WebWindowType windowType;
+
+signals:
+ void windowCreated();
+
+private:
+ QWebEnginePage *createWindow(WebWindowType type) override
+ {
+ windowType = type;
+ emit windowCreated();
+ return nullptr;
+ }
+};
+
+void tst_QWebEnginePage::openLinkInNewPageWithWebWindowType()
+{
+ QFETCH(QWebEnginePage::WebWindowType, webWindowType);
+ QFETCH(QString, elementId);
+ QFETCH(Qt::MouseButton, button);
+ QFETCH(Qt::KeyboardModifier, keyboardModififer);
+
+ WebWindowTypeTestPage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy windowCreatedSpy(&page, &WebWindowTypeTestPage::windowCreated);
+ QWebEngineView view(&page);
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
+ QString html = "<html><body>"
+ "<a id='link' href='hello' target='_blank'>link</a>"
+ "<br><br>"
+ "<button id='openWindow' onclick='myFunction()'>Try it</button>"
+ "<script>"
+ "function myFunction() {"
+ " const myWindow = window.open('', '', 'width=300,height=300');"
+ "}"
+ "</script>"
+ "</body></html>";
+
+ page.setHtml(html);
+ QVERIFY(loadFinishedSpy.wait());
+
+ QTest::mouseClick(view.focusProxy(), button, keyboardModififer,
+ elementCenter(&page, elementId));
+ QVERIFY(windowCreatedSpy.wait());
+ QCOMPARE(page.windowType, webWindowType);
+}
+
+class DoNothingInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ DoNothingInterceptor() { }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &) override
+ {
+ ran = true;
+ }
+ bool ran = false;
+};
+
+void tst_QWebEnginePage::keepInterceptorAfterNewWindowRequested()
+{
+ DoNothingInterceptor interceptor;
+ QWebEnginePage page;
+ page.setUrlRequestInterceptor(&interceptor);
+ connect(&page, &QWebEnginePage::newWindowRequested, [&](QWebEngineNewWindowRequest &request) {
+ request.openIn(&page);
+ });
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+
+ QWebEngineView view;
+ view.resize(500, 500);
+ view.setPage(&page);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.setHtml("<html><body>"
+ "<a id='link' href='hello' target='_blank'>link</a>"
+ "</body></html>");
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(loadFinishedSpy.takeFirst().value(0).toBool());
+ QVERIFY(interceptor.ran);
+ interceptor.ran = false;
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(loadFinishedSpy.takeFirst().value(0).toBool());
+ QVERIFY(!interceptor.ran);
+
+ page.setHtml("<html><body></body></html>");
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(loadFinishedSpy.takeFirst().value(0).toBool());
+ QVERIFY(interceptor.ran);
+}
+
+void tst_QWebEnginePage::chooseDesktopMedia()
+{
+#if QT_CONFIG(webengine_extensions) && QT_CONFIG(webengine_webrtc)
+ HttpServer server;
+ server.setHostDomain("localhost");
+ connect(&server, &HttpServer::newRequest, &server, [&] (HttpReqRep *r) {
+ if (r->requestMethod() == "GET")
+ r->setResponseBody("<html></html>");
+ });
+ QVERIFY(server.start());
+
+ QWebEnginePage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
+
+ bool desktopMediaRequested = false;
+ bool permissionRequested = false;
+
+ connect(&page, &QWebEnginePage::desktopMediaRequested,
+ [&](const QWebEngineDesktopMediaRequest &) {
+ desktopMediaRequested = true;
+ });
+
+ connect(&page, &QWebEnginePage::featurePermissionRequested,
+ [&](const QUrl &securityOrigin, QWebEnginePage::Feature feature) {
+ permissionRequested = true;
+ // Handle permission to 'complete' the media request
+ page.setFeaturePermission(securityOrigin, feature,
+ QWebEnginePage::PermissionGrantedByUser);
+ });
+
+ page.load(QUrl(server.url()));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
+
+ const QString extensionId("nkeimhogjdpnpccoofpliimaahmaaome");
+ page.runJavaScript(QString("(() => {"
+ " let port = chrome.runtime.connect(\"%1\", {name: \"chooseDesktopMedia\"});"
+ " port.postMessage({method: \"chooseDesktopMedia\"});"
+ "})()").arg(extensionId));
+
+ QTRY_VERIFY(desktopMediaRequested);
+ QTRY_VERIFY(permissionRequested);
+#endif // QT_CONFIG(webengine_extensions) && QT_CONFIG(webengine_webrtc)
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)
diff --git a/tests/auto/widgets/qwebengineprofile/CMakeLists.txt b/tests/auto/widgets/qwebengineprofile/CMakeLists.txt
index 744f44405..d7393eaef 100644
--- a/tests/auto/widgets/qwebengineprofile/CMakeLists.txt
+++ b/tests/auto/widgets/qwebengineprofile/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 38f3b04e7..095d4c8f2 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <util.h>
#include <QtCore/qbuffer.h>
@@ -57,15 +32,16 @@ class tst_QWebEngineProfile : public QObject
private Q_SLOTS:
void initTestCase();
- void userDefaultProfile();
+ void defaultProfile_data();
void defaultProfile();
- void testProfile();
+ void userDefinedProfile();
void clearDataFromCache();
void disableCache();
void urlSchemeHandlers();
void urlSchemeHandlerFailRequest();
void urlSchemeHandlerFailOnRead();
void urlSchemeHandlerStreaming();
+ void urlSchemeHandlerStreaming2();
void urlSchemeHandlerRequestHeaders();
void urlSchemeHandlerInstallation();
void urlSchemeHandlerXhrStatus();
@@ -103,32 +79,28 @@ void tst_QWebEngineProfile::initTestCase()
QWebEngineUrlScheme::registerScheme(myscheme);
}
-void tst_QWebEngineProfile::userDefaultProfile()
+static QString StandardCacheLocation() { static auto p = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); return p; }
+static QString StandardAppDataLocation() { static auto p = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); return p; }
+
+void tst_QWebEngineProfile::defaultProfile_data()
{
- QWebEngineProfile profile("Default");
- QVERIFY(!profile.isOffTheRecord());
- QCOMPARE(profile.storageName(), QStringLiteral("Default"));
- QCOMPARE(profile.httpCacheType(), QWebEngineProfile::DiskHttpCache);
- QCOMPARE(profile.persistentCookiesPolicy(), QWebEngineProfile::AllowPersistentCookies);
- QCOMPARE(profile.cachePath(),
- QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
- + QStringLiteral("/QtWebEngine/Default"));
- QCOMPARE(profile.persistentStoragePath(),
- QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
- + QStringLiteral("/QtWebEngine/Default"));
+ QTest::addColumn<bool>("userCreated");
+ QTest::addRow("global") << false;
+ QTest::addRow("user") << true;
}
void tst_QWebEngineProfile::defaultProfile()
{
- QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
+ QFETCH(bool, userCreated);
+ QScopedPointer<QWebEngineProfile> p(userCreated ? new QWebEngineProfile : nullptr);
+ QWebEngineProfile *profile = userCreated ? p.get() : QWebEngineProfile::defaultProfile();
QVERIFY(profile);
QVERIFY(profile->isOffTheRecord());
+ QCOMPARE(profile->storageName(), QString());
QCOMPARE(profile->httpCacheType(), QWebEngineProfile::MemoryHttpCache);
QCOMPARE(profile->persistentCookiesPolicy(), QWebEngineProfile::NoPersistentCookies);
QCOMPARE(profile->cachePath(), QString());
- QCOMPARE(profile->persistentStoragePath(),
- QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
- + QStringLiteral("/QtWebEngine/OffTheRecord"));
+ QCOMPARE(profile->persistentStoragePath(), StandardAppDataLocation() + QStringLiteral("/QtWebEngine/OffTheRecord"));
// TBD: setters do not really work
profile->setCachePath(QStringLiteral("/home/foo/bar"));
QCOMPARE(profile->cachePath(), QString());
@@ -140,18 +112,15 @@ void tst_QWebEngineProfile::defaultProfile()
QCOMPARE(profile->persistentCookiesPolicy(), QWebEngineProfile::NoPersistentCookies);
}
-
-void tst_QWebEngineProfile::testProfile()
+void tst_QWebEngineProfile::userDefinedProfile()
{
QWebEngineProfile profile(QStringLiteral("Test"));
QVERIFY(!profile.isOffTheRecord());
QCOMPARE(profile.storageName(), QStringLiteral("Test"));
QCOMPARE(profile.httpCacheType(), QWebEngineProfile::DiskHttpCache);
QCOMPARE(profile.persistentCookiesPolicy(), QWebEngineProfile::AllowPersistentCookies);
- QCOMPARE(profile.cachePath(), QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
- + QStringLiteral("/QtWebEngine/Test"));
- QCOMPARE(profile.persistentStoragePath(), QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
- + QStringLiteral("/QtWebEngine/Test"));
+ QCOMPARE(profile.cachePath(), StandardCacheLocation() + QStringLiteral("/QtWebEngine/Test"));
+ QCOMPARE(profile.persistentStoragePath(), StandardAppDataLocation() + QStringLiteral("/QtWebEngine/Test"));
}
class AutoDir : public QDir
@@ -221,6 +190,7 @@ void tst_QWebEngineProfile::clearDataFromCache()
AutoDir cacheDir("./tst_QWebEngineProfile_clearDataFromCache");
QWebEngineProfile profile(QStringLiteral("clearDataFromCache"));
+ QSignalSpy cacheSpy(&profile, &QWebEngineProfile::clearHttpCacheCompleted);
profile.setCachePath(cacheDir.path());
profile.setHttpCacheType(QWebEngineProfile::DiskHttpCache);
@@ -232,8 +202,7 @@ void tst_QWebEngineProfile::clearDataFromCache()
QVERIFY(cacheDir.exists("Cache"));
qint64 sizeBeforeClear = totalSize(cacheDir);
profile.clearHttpCache();
- // Wait for cache to be cleared.
- QTest::qWait(1000);
+ QTRY_COMPARE(cacheSpy.size(), 1);
QVERIFY(sizeBeforeClear > totalSize(cacheDir));
(void)server.stop();
@@ -296,10 +265,12 @@ public:
QList<QPointer<QBuffer>> m_buffers;
};
-class StreamingIODevice : public QIODevice {
+// an evil version constantly claiming to be at end, similar to QNetworkReply
+class StreamingIODeviceBasic : public QIODevice
+{
Q_OBJECT
public:
- StreamingIODevice(QObject *parent) : QIODevice(parent), m_bytesRead(0), m_bytesAvailable(0)
+ StreamingIODeviceBasic(QObject *parent) : QIODevice(parent), m_bytesRead(0), m_bytesAvailable(0)
{
setOpenMode(QIODevice::ReadOnly);
m_timer.start(100, this);
@@ -310,12 +281,11 @@ public:
const std::lock_guard<QRecursiveMutex> lock(m_mutex);
return m_bytesAvailable;
}
- bool atEnd() const override
+protected:
+ bool internalAtEnd() const
{
- const std::lock_guard<QRecursiveMutex> lock(m_mutex);
return (m_data.size() >= 1000 && m_bytesRead >= 1000);
}
-protected:
void timerEvent(QTimerEvent *) override
{
const std::lock_guard<QRecursiveMutex> lock(m_mutex);
@@ -336,7 +306,7 @@ protected:
memcpy(data, m_data.constData() + m_bytesRead, len);
m_bytesAvailable -= len;
m_bytesRead += len;
- } else if (atEnd())
+ } else if (internalAtEnd())
return -1;
return len;
@@ -346,14 +316,26 @@ protected:
return 0;
}
-private:
mutable QRecursiveMutex m_mutex;
+private:
QByteArray m_data;
QBasicTimer m_timer;
int m_bytesRead;
int m_bytesAvailable;
};
+// A nicer version implementing atEnd
+class StreamingIODevice : public StreamingIODeviceBasic
+{
+public:
+ StreamingIODevice(QObject *parent) : StreamingIODeviceBasic(parent) {}
+ bool atEnd() const override
+ {
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
+ return internalAtEnd();
+ }
+};
+
class StreamingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
{
public:
@@ -368,6 +350,20 @@ public:
}
};
+class StreamingUrlSchemeHandler2 : public QWebEngineUrlSchemeHandler
+{
+public:
+ StreamingUrlSchemeHandler2(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ }
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ job->reply("text/plain;charset=utf-8", new StreamingIODeviceBasic(job));
+ }
+};
+
void tst_QWebEngineProfile::urlSchemeHandlers()
{
RedirectingUrlSchemeHandler lettertoHandler;
@@ -411,8 +407,8 @@ void tst_QWebEngineProfile::urlSchemeHandlers()
QCOMPARE(toPlainTextSync(view.page()), url.toString());
// Check that all buffers got deleted
- QCOMPARE(gopherHandler.m_buffers.count(), 2);
- for (int i = 0; i < gopherHandler.m_buffers.count(); ++i)
+ QCOMPARE(gopherHandler.m_buffers.size(), 2);
+ for (int i = 0; i < gopherHandler.m_buffers.size(); ++i)
QVERIFY(gopherHandler.m_buffers.at(i).isNull());
}
@@ -473,7 +469,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerFailRequest()
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
view.load(QUrl(QStringLiteral("foo://bar")));
view.show();
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
QCOMPARE(toPlainTextSync(view.page()), QString());
}
@@ -488,7 +484,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerFailOnRead()
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
view.load(QUrl(QStringLiteral("foo://bar")));
view.show();
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
QCOMPARE(toPlainTextSync(view.page()), QString());
}
@@ -503,7 +499,24 @@ void tst_QWebEngineProfile::urlSchemeHandlerStreaming()
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
view.load(QUrl(QStringLiteral("stream://whatever")));
view.show();
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
+ QByteArray result;
+ result.append(1000, 'c');
+ QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result));
+}
+
+void tst_QWebEngineProfile::urlSchemeHandlerStreaming2()
+{
+ StreamingUrlSchemeHandler2 handler;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("stream", &handler);
+ QWebEngineView view;
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setPage(new QWebEnginePage(&profile, &view));
+ view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ view.load(QUrl(QStringLiteral("stream://whatever")));
+ view.show();
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
QByteArray result;
result.append(1000, 'c');
QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result));
@@ -564,7 +577,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders()
QWebEnginePage page(&profile);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl(QStringLiteral("myscheme://whatever")));
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
}
void tst_QWebEngineProfile::urlSchemeHandlerInstallation()
@@ -730,12 +743,12 @@ void tst_QWebEngineProfile::urlSchemeHandlerScriptModule()
QWebEnginePage page(&profile);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(QStringLiteral("<html><head><script src=\"aviancarrier:///\"></script></head><body>Test1</body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("test")).toString(), QStringLiteral("SUCCESS"));
loadFinishedSpy.clear();
page.setHtml(QStringLiteral("<html><head><script type=\"module\" src=\"aviancarrier:///\"></script></head><body>Test2</body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("test")).toString(), QStringLiteral("SUCCESS"));
}
@@ -770,7 +783,7 @@ void tst_QWebEngineProfile::customUserAgent()
QWebEnginePage page;
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(QStringLiteral("<html><body>Hello world!</body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
// First test the user-agent is default
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), defaultUserAgent);
@@ -783,7 +796,7 @@ void tst_QWebEngineProfile::customUserAgent()
QWebEnginePage page2(&testProfile);
QSignalSpy loadFinishedSpy2(&page2, SIGNAL(loadFinished(bool)));
page2.setHtml(QStringLiteral("<html><body>Hello again!</body></html>"));
- QTRY_COMPARE(loadFinishedSpy2.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy2.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page2, QStringLiteral("navigator.userAgent")).toString(), testUserAgent);
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), defaultUserAgent);
@@ -797,7 +810,7 @@ void tst_QWebEngineProfile::httpAcceptLanguage()
QWebEnginePage page;
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(QStringLiteral("<html><body>Hello world!</body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QStringList defaultLanguages = evaluateJavaScriptSync(&page, QStringLiteral("navigator.languages")).toStringList();
@@ -809,7 +822,7 @@ void tst_QWebEngineProfile::httpAcceptLanguage()
QWebEnginePage page2(&testProfile);
QSignalSpy loadFinishedSpy2(&page2, SIGNAL(loadFinished(bool)));
page2.setHtml(QStringLiteral("<html><body>Hello again!</body></html>"));
- QTRY_COMPARE(loadFinishedSpy2.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy2.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page2, QStringLiteral("navigator.languages")).toStringList(), QStringList(testLang));
// Test the old one wasn't affected
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.languages")).toStringList(), defaultLanguages);
@@ -826,7 +839,7 @@ void tst_QWebEngineProfile::downloadItem()
QWebEnginePage page(&testProfile);
QSignalSpy downloadSpy(&testProfile, SIGNAL(downloadRequested(QWebEngineDownloadRequest *)));
page.load(QUrl::fromLocalFile(QCoreApplication::applicationFilePath()));
- QTRY_COMPARE(downloadSpy.count(), 1);
+ QTRY_COMPARE(downloadSpy.size(), 1);
}
void tst_QWebEngineProfile::changePersistentPath()
@@ -952,29 +965,29 @@ void tst_QWebEngineProfile::initiator()
QWebEnginePage page(&profile, nullptr);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl("about:blank"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
loadFinishedSpy.clear();
// about:blank has a unique origin, so initiator should be QUrl("null")
evaluateJavaScriptSync(&page, "window.location = 'foo:bar'");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
loadFinishedSpy.clear();
QCOMPARE(handler.initiator, QUrl("null"));
page.setHtml("", QUrl("http://test:123/foo%20bar"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
loadFinishedSpy.clear();
// baseUrl determines the origin, so QUrl("http://test:123")
evaluateJavaScriptSync(&page, "window.location = 'foo:bar'");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
loadFinishedSpy.clear();
QCOMPARE(handler.initiator, QUrl("http://test:123"));
// Directly calling load/setUrl should have initiator QUrl(), meaning
// browser-initiated, trusted.
page.load(QUrl("foo:bar"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 10000);
QCOMPARE(handler.initiator, QUrl());
}
@@ -990,7 +1003,7 @@ void tst_QWebEngineProfile::badDeleteOrder()
QSignalSpy spyLoadFinished(page, SIGNAL(loadFinished(bool)));
page->setHtml(QStringLiteral("<html><body><h1>Badly handled page!</h1></body></html>"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
delete profile;
delete view;
@@ -1006,7 +1019,7 @@ void tst_QWebEngineProfile::qtbug_71895()
view.page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache);
view.page()->profile()->cookieStore()->deleteAllCookies();
view.page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
- bool gotSignal = loadSpy.count() || loadSpy.wait(20000);
+ bool gotSignal = loadSpy.size() || loadSpy.wait(20000);
if (!gotSignal)
QSKIP("Couldn't load page from network, skipping test.");
}
diff --git a/tests/auto/widgets/qwebenginescript/CMakeLists.txt b/tests/auto/widgets/qwebenginescript/CMakeLists.txt
index 6e768cf90..d0d499b84 100644
--- a/tests/auto/widgets/qwebenginescript/CMakeLists.txt
+++ b/tests/auto/widgets/qwebenginescript/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebenginescript
diff --git a/tests/auto/widgets/qwebenginescript/resources/test_window_open.html b/tests/auto/widgets/qwebenginescript/resources/test_window_open.html
index 3f72d176d..3ceafc49d 100644
--- a/tests/auto/widgets/qwebenginescript/resources/test_window_open.html
+++ b/tests/auto/widgets/qwebenginescript/resources/test_window_open.html
@@ -3,7 +3,7 @@
<head>
<title>window.open</title>
<script>
- window.open("qrc:/resource/test_iframe_main.html", "iframe_main");
+ window.open("qrc:/resources/test_iframe_main.html", "iframe_main");
</script>
</head>
<body></body>
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 5df9f035f..9ba13589f 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -76,6 +76,7 @@ private Q_SLOTS:
void scriptsInNestedIframes();
void matchQrcUrl();
void injectionOrder();
+ void reloadWithSubframes();
};
void tst_QWebEngineScript::domEditing()
@@ -184,7 +185,7 @@ void tst_QWebEngineScript::loadEvents()
// Single frame / setHtml
page.setHtml(QStringLiteral("<!DOCTYPE html><html><head><title>mr</title></head><body></body></html>"));
- QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.size(), 1, 20000);
QVERIFY(page.spy.takeFirst().value(0).toBool());
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
@@ -192,14 +193,14 @@ void tst_QWebEngineScript::loadEvents()
// After discard
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.size(), 1, 20000);
QVERIFY(page.spy.takeFirst().value(0).toBool());
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
// Multiple frames
page.load(QUrl("qrc:/resources/test_iframe_main.html"));
- QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.size(), 1, 20000);
QVERIFY(page.spy.takeFirst().value(0).toBool());
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
@@ -210,7 +211,7 @@ void tst_QWebEngineScript::loadEvents()
// Cross-process navigation
page.load(QUrl("chrome://gpu"));
- QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.size(), 1, 20000);
QVERIFY(page.spy.takeFirst().value(0).toBool());
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
@@ -218,9 +219,9 @@ void tst_QWebEngineScript::loadEvents()
// Using window.open from JS
QVERIFY(profile.pages.size() == 1);
page.load(QUrl("qrc:/resources/test_window_open.html"));
- QTRY_COMPARE(profile.pages.size(), 2);
- QTRY_COMPARE(profile.pages.front().spy.count(), 1);
- QTRY_COMPARE(profile.pages.back().spy.count(), 1);
+ QTRY_COMPARE(profile.pages.size(), 2u);
+ QTRY_COMPARE(profile.pages.front().spy.size(), 1);
+ QTRY_COMPARE(profile.pages.back().spy.size(), 1);
QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::MainWorld).toStringList()));
QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::MainWorld).toStringList()));
@@ -271,7 +272,7 @@ void tst_QWebEngineScript::scriptDisabled()
page.scripts().insert(script);
page.load(QUrl("about:blank"));
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
// MainWorld scripts are disabled by the setting...
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::MainWorld), QVariant());
@@ -280,7 +281,7 @@ void tst_QWebEngineScript::scriptDisabled()
page.scripts().clear();
page.scripts().insert(script);
page.load(QUrl("about:blank"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
// ...but ApplicationWorld scripts should still work
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::MainWorld), QVariant());
@@ -298,7 +299,7 @@ void tst_QWebEngineScript::viewSource()
page.scripts().insert(script);
page.load(QUrl("view-source:about:blank"));
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(evaluateJavaScriptSync(&page, "foo"), QVariant(42));
}
@@ -457,7 +458,7 @@ void tst_QWebEngineScript::scriptsInNestedIframes()
QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
page.load(QUrl("qrc:/resources/test_iframe_main.html"));
view.show();
- QVERIFY(spyFinished.wait());
+ QTRY_VERIFY_WITH_TIMEOUT(spyFinished.size() > 0, 20000);
// Check that main frame has modified content.
QCOMPARE(
@@ -557,22 +558,22 @@ void tst_QWebEngineScript::navigation()
QString url1 = QStringLiteral("about:blank");
page.setUrl(url1);
- QTRY_COMPARE(spyTextChanged.count(), 1);
+ QTRY_COMPARE(spyTextChanged.size(), 1);
QCOMPARE(testObject.text(), url1);
QString url2 = QStringLiteral("chrome://gpu/");
page.setUrl(url2);
- QTRY_COMPARE(spyTextChanged.count(), 2);
+ QTRY_COMPARE(spyTextChanged.size(), 2);
QCOMPARE(testObject.text(), url2);
QString url3 = QStringLiteral("qrc:/resources/test_iframe_main.html");
page.setUrl(url3);
- QTRY_COMPARE(spyTextChanged.count(), 3);
+ QTRY_COMPARE(spyTextChanged.size(), 3);
QCOMPARE(testObject.text(), url3);
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
page.setUrl(url1);
- QTRY_COMPARE(spyTextChanged.count(), 4);
+ QTRY_COMPARE(spyTextChanged.size(), 4);
QCOMPARE(testObject.text(), url1);
}
@@ -694,6 +695,38 @@ void tst_QWebEngineScript::injectionOrder()
QTRY_COMPARE(page.log, expected);
}
+void tst_QWebEngineScript::reloadWithSubframes()
+{
+ class Page : public QWebEnginePage
+ {
+ public:
+ Page() : QWebEnginePage() {}
+ QVector<QString> log;
+
+ protected:
+ void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel, const QString &message, int,
+ const QString &) override
+ {
+ log.append(message);
+ }
+ } page;
+
+ QWebEngineScript s;
+ s.setInjectionPoint(QWebEngineScript::DocumentCreation);
+ s.setSourceCode(QStringLiteral("console.log('Hello');"));
+ page.scripts().insert(s);
+
+ page.setHtml(QStringLiteral("<body>"
+ " <h1>Test scripts working on reload </h1>"
+ " <iframe src='about://blank'>"
+ " </iframe>"
+ "</body>"));
+ QTRY_COMPARE(page.log.size(), 1);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(page.log.size(), 2);
+}
+
QTEST_MAIN(tst_QWebEngineScript)
#include "tst_qwebenginescript.moc"
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index eccf02971..26f2da4bb 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -1,14 +1,12 @@
-[microFocusCoordinates]
-osx
+[mixLangLocale:eu_ES]
+*
-[visibilityState3]
+[navigateOnDrop:file]
windows
-[horizontalScrollbarTest]
-osx
-
-[mixLangLocale:eu_ES]
-*
+[navigateOnDrop:file_no_navigate]
+windows
-[reusePage]
-b2qt arm
+[horizontalScrollbarTest]
+macos
+rhel # flaky
diff --git a/tests/auto/widgets/qwebengineview/CMakeLists.txt b/tests/auto/widgets/qwebengineview/CMakeLists.txt
index b06ee7201..9583184d0 100644
--- a/tests/auto/widgets/qwebengineview/CMakeLists.txt
+++ b/tests/auto/widgets/qwebengineview/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebengineview
diff --git a/tests/auto/widgets/qwebengineview/resources/dummy.html b/tests/auto/widgets/qwebengineview/resources/dummy.html
index 9075f27c3..f5ba1963a 100644
--- a/tests/auto/widgets/qwebengineview/resources/dummy.html
+++ b/tests/auto/widgets/qwebengineview/resources/dummy.html
@@ -1,6 +1,6 @@
<html><head>
<title>Dummy simple page without real content</title>
-<link rel='icon' href='resources/image2.png'/>
+<link rel='icon' href='qrc:///resources/image2.png'/>
</head><body>
<a>This is test content</a>
</body></html>
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index d6a945e65..f4ed06e14 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -18,6 +18,9 @@
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
+
#include <QtWebEngineCore/private/qtwebenginecore-config_p.h>
#include <qtest.h>
#include <util.h>
@@ -34,14 +37,18 @@
#include <qtemporarydir.h>
#include <QClipboard>
#include <QCompleter>
+#include <QDropEvent>
#include <QLabel>
#include <QLineEdit>
+#include <QListView>
#include <QHBoxLayout>
#include <QMenu>
+#include <QMimeData>
#include <QQuickItem>
#include <QQuickWidget>
#include <QtWebEngineCore/qwebenginehttprequest.h>
#include <QScopeGuard>
+#include <QStringListModel>
#include <QTcpServer>
#include <QTcpSocket>
#include <QStyle>
@@ -68,7 +75,8 @@ namespace QTest {
{
QTest::qWait(QTest::defaultMouseDelay());
lastMouseTimestamp += QTest::defaultMouseDelay();
- QMouseEvent me(type, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent me(type, pos, widget->mapToGlobal(pos), Qt::LeftButton, Qt::LeftButton,
+ Qt::NoModifier);
me.setTimestamp(++lastMouseTimestamp);
QSpontaneKeyEvent::setSpontaneous(&me);
qApp->sendEvent(widget, &me);
@@ -104,6 +112,7 @@ private Q_SLOTS:
void changePage();
void reusePage_data();
void reusePage();
+ void setLoadedPage();
void microFocusCoordinates();
void focusInputTypes();
void unhandledKeyEventPropagation();
@@ -149,7 +158,7 @@ private Q_SLOTS:
void mouseLeave();
-#ifndef QT_NO_CLIPBOARD
+#if QT_CONFIG(clipboard)
void globalMouseSelection();
#endif
void noContextMenu();
@@ -173,6 +182,13 @@ private Q_SLOTS:
void setViewPreservesExplicitPage();
void closeDiscardsPage();
void loadAfterRendererCrashed();
+ void inspectElement();
+ void navigateOnDrop_data();
+ void navigateOnDrop();
+ void emptyUriListOnDrop();
+ void datalist();
+ void longKeyEventText();
+ void pageWithPaintListeners();
};
// This will be called before the first test function is executed.
@@ -195,6 +211,96 @@ void tst_QWebEngineView::init()
// This will be called after every test function.
void tst_QWebEngineView::cleanup()
{
+ QTRY_COMPARE(QApplication::topLevelWidgets().size(), 0);
+}
+
+class PageWithPaintListeners : public QWebEnginePage
+{
+ Q_OBJECT
+public:
+ PageWithPaintListeners(QObject *parent = nullptr) : QWebEnginePage(parent)
+ {
+ addFirstContentfulPaintListener();
+ addLargestContentfulPaintListener();
+ }
+
+ void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message,
+ int lineNumber, const QString &sourceID) override
+ {
+ Q_UNUSED(level)
+ Q_UNUSED(lineNumber)
+ Q_UNUSED(sourceID)
+ if (message.contains("firstContentfulPaint"))
+ emit firstContentfulPaint();
+ if (message.contains("largestContentfulPaint"))
+ emit largestContentfulPaint();
+ }
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver
+ void addFirstContentfulPaintListener()
+ {
+ QObject::connect(this, &QWebEnginePage::loadFinished, [this]() {
+ runJavaScript(QStringLiteral(
+ "new PerformanceObserver((entryList) => {"
+ " if (entryList.getEntriesByType('first-contentful-paint'))"
+ " console.log('firstContentfulPaint');"
+ "}).observe({type: 'paint', buffered: true});"));
+ });
+ }
+
+ void addLargestContentfulPaintListener()
+ {
+ QObject::connect(this, &QWebEnginePage::loadFinished, [this]() {
+ runJavaScript(QStringLiteral(
+ "new PerformanceObserver((entryList) => {"
+ " console.log('largestContentfulPaint');"
+ "}).observe({type: 'largest-contentful-paint', buffered: true});"));
+ });
+ }
+
+signals:
+ void firstContentfulPaint(); // https://web.dev/articles/fcp
+ void largestContentfulPaint(); // https://web.dev/articles/lcp
+};
+
+void tst_QWebEngineView::pageWithPaintListeners()
+{
+ PageWithPaintListeners page;
+
+ QSignalSpy firstContentfulPaintSpy(&page, &PageWithPaintListeners::firstContentfulPaint);
+ QSignalSpy largestContentfulPaintSpy(&page, &PageWithPaintListeners::largestContentfulPaint);
+
+ const QString empty =
+ QStringLiteral("<html><body style='width:100x;height:100px;'></body></html>");
+ const QString scrollBars =
+ QStringLiteral("<html><body style='width:1000px;height:1000px;'></body></html>");
+ const QString backgroundColor =
+ QStringLiteral("<html><body style='background-color:green'></body></html>");
+ const QString text = QStringLiteral("<html><body>text</body></html>");
+
+ QWebEngineView view;
+ view.setPage(&page);
+ view.resize(600, 600);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.setHtml(empty);
+ QTest::qWait(500); // empty page should not trigger
+ QVERIFY(firstContentfulPaintSpy.size() == 0);
+ QVERIFY(largestContentfulPaintSpy.size() == 0);
+
+ page.setHtml(backgroundColor);
+ QTRY_VERIFY(firstContentfulPaintSpy.size() == 1);
+
+ page.setHtml(text);
+ QTRY_VERIFY(firstContentfulPaintSpy.size() == 2);
+ QTRY_VERIFY(largestContentfulPaintSpy.size() == 1);
+
+#if !QT_CONFIG(webengine_embedded_build)
+ // Embedded builds have different scrollbars that are only painted on hover
+ page.setHtml(scrollBars);
+ QTRY_VERIFY(firstContentfulPaintSpy.size() == 3);
+#endif
}
void tst_QWebEngineView::renderHints()
@@ -293,10 +399,10 @@ void tst_QWebEngineView::changePage()
QSignalSpy pageFromLoadSpy(pageFrom.get(), &QWebEnginePage::loadFinished);
QSignalSpy pageFromIconLoadSpy(pageFrom.get(), &QWebEnginePage::iconChanged);
pageFrom->load(urlFrom);
- QTRY_COMPARE(pageFromLoadSpy.count(), 1);
+ QTRY_COMPARE(pageFromLoadSpy.size(), 1);
QCOMPARE(pageFromLoadSpy.last().value(0).toBool(), true);
if (!fromIsNullPage) {
- QTRY_COMPARE(pageFromIconLoadSpy.count(), 1);
+ QTRY_COMPARE(pageFromIconLoadSpy.size(), 1);
QVERIFY(!pageFromIconLoadSpy.last().value(0).isNull());
}
@@ -304,13 +410,13 @@ void tst_QWebEngineView::changePage()
QCOMPARE(view->page(), pageFrom.get());
QCOMPARE(QWebEngineView::forPage(pageFrom.get()), view.get());
- QTRY_COMPARE(spyUrl.count(), 1);
+ QTRY_COMPARE(spyUrl.size(), 1);
QCOMPARE(spyUrl.last().value(0).toUrl(), pageFrom->url());
- QTRY_COMPARE(spyTitle.count(), 1);
+ QTRY_COMPARE(spyTitle.size(), 1);
QCOMPARE(spyTitle.last().value(0).toString(), pageFrom->title());
- QTRY_COMPARE(spyIconUrl.count(), fromIsNullPage ? 0 : 1);
- QTRY_COMPARE(spyIcon.count(), fromIsNullPage ? 0 : 1);
+ QTRY_COMPARE(spyIconUrl.size(), fromIsNullPage ? 0 : 1);
+ QTRY_COMPARE(spyIcon.size(), fromIsNullPage ? 0 : 1);
if (!fromIsNullPage) {
QVERIFY(!pageFrom->iconUrl().isEmpty());
QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageFrom->iconUrl());
@@ -322,10 +428,10 @@ void tst_QWebEngineView::changePage()
QSignalSpy pageToLoadSpy(pageTo.get(), &QWebEnginePage::loadFinished);
QSignalSpy pageToIconLoadSpy(pageTo.get(), &QWebEnginePage::iconChanged);
pageTo->load(urlTo);
- QTRY_COMPARE(pageToLoadSpy.count(), 1);
+ QTRY_COMPARE(pageToLoadSpy.size(), 1);
QCOMPARE(pageToLoadSpy.last().value(0).toBool(), true);
if (!toIsNullPage) {
- QTRY_COMPARE(pageToIconLoadSpy.count(), 1);
+ QTRY_COMPARE(pageToIconLoadSpy.size(), 1);
QVERIFY(!pageToIconLoadSpy.last().value(0).isNull());
}
@@ -334,16 +440,16 @@ void tst_QWebEngineView::changePage()
QCOMPARE(QWebEngineView::forPage(pageTo.get()), view.get());
QCOMPARE(QWebEngineView::forPage(pageFrom.get()), nullptr);
- QTRY_COMPARE(spyUrl.count(), 2);
+ QTRY_COMPARE(spyUrl.size(), 2);
QCOMPARE(spyUrl.last().value(0).toUrl(), pageTo->url());
- QTRY_COMPARE(spyTitle.count(), 2);
+ QTRY_COMPARE(spyTitle.size(), 2);
QCOMPARE(spyTitle.last().value(0).toString(), pageTo->title());
bool iconIsSame = fromIsNullPage == toIsNullPage;
int iconChangeNotifyCount = fromIsNullPage ? (iconIsSame ? 0 : 1) : (iconIsSame ? 1 : 2);
- QTRY_COMPARE(spyIconUrl.count(), iconChangeNotifyCount);
- QTRY_COMPARE(spyIcon.count(), iconChangeNotifyCount);
+ QTRY_COMPARE(spyIconUrl.size(), iconChangeNotifyCount);
+ QTRY_COMPARE(spyIcon.size(), iconChangeNotifyCount);
QCOMPARE(pageFrom->iconUrl() == pageTo->iconUrl(), iconIsSame);
if (!iconIsSame) {
QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageTo->iconUrl());
@@ -354,10 +460,10 @@ void tst_QWebEngineView::changePage()
// verify no emits on destroy with the same number of signals in spy
view.reset();
qApp->processEvents();
- QTRY_COMPARE(spyUrl.count(), 2);
- QTRY_COMPARE(spyTitle.count(), 2);
- QTRY_COMPARE(spyIconUrl.count(), iconChangeNotifyCount);
- QTRY_COMPARE(spyIcon.count(), iconChangeNotifyCount);
+ QTRY_COMPARE(spyUrl.size(), 2);
+ QTRY_COMPARE(spyTitle.size(), 2);
+ QTRY_COMPARE(spyIconUrl.size(), iconChangeNotifyCount);
+ QTRY_COMPARE(spyIcon.size(), iconChangeNotifyCount);
}
void tst_QWebEngineView::reusePage_data()
@@ -394,7 +500,7 @@ void tst_QWebEngineView::reusePage()
view1->show();
QVERIFY(QTest::qWaitForWindowExposed(view1));
delete view1;
- QVERIFY(page != 0); // deleting view must not have deleted the page, since it's not a child of view
+ QVERIFY(page != nullptr); // deleting view must not have deleted the page, since it's not a child of view
QWebEngineView *view2 = new QWebEngineView;
view2->setPage(page.data());
@@ -407,6 +513,23 @@ void tst_QWebEngineView::reusePage()
QDir::setCurrent(QApplication::applicationDirPath());
}
+void tst_QWebEngineView::setLoadedPage()
+{
+ // MEMO load page first to make sure that just simple attach to view would draw its content
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ page.setHtml(QString("<html><body bgcolor=\"%1\"></body></html>").arg(QColor(Qt::yellow).name()));
+ QTRY_VERIFY(loadSpy.size() == 1 && loadSpy.first().first().toBool());
+
+ QWebEngineView view;
+ view.resize(480, 320);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ view.setPage(&page);
+ QTRY_COMPARE(view.grab().toImage().pixelColor(QPoint(view.width() / 2, view.height() / 2)), Qt::yellow);
+}
+
// Class used in crashTests
class WebViewCrashTest : public QObject {
Q_OBJECT
@@ -481,7 +604,7 @@ void tst_QWebEngineView::microFocusCoordinates()
QVariant initialMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle);
evaluateJavaScriptSync(webView.page(), "window.scrollBy(0, 50)");
- QTRY_VERIFY(scrollSpy.count() > 0);
+ QTRY_VERIFY(scrollSpy.size() > 0);
QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle).isValid());
QVariant currentMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle);
@@ -592,6 +715,7 @@ void tst_QWebEngineView::focusInputTypes()
class KeyEventRecordingWidget : public QWidget {
public:
+ ~KeyEventRecordingWidget() { qDeleteAll(pressEvents); qDeleteAll(releaseEvents); }
QList<QKeyEvent *> pressEvents;
QList<QKeyEvent *> releaseEvents;
void keyPressEvent(QKeyEvent *e) override { pressEvents << e->clone(); }
@@ -608,7 +732,7 @@ void tst_QWebEngineView::unhandledKeyEventPropagation()
QSignalSpy loadFinishedSpy(&webView, SIGNAL(loadFinished(bool)));
webView.load(QUrl("qrc:///resources/keyboardEvents.html"));
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_VERIFY_WITH_TIMEOUT(loadFinishedSpy.size() > 0, 20000);
evaluateJavaScriptSync(webView.page(), "document.getElementById('first_div').focus()");
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("first_div"));
@@ -654,19 +778,29 @@ void tst_QWebEngineView::unhandledKeyEventPropagation()
void tst_QWebEngineView::horizontalScrollbarTest()
{
+#if QT_CONFIG(webengine_embedded_build)
+ // Embedded builds enable the OverlayScrollbar and Viewport features (see 'useEmbeddedSwitches' in web_engine_context.cpp).
+ // These features make the scrollbar simpler assuming we are on a device with small (usually touch) display.
+ // These scrollbars behave differently on mouse events.
+ QSKIP("Embedded builds have different scrollbar, skipping test.");
+#endif
QString html("<html><body>"
"<div style='width: 1000px; height: 1000px; background-color: green' />"
"</body></html>");
QWebEngineView view;
+ PageWithPaintListeners page;
+ view.setPage(&page);
view.setFixedSize(600, 600);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QSignalSpy firstPaintSpy(&page, &PageWithPaintListeners::firstContentfulPaint);
QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QTRY_COMPARE(firstPaintSpy.size(), 1);
QVERIFY(view.page()->scrollPosition() == QPoint(0, 0));
QSignalSpy scrollSpy(view.page(), SIGNAL(scrollPositionChanged(QPointF)));
@@ -903,7 +1037,7 @@ public:
case QEvent::ContextMenu:
case QEvent::KeyPress:
case QEvent::KeyRelease:
-#ifndef QT_NO_WHEELEVENT
+#if QT_CONFIG(wheelevent)
case QEvent::Wheel:
#endif
++m_eventCounter;
@@ -958,7 +1092,7 @@ void tst_QWebEngineView::doNotSendMouseKeyboardEventsWhenDisabled()
QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool)));
webView.setHtml("<html><head><title>Title</title></head><body>Hello"
"<input id=\"input\" type=\"text\"></body></html>");
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// When the webView is enabled, the events are swallowed by it, and the parent widget
// does not receive any events, otherwise all events are processed by the parent widget.
@@ -1005,7 +1139,7 @@ void tst_QWebEngineView::stopSettingFocusWhenDisabled()
QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool)));
webView.setHtml("<html><head><title>Title</title></head><body>Hello"
"<input id=\"input\" type=\"text\"></body></html>");
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QTRY_COMPARE_WITH_TIMEOUT(webView.hasFocus(), focusResult, 1000);
evaluateJavaScriptSync(webView.page(), "document.getElementById(\"input\").focus()");
@@ -1118,21 +1252,23 @@ void tst_QWebEngineView::focusInternalRenderWidgetHostViewQuickItem()
QWebEngineView *webView = new QWebEngineView;
QWebEngineSettings *settings = webView->page()->settings();
settings->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
- webView->resize(300, 300);
+ webView->resize(300, 100);
- QHBoxLayout *layout = new QHBoxLayout;
+ QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
layout->addWidget(webView);
+ containerWidget->resize(300, 200);
containerWidget->setLayout(layout);
containerWidget->show();
QVERIFY(QTest::qWaitForWindowExposed(containerWidget.data()));
// Load the content, and check that focus is not set.
QSignalSpy loadSpy(webView, SIGNAL(loadFinished(bool)));
- webView->setHtml("<html><head><title>Title</title></head><body>Hello"
- "<input id=\"input\" type=\"text\"></body></html>");
- QTRY_COMPARE(loadSpy.count(), 1);
+ webView->setHtml("<html><body>"
+ " <input id='input1' type='text'/>"
+ "</body></html>");
+ QTRY_COMPARE(loadSpy.size(), 1);
QTRY_COMPARE(webView->hasFocus(), false);
// Manually trigger focus.
@@ -1141,15 +1277,43 @@ void tst_QWebEngineView::focusInternalRenderWidgetHostViewQuickItem()
// Check that focus is set in QWebEngineView and all internal classes.
QTRY_COMPARE(webView->hasFocus(), true);
- QQuickWidget *renderWidgetHostViewQtDelegateWidget =
- qobject_cast<QQuickWidget *>(webView->focusProxy());
- QVERIFY(renderWidgetHostViewQtDelegateWidget);
- QTRY_COMPARE(renderWidgetHostViewQtDelegateWidget->hasFocus(), true);
+ QQuickWidget *webEngineQuickWidget = qobject_cast<QQuickWidget *>(webView->focusProxy());
+ QVERIFY(webEngineQuickWidget);
+ QTRY_COMPARE(webEngineQuickWidget->hasFocus(), true);
+
+ QQuickItem *root = webEngineQuickWidget->rootObject();
+ // The root item should not has focus, otherwise it would handle input events
+ // instead of the RenderWidgetHostViewQtDelegateItem.
+ QVERIFY(!root->hasFocus());
+
+ QCOMPARE(root->childItems().size(), 1);
+ QQuickItem *renderWidgetHostViewQtDelegateItem = root->childItems().at(0);
+ QVERIFY(renderWidgetHostViewQtDelegateItem);
+ QTRY_COMPARE(renderWidgetHostViewQtDelegateItem->hasFocus(), true);
+ // Test if QWebEngineView handles key events.
+ QTRY_COMPARE(renderWidgetHostViewQtDelegateItem->hasActiveFocus(), true);
+
+ // Key events should not be forwarded to the unfocused input field.
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(),
+ "document.getElementById('input1').value").toString(),
+ QStringLiteral(""));
+ QTest::keyClick(webView->focusProxy(), Qt::Key_X);
+ QTest::qWait(100);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(),
+ "document.getElementById('input1').value").toString(),
+ QStringLiteral(""));
+
+ // Focus the input field. Focus rectangle is expected to appear around the input field.
+ evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(),
+ "document.activeElement.id").toString(),
+ QStringLiteral("input1"));
- QQuickItem *renderWidgetHostViewQuickItem =
- renderWidgetHostViewQtDelegateWidget->rootObject();
- QVERIFY(renderWidgetHostViewQuickItem);
- QTRY_COMPARE(renderWidgetHostViewQuickItem->hasFocus(), true);
+ // Test the focused input field with a key event.
+ QTest::keyClick(webView->focusProxy(), Qt::Key_X);
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(),
+ "document.getElementById('input1').value").toString(),
+ QStringLiteral("x"));
}
void tst_QWebEngineView::doNotBreakLayout()
@@ -1189,7 +1353,7 @@ void tst_QWebEngineView::changeLocale()
QWebEngineView viewDE;
QSignalSpy loadFinishedSpyDE(&viewDE, SIGNAL(loadFinished(bool)));
viewDE.load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.size(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
@@ -1199,7 +1363,7 @@ void tst_QWebEngineView::changeLocale()
QWebEngineView viewEN;
QSignalSpy loadFinishedSpyEN(&viewEN, SIGNAL(loadFinished(bool)));
viewEN.load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.size(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty());
errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
@@ -1212,7 +1376,7 @@ void tst_QWebEngineView::changeLocale()
// Check whether an existing QWebEngineView keeps the language settings after changing the default locale
viewDE.load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.size(), 1, 20000);
QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty());
errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts);
@@ -1244,10 +1408,10 @@ void tst_QWebEngineView::mixLangLocale()
auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; });
view.load(QUrl("qrc:///resources/dummy.html"));
- QTRY_VERIFY(terminated || loadSpy.count() == 1);
+ QTRY_VERIFY(terminated || loadSpy.size() == 1);
QVERIFY2(!terminated,
- qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count())));
+ qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.size())));
QVERIFY(loadSpy.first().first().toBool());
QString content = toPlainTextSync(view.page());
@@ -1294,18 +1458,19 @@ void tst_QWebEngineView::inputMethodsTextFormat_data()
void tst_QWebEngineView::inputMethodsTextFormat()
{
- QWebEngineView view;
- view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
- QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ QWebEnginePage page;
+ QWebEngineView view(&page);
+ page.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
- view.setHtml("<html><body>"
+ page.setHtml("<html><body>"
" <input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/>"
"</body></html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
- evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()");
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
+ evaluateJavaScriptSync(&page, "document.getElementById('input1').focus()");
QFETCH(QString, string);
QFETCH(int, start);
@@ -1329,8 +1494,8 @@ void tst_QWebEngineView::inputMethodsTextFormat()
attrs.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format));
QInputMethodEvent im(string, attrs);
- QVERIFY(QApplication::sendEvent(view.focusProxy(), &im));
- QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), string);
+ QApplication::sendEvent(view.focusProxy(), &im);
+ QTRY_COMPARE_WITH_TIMEOUT(evaluateJavaScriptSync(&page, "document.getElementById('input1').value").toString(), string, 20000);
}
void tst_QWebEngineView::keyboardEvents()
@@ -1339,7 +1504,7 @@ void tst_QWebEngineView::keyboardEvents()
view.show();
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.load(QUrl("qrc:///resources/keyboardEvents.html"));
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 30000);
QStringList elements;
elements << "first_div" << "second_div";
@@ -1458,17 +1623,21 @@ void tst_QWebEngineView::keyboardFocusAfterPopup()
QTRY_COMPARE(QApplication::focusWidget(), window.lineEdit);
// Trigger QCompleter's popup and select the first suggestion.
- QTest::keyClick(QApplication::focusWindow(), Qt::Key_T);
+ QTest::keyPress(QApplication::focusWindow(), Qt::Key_T);
+ QTest::keyRelease(QApplication::focusWindow(), Qt::Key_T);
QTRY_VERIFY(QApplication::activePopupWidget());
- QTest::keyClick(QApplication::focusWindow(), Qt::Key_Down);
- QTest::keyClick(QApplication::focusWindow(), Qt::Key_Enter);
+ QTest::keyPress(QApplication::focusWindow(), Qt::Key_Down);
+ QTest::keyRelease(QApplication::focusWindow(), Qt::Key_Down);
+ QTest::keyPress(QApplication::focusWindow(), Qt::Key_Enter);
+ QTest::keyRelease(QApplication::focusWindow(), Qt::Key_Enter);
// Due to FocusOnNavigationEnabled, focus should now move to the webView.
QTRY_COMPARE(QApplication::focusWidget(), window.webView->focusProxy());
// Keyboard events sent to the window should go to the <input> element.
- QVERIFY(loadFinishedSpy.count() || loadFinishedSpy.wait());
- QTest::keyClick(QApplication::focusWindow(), Qt::Key_X);
+ QVERIFY(loadFinishedSpy.size() || loadFinishedSpy.wait());
+ QTest::keyPress(QApplication::focusWindow(), Qt::Key_X);
+ QTest::keyRelease(QApplication::focusWindow(), Qt::Key_X);
QTRY_COMPARE(evaluateJavaScriptSync(window.webView->page(), "document.getElementById('input1').value").toString(),
QStringLiteral("x"));
}
@@ -1497,7 +1666,7 @@ void tst_QWebEngineView::mouseClick()
textInputCenter = elementCenter(view.page(), "input");
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
// Double click
@@ -1512,13 +1681,13 @@ void tst_QWebEngineView::mouseClick()
textInputCenter = elementCenter(view.page(), "input");
QTest::mouseMultiClick(view.focusProxy(), textInputCenter, 2);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QStringLiteral("Company"));
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
// Triple click
@@ -1533,13 +1702,13 @@ void tst_QWebEngineView::mouseClick()
textInputCenter = elementCenter(view.page(), "input");
QTest::mouseMultiClick(view.focusProxy(), textInputCenter, 3);
QVERIFY(selectionChangedSpy.wait());
- QTRY_COMPARE(selectionChangedSpy.count(), 2);
+ QTRY_COMPARE(selectionChangedSpy.size(), 2);
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QStringLiteral("The Qt Company"));
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QCOMPARE(selectionChangedSpy.size(), 3);
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
}
@@ -1567,12 +1736,12 @@ void tst_QWebEngineView::postData()
// examine request
QStringList request = lines[0].split(" ", Qt::SkipEmptyParts);
- bool requestOk = request.length() > 2
+ bool requestOk = request.size() > 2
&& request[2].toUpper().startsWith("HTTP/")
&& request[0].toUpper() == "POST"
&& request[1] == "/";
if (!requestOk) // POST and HTTP/... can be switched(?)
- requestOk = request.length() > 2
+ requestOk = request.size() > 2
&& request[0].toUpper().startsWith("HTTP/")
&& request[2].toUpper() == "POST"
&& request[1] == "/";
@@ -1580,16 +1749,16 @@ void tst_QWebEngineView::postData()
// examine headers
int line = 1;
bool headersOk = true;
- for (; headersOk && line < lines.length(); line++) {
+ for (; headersOk && line < lines.size(); line++) {
QStringList headerParts = lines[line].split(":");
- if (headerParts.length() < 2)
+ if (headerParts.size() < 2)
break;
QString headerKey = headerParts[0].trimmed().toLower();
QString headerValue = headerParts[1].trimmed().toLower();
if (headerKey == "host")
headersOk = headersOk && (headerValue == "127.0.0.1")
- && (headerParts.length() == 3)
+ && (headerParts.size() == 3)
&& (headerParts[2].trimmed()
== QString::number(server.serverPort()));
if (headerKey == "content-type")
@@ -1598,12 +1767,12 @@ void tst_QWebEngineView::postData()
// examine body
bool bodyOk = true;
- if (lines.length() == line+2) {
+ if (lines.size() == line+2) {
QStringList postedFields = lines[line+1].split("&");
QMap<QString, QString> postedData;
- for (int i = 0; bodyOk && i < postedFields.length(); i++) {
+ for (int i = 0; bodyOk && i < postedFields.size(); i++) {
QStringList postedField = postedFields[i].split("=");
- if (postedField.length() == 2)
+ if (postedField.size() == 2)
postedData[QUrl::fromPercentEncoding(postedField[0].toLocal8Bit())]
= QUrl::fromPercentEncoding(postedField[1].toLocal8Bit());
else
@@ -1676,11 +1845,10 @@ void tst_QWebEngineView::postData()
void tst_QWebEngineView::inputFieldOverridesShortcuts()
{
+ QWebEngineView view;
bool actionTriggered = false;
- QAction *action = new QAction;
+ QAction *action = new QAction(&view);
connect(action, &QAction::triggered, [&actionTriggered] () { actionTriggered = true; });
-
- QWebEngineView view;
view.addAction(action);
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
@@ -1898,14 +2066,14 @@ void tst_QWebEngineView::inputContextQueryInput()
view.setHtml("<html><body>"
" <input type='text' id='input1' value='' size='50'/>"
"</body></html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QCOMPARE(testContext.infos.count(), 0);
+ QCOMPARE(testContext.infos.size(), 0);
// Set focus on an input field.
QPoint textInputCenter = elementCenter(view.page(), "input1");
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
- QTRY_COMPARE(testContext.infos.count(), 2);
+ QTRY_COMPARE(testContext.infos.size(), 2);
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
foreach (const InputMethodInfo &info, testContext.infos) {
QCOMPARE(info.cursorPosition, 0);
@@ -1917,7 +2085,7 @@ void tst_QWebEngineView::inputContextQueryInput()
// Change content of an input field from JavaScript.
evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value='QtWebEngine';");
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 11);
QCOMPARE(testContext.infos[0].anchorPosition, 11);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine"));
@@ -1926,7 +2094,7 @@ void tst_QWebEngineView::inputContextQueryInput()
// Change content of an input field by key press.
QTest::keyClick(view.focusProxy(), Qt::Key_Exclam);
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 12);
QCOMPARE(testContext.infos[0].anchorPosition, 12);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
@@ -1935,7 +2103,7 @@ void tst_QWebEngineView::inputContextQueryInput()
// Change cursor position.
QTest::keyClick(view.focusProxy(), Qt::Key_Left);
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 11);
QCOMPARE(testContext.infos[0].anchorPosition, 11);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
@@ -1950,8 +2118,8 @@ void tst_QWebEngineView::inputContextQueryInput()
QInputMethodEvent event("", attributes);
QApplication::sendEvent(view.focusProxy(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 2);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 2);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
// As a first step, Chromium moves the cursor to the start of the selection.
// We don't filter this in QtWebEngine because we don't know yet if this is part of a selection.
@@ -1976,8 +2144,8 @@ void tst_QWebEngineView::inputContextQueryInput()
QInputMethodEvent event("", attributes);
QApplication::sendEvent(view.focusProxy(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 1);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 0);
QCOMPARE(testContext.infos[0].anchorPosition, 0);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
@@ -1991,9 +2159,9 @@ void tst_QWebEngineView::inputContextQueryInput()
QInputMethodEvent event("123", attributes);
QApplication::sendEvent(view.focusProxy(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 1);
- QCOMPARE(testContext.infos[0].cursorPosition, 3);
- QCOMPARE(testContext.infos[0].anchorPosition, 3);
+ QTRY_COMPARE(testContext.infos.size(), 1);
+ QCOMPARE(testContext.infos[0].cursorPosition, 0);
+ QCOMPARE(testContext.infos[0].anchorPosition, 0);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("QtWebEngine!"));
QCOMPARE(testContext.infos[0].selectedText, QStringLiteral(""));
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QStringLiteral("123QtWebEngine!"));
@@ -2005,7 +2173,7 @@ void tst_QWebEngineView::inputContextQueryInput()
QInputMethodEvent event("", attributes);
QApplication::sendEvent(view.focusProxy(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 2);
+ QTRY_COMPARE(testContext.infos.size(), 2);
foreach (const InputMethodInfo &info, testContext.infos) {
QCOMPARE(info.cursorPosition, 0);
QCOMPARE(info.anchorPosition, 0);
@@ -2022,7 +2190,7 @@ void tst_QWebEngineView::inputContextQueryInput()
event.setCommitString(QStringLiteral("123"), 0, 0);
QApplication::sendEvent(view.focusProxy(), &event);
}
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QCOMPARE(testContext.infos[0].cursorPosition, 3);
QCOMPARE(testContext.infos[0].anchorPosition, 3);
QCOMPARE(testContext.infos[0].surroundingText, QStringLiteral("123QtWebEngine!"));
@@ -2032,7 +2200,7 @@ void tst_QWebEngineView::inputContextQueryInput()
// Focus out.
QTest::keyPress(view.focusProxy(), Qt::Key_Tab);
- QTRY_COMPARE(testContext.infos.count(), 1);
+ QTRY_COMPARE(testContext.infos.size(), 1);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral(""));
testContext.infos.clear();
}
@@ -2076,7 +2244,7 @@ void tst_QWebEngineView::inputMethods()
QInputMethodEvent eventText(text, inputAttributes);
QApplication::sendEvent(view.focusProxy(), &eventText);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), text);
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
}
{
@@ -2085,7 +2253,7 @@ void tst_QWebEngineView::inputMethods()
eventText.setCommitString(text, 0, 0);
QApplication::sendEvent(view.focusProxy(), &eventText);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), text);
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
}
// ImMaximumTextLength
@@ -2161,24 +2329,24 @@ void tst_QWebEngineView::textSelectionInInputField()
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
// There was no selection to be changed by the click
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QString(), attributes);
event.setCommitString("XXX", 0, 0);
QApplication::sendEvent(view.focusProxy(), &event);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngineXXX"));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
event.setCommitString(QString(), -2, 2); // Erase two characters.
QApplication::sendEvent(view.focusProxy(), &event);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngineX"));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
event.setCommitString(QString(), -1, 1); // Erase one character.
QApplication::sendEvent(view.focusProxy(), &event);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// Move to the start of the line
QTest::keyClick(view.focusProxy(), Qt::Key_Home);
@@ -2190,7 +2358,7 @@ void tst_QWebEngineView::textSelectionInInputField()
// Select to the end of the line
QTest::keyClick(view.focusProxy(), Qt::Key_End, Qt::ShiftModifier);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 2);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
@@ -2200,7 +2368,7 @@ void tst_QWebEngineView::textSelectionInInputField()
// Deselect the selection (this moves the current cursor to the end of the text)
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
@@ -2213,7 +2381,7 @@ void tst_QWebEngineView::textSelectionInInputField()
// Select to the start of the line
QTest::keyClick(view.focusProxy(), Qt::Key_Home, Qt::ShiftModifier);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QCOMPARE(selectionChangedSpy.size(), 3);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 9);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
@@ -2235,34 +2403,31 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
QVERIFY(loadFinishedSpy.wait());
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
// Simple click should not update text selection, however it updates selection bounds in Chromium
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center());
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
// Select text by ctrl+a
QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier);
- QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QVERIFY(view.hasSelection());
QCOMPARE(view.page()->selectedText(), QString("This is a text"));
// Deselect text by mouse click
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center());
- QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QTRY_COMPARE(selectionChangedSpy.size(), 2);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
// Select text by ctrl+a
QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier);
- QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QTRY_COMPARE(selectionChangedSpy.size(), 3);
QVERIFY(view.hasSelection());
QCOMPARE(view.page()->selectedText(), QString("This is a text"));
@@ -2270,8 +2435,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
view.hide();
view.page()->setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
view.show();
- QVERIFY(loadFinishedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 4);
+ QTRY_COMPARE(selectionChangedSpy.size(), 4);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
@@ -2284,7 +2448,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
QVERIFY(loadFinishedSpy.wait());
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
@@ -2294,31 +2458,27 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
// Select the whole page by ctrl+a
QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier);
- QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QVERIFY(view.hasSelection());
QVERIFY(view.page()->selectedText().startsWith(QString("This is a text")));
// Remove selection by clicking into an input field
QPoint textInputCenter = elementCenter(view.page(), "input1");
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
- QVERIFY(selectionChangedSpy.wait());
+ QTRY_COMPARE(selectionChangedSpy.size(), 2);
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
- QCOMPARE(selectionChangedSpy.count(), 2);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
// Select the content of the input field by ctrl+a
QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier);
- QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QTRY_COMPARE(selectionChangedSpy.size(), 3);
QVERIFY(view.hasSelection());
QCOMPARE(view.page()->selectedText(), QString("QtWebEngine"));
// Deselect input field's text by mouse click
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center());
- QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 4);
+ QTRY_COMPARE(selectionChangedSpy.size(), 4);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
}
@@ -2365,7 +2525,7 @@ void tst_QWebEngineView::emptyInputMethodEvent()
QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
// 1. Empty input method event does not clear text
QInputMethodEvent emptyEvent;
@@ -2414,7 +2574,7 @@ void tst_QWebEngineView::imeComposition()
QVERIFY(QTest::qWaitForWindowExposed(&view));
evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
// Clear the selection, also cancel the ongoing composition if there is one.
{
@@ -2424,7 +2584,7 @@ void tst_QWebEngineView::imeComposition()
QInputMethodEvent event("", attributes);
QApplication::sendEvent(view.focusProxy(), &event);
selectionChangedSpy.wait();
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
}
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine inputMethod"));
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
@@ -2445,7 +2605,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// Send temporary text, which makes the editor has composition 'n'.
{
@@ -2457,7 +2617,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// Send commit text, which makes the editor conforms composition.
{
@@ -2470,7 +2630,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 1);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 1);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// 2. insert a character to the middle of the line.
@@ -2484,7 +2644,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 1);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 1);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// Send commit text, which makes the editor conforms composition.
{
@@ -2497,7 +2657,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 2);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 2);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// 3. Insert a character to the end of the line.
@@ -2515,7 +2675,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 25);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 25);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// Send commit text, which makes the editor conforms composition.
{
@@ -2528,7 +2688,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 26);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 26);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
// 4. Replace the selection.
@@ -2538,7 +2698,7 @@ void tst_QWebEngineView::imeComposition()
QTest::keyClick(view.focusProxy(), Qt::Key_Left, Qt::ShiftModifier | Qt::AltModifier);
#endif
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine inputMethodt"));
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 14);
@@ -2552,7 +2712,7 @@ void tst_QWebEngineView::imeComposition()
QApplication::sendEvent(view.focusProxy(), &event);
// The new composition should clear the previous selection
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
}
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine "));
// The cursor should be positioned at the end of the composition text
@@ -2572,7 +2732,7 @@ void tst_QWebEngineView::imeComposition()
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 15);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 15);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
selectionChangedSpy.clear();
@@ -2597,8 +2757,8 @@ void tst_QWebEngineView::imeComposition()
QApplication::sendEvent(view.focusProxy(), &event);
}
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString(""));
- QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
- QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("QtWebEngine"));
@@ -2614,7 +2774,7 @@ void tst_QWebEngineView::imeComposition()
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("QtWebEngine"));
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
}
void tst_QWebEngineView::newlineInTextarea()
@@ -2769,7 +2929,7 @@ void tst_QWebEngineView::imeJSInputEvents()
}
// Simply committing text should not trigger any JS composition event.
- QTRY_COMPARE(logLines().count(), 3);
+ QTRY_COMPARE(logLines().size(), 3);
QCOMPARE(logLines()[0], QStringLiteral("[object InputEvent] beforeinput commit"));
QCOMPARE(logLines()[1], QStringLiteral("[object TextEvent] textInput commit"));
QCOMPARE(logLines()[2], QStringLiteral("[object InputEvent] input commit"));
@@ -2785,7 +2945,7 @@ void tst_QWebEngineView::imeJSInputEvents()
qApp->processEvents();
}
- QTRY_COMPARE(logLines().count(), 4);
+ QTRY_COMPARE(logLines().size(), 4);
QCOMPARE(logLines()[0], QStringLiteral("[object CompositionEvent] compositionstart "));
QCOMPARE(logLines()[1], QStringLiteral("[object InputEvent] beforeinput preedit"));
QCOMPARE(logLines()[2], QStringLiteral("[object CompositionEvent] compositionupdate preedit"));
@@ -2799,7 +2959,7 @@ void tst_QWebEngineView::imeJSInputEvents()
qApp->processEvents();
}
- QTRY_COMPARE(logLines().count(), 9);
+ QTRY_COMPARE(logLines().size(), 9);
QCOMPARE(logLines()[4], QStringLiteral("[object InputEvent] beforeinput commit"));
QCOMPARE(logLines()[5], QStringLiteral("[object CompositionEvent] compositionupdate commit"));
QCOMPARE(logLines()[6], QStringLiteral("[object TextEvent] textInput commit"));
@@ -2817,7 +2977,7 @@ void tst_QWebEngineView::imeJSInputEvents()
qApp->processEvents();
}
- QTRY_COMPARE(logLines().count(), 4);
+ QTRY_COMPARE(logLines().size(), 4);
QCOMPARE(logLines()[0], QStringLiteral("[object CompositionEvent] compositionstart "));
QCOMPARE(logLines()[1], QStringLiteral("[object InputEvent] beforeinput preedit"));
QCOMPARE(logLines()[2], QStringLiteral("[object CompositionEvent] compositionupdate preedit"));
@@ -2830,7 +2990,7 @@ void tst_QWebEngineView::imeJSInputEvents()
qApp->processEvents();
}
- QTRY_COMPARE(logLines().count(), 9);
+ QTRY_COMPARE(logLines().size(), 9);
QCOMPARE(logLines()[4], QStringLiteral("[object InputEvent] beforeinput "));
QCOMPARE(logLines()[5], QStringLiteral("[object CompositionEvent] compositionupdate "));
QCOMPARE(logLines()[6], QStringLiteral("[object TextEvent] textInput "));
@@ -2897,6 +3057,7 @@ void tst_QWebEngineView::imeCompositionQueryEvent()
}
QInputMethodQueryEvent srrndTextQuery(Qt::ImSurroundingText);
+ QInputMethodQueryEvent absolutePosQuery(Qt::ImAbsolutePosition);
QInputMethodQueryEvent cursorPosQuery(Qt::ImCursorPosition);
QInputMethodQueryEvent anchorPosQuery(Qt::ImAnchorPosition);
@@ -2908,16 +3069,18 @@ void tst_QWebEngineView::imeCompositionQueryEvent()
qApp->processEvents();
}
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("composition"));
- QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
QApplication::sendEvent(input, &srrndTextQuery);
+ QApplication::sendEvent(input, &absolutePosQuery);
QApplication::sendEvent(input, &cursorPosQuery);
QApplication::sendEvent(input, &anchorPosQuery);
qApp->processEvents();
QTRY_COMPARE(srrndTextQuery.value(Qt::ImSurroundingText).toString(), QString(""));
- QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 11);
- QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 11);
+ QTRY_COMPARE(absolutePosQuery.value(Qt::ImAbsolutePosition).toInt(), 0);
+ QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 0);
+ QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 0);
// Send commit
{
@@ -2931,16 +3094,67 @@ void tst_QWebEngineView::imeCompositionQueryEvent()
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("composition"));
QApplication::sendEvent(input, &srrndTextQuery);
+ QApplication::sendEvent(input, &absolutePosQuery);
QApplication::sendEvent(input, &cursorPosQuery);
QApplication::sendEvent(input, &anchorPosQuery);
qApp->processEvents();
QTRY_COMPARE(srrndTextQuery.value(Qt::ImSurroundingText).toString(), QString("composition"));
+ QTRY_COMPARE(absolutePosQuery.value(Qt::ImAbsolutePosition).toInt(), 11);
QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 11);
QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 11);
+
+ // Test another composition to ensure that the cursor position is set correctly.
+ // In this case cursor will be at position 11 during input composition.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("123", attributes);
+ QApplication::sendEvent(input, &event);
+ qApp->processEvents();
+ }
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value")
+ .toString(),
+ QString("composition123"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
+
+ QApplication::sendEvent(input, &srrndTextQuery);
+ QApplication::sendEvent(input, &absolutePosQuery);
+ QApplication::sendEvent(input, &cursorPosQuery);
+ QApplication::sendEvent(input, &anchorPosQuery);
+ qApp->processEvents();
+
+ QTRY_COMPARE(srrndTextQuery.value(Qt::ImSurroundingText).toString(), QString("composition"));
+ QTRY_COMPARE(absolutePosQuery.value(Qt::ImAbsolutePosition).toInt(), 11);
+ QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 11);
+ QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 11);
+
+ // Send commit
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("123");
+ QApplication::sendEvent(input, &event);
+ qApp->processEvents();
+ }
+
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value")
+ .toString(),
+ QString("composition123"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 14);
+
+ QApplication::sendEvent(input, &srrndTextQuery);
+ QApplication::sendEvent(input, &absolutePosQuery);
+ QApplication::sendEvent(input, &cursorPosQuery);
+ QApplication::sendEvent(input, &anchorPosQuery);
+ qApp->processEvents();
+
+ QTRY_COMPARE(srrndTextQuery.value(Qt::ImSurroundingText).toString(), QString("composition123"));
+ QTRY_COMPARE(absolutePosQuery.value(Qt::ImAbsolutePosition).toInt(), 14);
+ QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 14);
+ QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 14);
}
-#ifndef QT_NO_CLIPBOARD
+#if QT_CONFIG(clipboard)
void tst_QWebEngineView::globalMouseSelection()
{
if (!QApplication::clipboard()->supportsSelection()) {
@@ -2962,20 +3176,20 @@ void tst_QWebEngineView::globalMouseSelection()
// Select text via JavaScript
evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QVERIFY(QApplication::clipboard()->text(QClipboard::Selection).isEmpty());
// Deselect the selection (this moves the current cursor to the end of the text)
QPoint textInputCenter = elementCenter(view.page(), "input1");
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 2);
+ QCOMPARE(selectionChangedSpy.size(), 2);
QVERIFY(QApplication::clipboard()->text(QClipboard::Selection).isEmpty());
// Select to the start of the line
QTest::keyClick(view.focusProxy(), Qt::Key_Home, Qt::ShiftModifier);
QVERIFY(selectionChangedSpy.wait());
- QCOMPARE(selectionChangedSpy.count(), 3);
+ QCOMPARE(selectionChangedSpy.size(), 3);
QCOMPARE(QApplication::clipboard()->text(QClipboard::Selection), QStringLiteral("QtWebEngine"));
}
#endif
@@ -3001,7 +3215,7 @@ void tst_QWebEngineView::noContextMenu()
QTest::mouseMove(wrapper.windowHandle(), QPoint(10,10));
QTest::mouseClick(wrapper.windowHandle(), Qt::RightButton);
- QTRY_COMPARE(wrapper.findChildren<QMenu *>().count(), 1);
+ QTRY_COMPARE(wrapper.findChildren<QMenu *>().size(), 1);
QVERIFY(view.findChildren<QMenu *>().isEmpty());
}
@@ -3041,7 +3255,7 @@ void tst_QWebEngineView::contextMenu()
view.load(QUrl("about:blank"));
view.resize(640, 480);
view.show();
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QVERIFY(view.findChildren<QMenu *>().isEmpty());
QTest::mouseMove(view.windowHandle(), QPoint(10,10));
@@ -3049,9 +3263,9 @@ void tst_QWebEngineView::contextMenu()
// verify for zero children will always succeed, so should be tested with at least minor timeout
if (childrenCount <= 0) {
- QVERIFY(!QTest::qWaitFor([&view] () { return view.findChildren<QMenu *>().count() > 0; }, 500));
+ QVERIFY(!QTest::qWaitFor([&view] () { return view.findChildren<QMenu *>().size() > 0; }, 500));
} else {
- QTRY_COMPARE(view.findChildren<QMenu *>().count(), childrenCount);
+ QTRY_COMPARE(view.findChildren<QMenu *>().size(), childrenCount);
if (isCustomMenu) {
QCOMPARE(view.findChildren<QMenu *>().first(), customMenu);
}
@@ -3117,46 +3331,50 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::addColumn<bool>("supported");
QTest::newRow("about") << QUrl("chrome://about") << false;
QTest::newRow("accessibility") << QUrl("chrome://accessibility") << true;
- QTest::newRow("appcache-internals") << QUrl("chrome://appcache-internals") << true;
+ QTest::newRow("app-service-internals") << QUrl("chrome://app-service-internals") << false;
+ QTest::newRow("app-settings") << QUrl("chrome://app-settings") << false;
QTest::newRow("apps") << QUrl("chrome://apps") << false;
+ QTest::newRow("attribution-internals") << QUrl("chrome://attribution-internals") << true;
QTest::newRow("autofill-internals") << QUrl("chrome://autofill-internals") << false;
QTest::newRow("blob-internals") << QUrl("chrome://blob-internals") << true;
QTest::newRow("bluetooth-internals") << QUrl("chrome://bluetooth-internals") << false;
QTest::newRow("bookmarks") << QUrl("chrome://bookmarks") << false;
QTest::newRow("chrome-urls") << QUrl("chrome://chrome-urls") << false;
QTest::newRow("components") << QUrl("chrome://components") << false;
- QTest::newRow("conversion-internals") << QUrl("chrome://conversion-internals") << true;
+ QTest::newRow("connectors-internals") << QUrl("chrome://connectors-internals") << false;
QTest::newRow("crashes") << QUrl("chrome://crashes") << false;
QTest::newRow("credits") << QUrl("chrome://credits") << false;
QTest::newRow("device-log") << QUrl("chrome://device-log") << true;
- QTest::newRow("devices") << QUrl("chrome://devices") << false;
QTest::newRow("dino") << QUrl("chrome://dino") << false; // It works but this is an error page
QTest::newRow("discards") << QUrl("chrome://discards") << false;
QTest::newRow("download-internals") << QUrl("chrome://download-internals") << false;
QTest::newRow("downloads") << QUrl("chrome://downloads") << false;
QTest::newRow("extensions") << QUrl("chrome://extensions") << false;
+ QTest::newRow("extensions-internals") << QUrl("chrome://extensions-internals") << false;
QTest::newRow("flags") << QUrl("chrome://flags") << false;
QTest::newRow("gcm-internals") << QUrl("chrome://gcm-internals") << false;
QTest::newRow("gpu") << QUrl("chrome://gpu") << true;
QTest::newRow("help") << QUrl("chrome://help") << false;
QTest::newRow("histograms") << QUrl("chrome://histograms") << true;
QTest::newRow("history") << QUrl("chrome://history") << false;
+ QTest::newRow("history-clusters-internals") << QUrl("chrome://history-clusters-internals") << false;
QTest::newRow("indexeddb-internals") << QUrl("chrome://indexeddb-internals") << true;
QTest::newRow("inspect") << QUrl("chrome://inspect") << false;
QTest::newRow("interstitials") << QUrl("chrome://interstitials") << false;
- QTest::newRow("interventions-internals") << QUrl("chrome://interventions-internals") << false;
QTest::newRow("invalidations") << QUrl("chrome://invalidations") << false;
QTest::newRow("linux-proxy-config") << QUrl("chrome://linux-proxy-config") << false;
QTest::newRow("local-state") << QUrl("chrome://local-state") << false;
QTest::newRow("management") << QUrl("chrome://management") << false;
QTest::newRow("media-engagement") << QUrl("chrome://media-engagement") << false;
QTest::newRow("media-internals") << QUrl("chrome://media-internals") << true;
+ QTest::newRow("nacl") << QUrl("chrome://nacl") << false;
QTest::newRow("net-export") << QUrl("chrome://net-export") << false;
QTest::newRow("net-internals") << QUrl("chrome://net-internals") << true;
QTest::newRow("network-error") << QUrl("chrome://network-error") << false;
QTest::newRow("network-errors") << QUrl("chrome://network-errors") << true;
QTest::newRow("ntp-tiles-internals") << QUrl("chrome://ntp-tiles-internals") << false;
QTest::newRow("omnibox") << QUrl("chrome://omnibox") << false;
+ QTest::newRow("optimization-guide-internals") << QUrl("chrome://optimization-guide-internals") << false;
QTest::newRow("password-manager-internals") << QUrl("chrome://password-manager-internals") << false;
QTest::newRow("policy") << QUrl("chrome://policy") << false;
QTest::newRow("predictors") << QUrl("chrome://predictors") << false;
@@ -3165,7 +3383,7 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("process-internals") << QUrl("chrome://process-internals") << true;
QTest::newRow("quota-internals") << QUrl("chrome://quota-internals") << true;
QTest::newRow("safe-browsing") << QUrl("chrome://safe-browsing") << false;
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
QTest::newRow("sandbox") << QUrl("chrome://sandbox") << true;
#else
QTest::newRow("sandbox") << QUrl("chrome://sandbox") << false;
@@ -3174,8 +3392,6 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("settings") << QUrl("chrome://settings") << false;
QTest::newRow("signin-internals") << QUrl("chrome://signin-internals") << false;
QTest::newRow("site-engagement") << QUrl("chrome://site-engagement") << false;
- QTest::newRow("suggestions") << QUrl("chrome://suggestions") << false;
- QTest::newRow("supervised-user-internals") << QUrl("chrome://supervised-user-internals") << false;
QTest::newRow("sync-internals") << QUrl("chrome://sync-internals") << false;
QTest::newRow("system") << QUrl("chrome://system") << false;
QTest::newRow("terms") << QUrl("chrome://terms") << false;
@@ -3185,12 +3401,14 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("usb-internals") << QUrl("chrome://usb-internals") << false;
QTest::newRow("user-actions") << QUrl("chrome://user-actions") << true;
QTest::newRow("version") << QUrl("chrome://version") << false;
+ QTest::newRow("web-app-internals") << QUrl("chrome://web-app-internals") << false;
#if QT_CONFIG(webengine_webrtc)
QTest::newRow("webrtc-internals") << QUrl("chrome://webrtc-internals") << true;
#if QT_CONFIG(webengine_extensions)
QTest::newRow("webrtc-logs") << QUrl("chrome://webrtc-logs") << true;
#endif // QT_CONFIG(webengine_extensions)
#endif // QT_CONFIG(webengine_webrtc)
+ QTest::newRow("whats-new") << QUrl("chrome://whats-new") << false;
}
void tst_QWebEngineView::webUIURLs()
@@ -3202,7 +3420,7 @@ void tst_QWebEngineView::webUIURLs()
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 90000);
QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), supported);
}
@@ -3211,7 +3429,7 @@ void tst_QWebEngineView::visibilityState()
QWebEngineView view;
QSignalSpy spy(&view, &QWebEngineView::loadFinished);
view.load(QStringLiteral("about:blank"));
- QVERIFY(spy.count() || spy.wait());
+ QVERIFY(spy.size() || spy.wait());
QVERIFY(spy.takeFirst().takeFirst().toBool());
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.visibilityState").toString(), QStringLiteral("hidden"));
view.show();
@@ -3226,7 +3444,7 @@ void tst_QWebEngineView::visibilityState2()
view.show();
view.load(QStringLiteral("about:blank"));
view.hide();
- QVERIFY(spy.count() || spy.wait());
+ QVERIFY(spy.size() || spy.wait());
QVERIFY(spy.takeFirst().takeFirst().toBool());
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.visibilityState").toString(), QStringLiteral("hidden"));
}
@@ -3239,8 +3457,8 @@ void tst_QWebEngineView::visibilityState3()
QSignalSpy spy2(&page2, &QWebEnginePage::loadFinished);
page1.load(QStringLiteral("about:blank"));
page2.load(QStringLiteral("about:blank"));
- QVERIFY(spy1.count() || spy1.wait());
- QVERIFY(spy2.count() || spy2.wait());
+ QVERIFY(spy1.size() || spy1.wait());
+ QVERIFY(spy2.size() || spy2.wait());
QWebEngineView view;
view.setPage(&page1);
view.show();
@@ -3304,7 +3522,7 @@ void tst_QWebEngineView::deletePage()
QVERIFY(view.page());
QSignalSpy spy(view.page(), &QWebEnginePage::loadFinished);
view.page()->load(QStringLiteral("about:blank"));
- QTRY_VERIFY(spy.count());
+ QTRY_VERIFY(spy.size());
}
void tst_QWebEngineView::autoDeleteOnExternalPageDelete()
@@ -3318,7 +3536,7 @@ void tst_QWebEngineView::autoDeleteOnExternalPageDelete()
view->show();
view->resize(320, 240);
page->load(QUrl("about:blank"));
- QTRY_VERIFY(spy.count());
+ QTRY_VERIFY(spy.size());
QVERIFY(page->parent() != view);
auto sc = QObject::connect(page, &QWebEnginePage::destroyed, view, &QWebEngineView::deleteLater);
@@ -3351,7 +3569,7 @@ void tst_QWebEngineView::closeOpenerTab()
testView->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
QSignalSpy loadFinishedSpy(testView, SIGNAL(loadFinished(bool)));
testView->setUrl(QStringLiteral("about:blank"));
- QTRY_VERIFY(loadFinishedSpy.count());
+ QTRY_VERIFY(loadFinishedSpy.size());
testView->page()->runJavaScript(QStringLiteral("window.open('about:blank','_blank')"));
QTRY_COMPARE(testView->createdWindows.size(), 1);
auto *newView = testView->createdWindows.at(0);
@@ -3372,13 +3590,11 @@ void tst_QWebEngineView::switchPage()
QSignalSpy loadFinishedSpy2(&page2, SIGNAL(loadFinished(bool)));
// TODO fixme: page without the view has no real widget behind, so
// reading graphical content will fail, add view for now.
- QWebEngineView webView1;
- QWebEngineView webView2;
- webView1.setPage(&page1);
- webView2.setPage(&page2);
+ QWebEngineView webView1(&page1, nullptr);
+ QWebEngineView webView2(&page2, nullptr);
page1.setHtml("<html><body bgcolor=\"#000000\"></body></html>");
page2.setHtml("<html><body bgcolor=\"#ffffff\"></body></html>");
- QTRY_VERIFY(loadFinishedSpy1.count() && loadFinishedSpy2.count());
+ QTRY_VERIFY(loadFinishedSpy1.size() && loadFinishedSpy2.size());
QWebEngineView webView;
webView.resize(300,300);
webView.show();
@@ -3449,17 +3665,15 @@ void tst_QWebEngineView::setViewPreservesExplicitPage()
void tst_QWebEngineView::closeDiscardsPage()
{
QWebEngineProfile profile;
- QWebEnginePage page(&profile);
- QWebEngineView view;
- view.setPage(&page);
+ QWebEngineView view(&profile, nullptr);
view.resize(300, 300);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QCOMPARE(page.isVisible(), true);
- QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(view.page()->isVisible(), true);
+ QCOMPARE(view.page()->lifecycleState(), QWebEnginePage::LifecycleState::Active);
view.close();
- QCOMPARE(page.isVisible(), false);
- QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(view.page()->isVisible(), false);
+ QCOMPARE(view.page()->lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
}
@@ -3477,9 +3691,317 @@ void tst_QWebEngineView::loadAfterRendererCrashed()
QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
view.load(QUrl("qrc:///resources/dummy.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QVERIFY(loadSpy.first().first().toBool());
}
+void tst_QWebEngineView::inspectElement()
+{
+ QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ auto page = view.page();
+ // shouldn't do anything until page is set
+ page->triggerAction(QWebEnginePage::InspectElement);
+ QTest::qWait(100);
+
+ QSignalSpy spy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("data:text/plain,foobarbaz"));
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 12000);
+
+ // shouldn't do anything since inspector is not attached
+ page->triggerAction(QWebEnginePage::InspectElement);
+ QTest::qWait(100);
+
+ QWebEngineView inspectorView;
+ inspectorView.resize(640, 480);
+ inspectorView.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&inspectorView));
+ inspectorView.page()->setInspectedPage(page);
+
+ page->triggerAction(QWebEnginePage::InspectElement);
+ // TODO verify somehow
+ QTest::qWait(100);
+}
+
+void tst_QWebEngineView::navigateOnDrop_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<bool>("navigateOnDrop");
+ QTest::newRow("file") << QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).absoluteFilePath("resources/dummy.html")) << true;
+ QTest::newRow("qrc") << QUrl("qrc:///resources/dummy.html") << true;
+ QTest::newRow("file_no_navigate") << QUrl::fromLocalFile(QDir(QT_TESTCASE_SOURCEDIR).absoluteFilePath("resources/dummy.html")) << false;
+ QTest::newRow("qrc_no_navigate") << QUrl("qrc:///resources/dummy.html") << false;
+}
+
+void tst_QWebEngineView::navigateOnDrop()
+{
+ QFETCH(QUrl, url);
+ QFETCH(bool, navigateOnDrop);
+ struct WebEngineView : QWebEngineView {
+ QWebEngineView* createWindow(QWebEnginePage::WebWindowType /* type */) override { return this; }
+ } view;
+ view.page()->settings()->setAttribute(QWebEngineSettings::NavigateOnDropEnabled, navigateOnDrop);
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ QMimeData mimeData;
+ mimeData.setUrls({ url });
+
+ auto sendEvents = [&] () {
+ QDragEnterEvent dee(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(&view, &dee);
+ QDropEvent de(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(&view, &de);
+ };
+
+ sendEvents();
+ if (navigateOnDrop) {
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QVERIFY(loadSpy.last().first().toBool());
+ QCOMPARE(view.url(), url);
+ } else {
+ QTest::qWait(500);
+ QCOMPARE(loadSpy.size(), 0);
+ QVERIFY(view.url() != url);
+ }
+
+ // Check dynamically changing the setting
+ loadSpy.clear();
+ view.page()->settings()->setAttribute(QWebEngineSettings::NavigateOnDropEnabled, !navigateOnDrop);
+ view.setUrl(QUrl("about:blank"));
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ sendEvents();
+ if (!navigateOnDrop) {
+ QTRY_COMPARE(loadSpy.size(), 2);
+ QVERIFY(loadSpy.last().first().toBool());
+ QCOMPARE(view.url(), url);
+ } else {
+ QTest::qWait(500);
+ QCOMPARE(loadSpy.size(), 1);
+ QVERIFY(view.url() != url);
+ }
+}
+
+void tst_QWebEngineView::emptyUriListOnDrop()
+{
+ QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QMimeData mimeData;
+ mimeData.setUrls({}); // creates an empty uri-list MIME type entry
+ QVERIFY(mimeData.hasUrls());
+
+ QDragEnterEvent dee(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton,
+ Qt::NoModifier);
+ QApplication::sendEvent(&view, &dee);
+ QDropEvent de(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(&view, &de);
+
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ view.setUrl(QUrl("about:blank"));
+ QTRY_COMPARE(loadSpy.size(), 1);
+}
+
+void tst_QWebEngineView::datalist()
+{
+ QString html("<html><body>"
+ "<input id='browserInput' list='browserDatalist'>"
+ "<datalist id='browserDatalist'>"
+ " <option value='Internet Explorer'>"
+ " <option value='Firefox'>"
+ " <option value='Chrome'>"
+ " <option value='Opera'>"
+ " <option value='Safari'>"
+ "</datalist>"
+ "</body></html>");
+
+ QWebEngineView view;
+ view.resize(200, 400);
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ view.setHtml(html);
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ QString listValuesJS("(function() {"
+ " var browserDatalist = document.getElementById('browserDatalist');"
+ " var options = browserDatalist.options;"
+ " var result = [];"
+ " for (let i = 0; i < options.length; ++i) {"
+ " result.push(options[i].value);"
+ " }"
+ " return result;"
+ "})();");
+ QStringList values = evaluateJavaScriptSync(view.page(), listValuesJS).toStringList();
+ QCOMPARE(values, QStringList({ "Internet Explorer", "Firefox", "Chrome", "Opera", "Safari" }));
+ QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('browserInput').value;")
+ .toString(),
+ QStringLiteral(""));
+
+ auto listView = [&view]() -> QListView * {
+ if (QApplication::topLevelWidgets().size() == 1) {
+ // No popup case.
+ return nullptr;
+ }
+
+ QWidget *autofillPopupWidget = nullptr;
+ for (QWidget *w : QApplication::topLevelWidgets()) {
+ if (w != &view) {
+ autofillPopupWidget = w;
+ break;
+ }
+ }
+
+ if (!autofillPopupWidget)
+ return nullptr;
+
+ for (QObject *o : autofillPopupWidget->children()) {
+ if (QListView *listView = qobject_cast<QListView *>(o))
+ return listView;
+ }
+
+ return nullptr;
+ };
+
+ // Make sure there is no open popup yet.
+ QVERIFY(!listView());
+ // Click in the input field.
+ QPoint browserInputCenter = elementCenter(view.page(), "browserInput");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, browserInputCenter);
+ // Wait for the popup.
+ QTRY_VERIFY(listView());
+
+ // No suggestion is selected.
+ QCOMPARE(listView()->currentIndex(), QModelIndex());
+ QCOMPARE(listView()->model()->rowCount(), 5);
+
+ // Accepting suggestion does nothing.
+ QTest::keyClick(view.windowHandle(), Qt::Key_Enter);
+ QVERIFY(listView());
+ QCOMPARE(listView()->currentIndex(), QModelIndex());
+
+ // Escape should close popup.
+ QTest::keyClick(view.windowHandle(), Qt::Key_Escape);
+ QTRY_VERIFY(!listView());
+
+ // Key Down should open the popup and select the first suggestion.
+ QTest::keyClick(view.windowHandle(), Qt::Key_Down);
+ QTRY_VERIFY(listView());
+ QCOMPARE(listView()->currentIndex().row(), 0);
+
+ // Test keyboard navigation in list.
+ QTest::keyClick(view.windowHandle(), Qt::Key_Up);
+ QCOMPARE(listView()->currentIndex().row(), 4);
+ QTest::keyClick(view.windowHandle(), Qt::Key_Up);
+ QCOMPARE(listView()->currentIndex().row(), 3);
+ QTest::keyClick(view.windowHandle(), Qt::Key_PageDown);
+ QCOMPARE(listView()->currentIndex().row(), 4);
+ QTest::keyClick(view.windowHandle(), Qt::Key_PageUp);
+ QCOMPARE(listView()->currentIndex().row(), 0);
+ QTest::keyClick(view.windowHandle(), Qt::Key_Down);
+ QCOMPARE(listView()->currentIndex().row(), 1);
+ QTest::keyClick(view.windowHandle(), Qt::Key_Down);
+ QCOMPARE(listView()->currentIndex().row(), 2);
+
+ // Test accepting suggestion.
+ QCOMPARE(static_cast<QStringListModel *>(listView()->model())
+ ->data(listView()->currentIndex())
+ .toString(),
+ QStringLiteral("Chrome"));
+ QTest::keyClick(view.windowHandle(), Qt::Key_Enter);
+ QTRY_COMPARE(
+ evaluateJavaScriptSync(view.page(), "document.getElementById('browserInput').value")
+ .toString(),
+ QStringLiteral("Chrome"));
+ // Accept closes popup.
+ QTRY_VERIFY(!listView());
+
+ // Clear input field, should not trigger popup.
+ evaluateJavaScriptSync(view.page(), "document.getElementById('browserInput').value = ''");
+ QVERIFY(!listView());
+
+ // Filter suggestions.
+ QTest::keyClick(view.windowHandle(), Qt::Key_F);
+ QTRY_VERIFY(listView());
+ QCOMPARE(listView()->model()->rowCount(), 2);
+ QCOMPARE(listView()->currentIndex(), QModelIndex());
+ QCOMPARE(static_cast<QStringListModel *>(listView()->model())
+ ->data(listView()->model()->index(0, 0))
+ .toString(),
+ QStringLiteral("Firefox"));
+ QCOMPARE(static_cast<QStringListModel *>(listView()->model())
+ ->data(listView()->model()->index(1, 0))
+ .toString(),
+ QStringLiteral("Safari"));
+ QTest::keyClick(view.windowHandle(), Qt::Key_I);
+ QTRY_COMPARE(listView()->model()->rowCount(), 1);
+ QCOMPARE(listView()->currentIndex(), QModelIndex());
+ QCOMPARE(static_cast<QStringListModel *>(listView()->model())
+ ->data(listView()->model()->index(0, 0))
+ .toString(),
+ QStringLiteral("Firefox"));
+ QTest::keyClick(view.windowHandle(), Qt::Key_L);
+ // Mismatch should close popup.
+ QTRY_VERIFY(!listView());
+ QTRY_COMPARE(
+ evaluateJavaScriptSync(view.page(), "document.getElementById('browserInput').value")
+ .toString(),
+ QStringLiteral("fil"));
+}
+
+class ConsolePage : public QWebEnginePage
+{
+ Q_OBJECT
+public:
+ ConsolePage(QObject *parent = nullptr) : QWebEnginePage(parent) { }
+ void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message,
+ int lineNumber, const QString &sourceID) override
+ {
+ Q_UNUSED(level)
+ Q_UNUSED(lineNumber)
+ Q_UNUSED(sourceID)
+ if (message.contains("TEST_KEY:Shift"))
+ emit done();
+ }
+signals:
+ void done();
+};
+
+//qtbug_113704
+void tst_QWebEngineView::longKeyEventText()
+{
+ const QString html(QStringLiteral("<html><body><p>TEST</p>"
+ "<script>"
+ "document.addEventListener('keydown', (event)=> {"
+ "console.log('TEST_KEY:' + event.key);"
+ "});"
+ "</script>"
+ "</body></html>"));
+
+ QWebEngineView view;
+ ConsolePage page;
+ view.setPage(&page);
+ QSignalSpy loadFinishedSpy(view.page(), &QWebEnginePage::loadFinished);
+ view.resize(200, 400);
+ view.show();
+ view.setHtml(html);
+ QTRY_VERIFY(loadFinishedSpy.size());
+ QSignalSpy consoleMessageSpy(&page, &ConsolePage::done);
+ Qt::Key key(Qt::Key_Shift);
+ QKeyEvent event(QKeyEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString());
+ QApplication::sendEvent(view.focusProxy(), &event);
+ QTRY_VERIFY(consoleMessageSpy.size());
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/schemes/CMakeLists.txt b/tests/auto/widgets/schemes/CMakeLists.txt
index 446ae5751..5299b3148 100644
--- a/tests/auto/widgets/schemes/CMakeLists.txt
+++ b/tests/auto/widgets/schemes/CMakeLists.txt
@@ -1,7 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../util/util.cmake)
+
qt_internal_add_test(tst_schemes
SOURCES
tst_schemes.cpp
LIBRARIES
Qt::WebEngineWidgets
+ Test::Util
)
diff --git a/tests/auto/widgets/schemes/tst_schemes.cpp b/tests/auto/widgets/schemes/tst_schemes.cpp
index a4a0e34ff..188c112e4 100644
--- a/tests/auto/widgets/schemes/tst_schemes.cpp
+++ b/tests/auto/widgets/schemes/tst_schemes.cpp
@@ -1,47 +1,50 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTest>
-#include <qwebengineview.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
#include <qwebenginesettings.h>
+#include <qwebengineurlrequestjob.h>
+#include <qwebengineurlscheme.h>
+#include <qwebengineurlschemehandler.h>
+#include <qwebengineview.h>
+#include <widgetutil.h>
class tst_Schemes : public QObject
{
Q_OBJECT
private Q_SLOTS:
+ void initTestCase();
void unknownUrlSchemePolicy_data();
void unknownUrlSchemePolicy();
+ void customSchemeFragmentNavigation_data();
+ void customSchemeFragmentNavigation();
};
+void tst_Schemes::initTestCase()
+{
+ QWebEngineUrlScheme pathScheme("path");
+ pathScheme.setSyntax(QWebEngineUrlScheme::Syntax::Path);
+ QWebEngineUrlScheme::registerScheme(pathScheme);
+
+ QWebEngineUrlScheme hostScheme("host");
+ hostScheme.setSyntax(QWebEngineUrlScheme::Syntax::Host);
+ QWebEngineUrlScheme::registerScheme(hostScheme);
+
+ QWebEngineUrlScheme hostAndPortScheme("hostandport");
+ hostAndPortScheme.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort);
+ hostAndPortScheme.setDefaultPort(3000);
+ QWebEngineUrlScheme::registerScheme(hostAndPortScheme);
+
+ QWebEngineUrlScheme hostPortUserInfoScheme("hostportuserinfo");
+ hostPortUserInfoScheme.setSyntax(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation);
+ hostPortUserInfoScheme.setDefaultPort(3000);
+ QWebEngineUrlScheme::registerScheme(hostPortUserInfoScheme);
+}
+
class AcceptNavigationRequestHandler : public QWebEnginePage
{
public:
@@ -118,5 +121,161 @@ void tst_Schemes::unknownUrlSchemePolicy()
QCOMPARE(page.acceptNavigationRequestCalls, shouldAccept ? 1 : 0);
}
+class CustomScheme : public QWebEngineUrlSchemeHandler
+{
+public:
+ CustomScheme(const QString &linkUrl) : m_linkUrl(linkUrl) { }
+
+ void requestStarted(QWebEngineUrlRequestJob *requestJob) override
+ {
+ QString html = QString("<html><body>"
+ "<p style='height: 2000px;'>"
+ "<a href='%1' id='link'>Click link</a>"
+ "</p><p id='anchor'>Anchor</p>"
+ "</body></html>")
+ .arg(m_linkUrl);
+ QBuffer *buffer = new QBuffer(requestJob);
+ buffer->setData(html.toUtf8());
+ requestJob->reply("text/html", buffer);
+ }
+
+ QString m_linkUrl;
+};
+
+void tst_Schemes::customSchemeFragmentNavigation_data()
+{
+ QTest::addColumn<QUrl>("baseUrl");
+ QTest::addColumn<QString>("linkUrl");
+ QTest::addColumn<QUrl>("expectedUrl");
+
+ // Path syntax
+ // - Preserves each part of the URL after navigation
+ QTest::newRow("Path syntax, path only, relative url")
+ << QUrl("path://path") << "#anchor" << QUrl("path://path#anchor");
+ QTest::newRow("Path syntax, path only, absolute url")
+ << QUrl("path://path") << "path://path#anchor" << QUrl("path://path#anchor");
+ QTest::newRow("Path syntax, host/path, relative url")
+ << QUrl("path://host/path") << "#anchor" << QUrl("path://host/path#anchor");
+ QTest::newRow("Path syntax, host/path, absolute url")
+ << QUrl("path://host/path") << "path://host/path#anchor"
+ << QUrl("path://host/path#anchor");
+ QTest::newRow("Path syntax, host:port, relative url")
+ << QUrl("path://host:3000") << "#anchor" << QUrl("path://host:3000#anchor");
+ QTest::newRow("Path syntax, host:port, absolute url")
+ << QUrl("path://host:3000") << "path://host:3000#anchor"
+ << QUrl("path://host:3000#anchor");
+ QTest::newRow("Path syntax, userinfo@host:port, relative url")
+ << QUrl("path://user:password@host:3000") << "#anchor"
+ << QUrl("path://user:password@host:3000#anchor");
+ QTest::newRow("Path syntax, userinfo@host:port, absolute url")
+ << QUrl("path://user:password@host:3000") << "path://user:password@host:3000#anchor"
+ << QUrl("path://user:password@host:3000#anchor");
+
+ // Host syntax
+ // - We lose the port and the user info from the authority after navigation
+ QTest::newRow("Host syntax, host only, relative url")
+ << QUrl("host://host") << "#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, host only, absolute url")
+ << QUrl("host://host") << "host://host#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, host/path, relative url")
+ << QUrl("host://host/path") << "#anchor" << QUrl("host://host/path#anchor");
+ QTest::newRow("Host syntax, host/path, absolute url")
+ << QUrl("host://host/path") << "host://host/path#anchor"
+ << QUrl("host://host/path#anchor");
+ QTest::newRow("Host syntax, host:port, relative url")
+ << QUrl("host://host:3000") << "#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, host:port, absolute url")
+ << QUrl("host://host:3000") << "host://host:3000#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, userinfo@host:port, relative url")
+ << QUrl("host://user:password@host:3000") << "#anchor" << QUrl("host://host/#anchor");
+ QTest::newRow("Host syntax, userinfo@host:port, absolute url")
+ << QUrl("host://user:password@host:3000") << "host://user:password@host:3000#anchor"
+ << QUrl("host://host/#anchor");
+
+ // HostAndPort syntax
+ // - We lose the port and the user info from the authority after navigation
+ QTest::newRow("HostAndPort syntax, host only, relative url")
+ << QUrl("hostandport://host") << "#anchor" << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, host only, absolute url")
+ << QUrl("hostandport://host") << "hostandport://host#anchor"
+ << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, host/path, relative url")
+ << QUrl("hostandport://host/path") << "#anchor"
+ << QUrl("hostandport://host/path#anchor");
+ QTest::newRow("HostAndPort syntax, host/path, absolute url")
+ << QUrl("hostandport://host/path") << "hostandport://host/path#anchor"
+ << QUrl("hostandport://host/path#anchor");
+ QTest::newRow("HostAndPort syntax, host:port, relative url")
+ << QUrl("hostandport://host:3000") << "#anchor" << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, host:port, absolute url")
+ << QUrl("hostandport://host:3000") << "hostandport://host:3000#anchor"
+ << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, userinfo@host:port, relative url")
+ << QUrl("hostandport://user:password@host:3000") << "#anchor"
+ << QUrl("hostandport://host/#anchor");
+ QTest::newRow("HostAndPort syntax, userinfo@host:port, absolute url")
+ << QUrl("hostandport://user:password@host:3000")
+ << "hostandport://user:password@host:3000#anchor" << QUrl("hostandport://host/#anchor");
+
+ // HostPortAndUserInformation syntax
+ // - We lose the port and it preserves the user info in the authority after navigation
+ QTest::newRow("HostPortAndUserInformation syntax, host only, relative url")
+ << QUrl("hostportuserinfo://host") << "#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host only, absolute url")
+ << QUrl("hostportuserinfo://host") << "hostportuserinfo://host#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host/path, relative url")
+ << QUrl("hostportuserinfo://host/path") << "#anchor"
+ << QUrl("hostportuserinfo://host/path#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host/path, absolute url")
+ << QUrl("hostportuserinfo://host/path") << "hostportuserinfo://host/path#anchor"
+ << QUrl("hostportuserinfo://host/path#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host:port, relative url")
+ << QUrl("hostportuserinfo://host:3000") << "#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, host:port, absolute url")
+ << QUrl("hostportuserinfo://host:3000") << "hostportuserinfo://host:3000#anchor"
+ << QUrl("hostportuserinfo://host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, userinfo@host:port, relative url")
+ << QUrl("hostportuserinfo://user:password@host:3000") << "#anchor"
+ << QUrl("hostportuserinfo://user:password@host/#anchor");
+ QTest::newRow("HostPortAndUserInformation syntax, userinfo@host:port, absolute url")
+ << QUrl("hostportuserinfo://user:password@host:3000")
+ << "hostportuserinfo://user:password@host:3000#anchor"
+ << QUrl("hostportuserinfo://user:password@host/#anchor");
+}
+
+void tst_Schemes::customSchemeFragmentNavigation()
+{
+ QFETCH(QUrl, baseUrl);
+ QFETCH(QUrl, expectedUrl);
+ QFETCH(QString, linkUrl);
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QWebEngineView view;
+ view.setPage(&page);
+ view.resize(800, 600);
+ view.show();
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy urlChangedSpy(&page, SIGNAL(urlChanged(QUrl)));
+
+ CustomScheme *schemeHandler = new CustomScheme(linkUrl);
+ page.profile()->installUrlSchemeHandler(baseUrl.scheme().toUtf8(), schemeHandler);
+
+ view.load(baseUrl);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.scrollY").toInt() == 0);
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QVERIFY(urlChangedSpy.wait());
+ QCOMPARE(page.url(), expectedUrl);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.scrollY").toInt() > 0);
+
+ // Same document navigation doesn't emit loadFinished
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+}
+
QTEST_MAIN(tst_Schemes)
#include "tst_schemes.moc"
diff --git a/tests/auto/widgets/shutdown/CMakeLists.txt b/tests/auto/widgets/shutdown/CMakeLists.txt
index 12ca27c3d..e2ce9eeb9 100644
--- a/tests/auto/widgets/shutdown/CMakeLists.txt
+++ b/tests/auto/widgets/shutdown/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_shutdown
SOURCES
tst_shutdown.cpp
diff --git a/tests/auto/widgets/shutdown/tst_shutdown.cpp b/tests/auto/widgets/shutdown/tst_shutdown.cpp
index 5c1e426d2..c2b31bb80 100644
--- a/tests/auto/widgets/shutdown/tst_shutdown.cpp
+++ b/tests/auto/widgets/shutdown/tst_shutdown.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtTest/QtTest>
diff --git a/tests/auto/widgets/spellchecking/CMakeLists.txt b/tests/auto/widgets/spellchecking/CMakeLists.txt
index 2c1926476..d0c7656c1 100644
--- a/tests/auto/widgets/spellchecking/CMakeLists.txt
+++ b/tests/auto/widgets/spellchecking/CMakeLists.txt
@@ -1,4 +1,8 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
+include(../../../../src/core/api/Qt6WebEngineCoreMacros.cmake)
qt_internal_add_test(tst_spellchecking
SOURCES
diff --git a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
index 7263904ce..c643a56ba 100644
--- a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
+++ b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <util.h>
#include <QtTest/QtTest>
@@ -170,19 +145,20 @@ void tst_Spellchecking::spellcheck()
QVariantList list = evaluateJavaScriptSync(m_view->page(), "findWordPosition('I lowe Qt ....','lowe');").toList();
QRect rect(list[0].value<int>(),list[1].value<int>(),list[2].value<int>(),list[3].value<int>());
+ QTRY_VERIFY(m_view->focusWidget());
//type text, spellchecker needs time
QTest::mouseMove(m_view->focusWidget(), QPoint(20,20));
QTest::mousePress(m_view->focusWidget(), Qt::LeftButton, {}, QPoint(20,20));
QTest::mouseRelease(m_view->focusWidget(), Qt::LeftButton, {}, QPoint(20,20));
QString text("I lowe Qt ....");
- for (int i = 0; i < text.length(); i++) {
+ for (int i = 0; i < text.size(); i++) {
QTest::keyClicks(m_view->focusWidget(), text.at(i));
QTest::qWait(60);
}
// make sure text is there
QString result = evaluateJavaScriptSync(m_view->page(), "text();").toString();
- QVERIFY(result == text);
+ QCOMPARE(result, text);
bool gotMisspelledWord = false; // clumsy QTRY_VERIFY still execs expr after first success
QString detail;
diff --git a/tests/auto/widgets/touchinput/CMakeLists.txt b/tests/auto/widgets/touchinput/CMakeLists.txt
index 82e3fca4a..bd76666d6 100644
--- a/tests/auto/widgets/touchinput/CMakeLists.txt
+++ b/tests/auto/widgets/touchinput/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(../../util/util.cmake)
qt_internal_add_test(tst_touchinput
diff --git a/tests/auto/widgets/touchinput/tst_touchinput.cpp b/tests/auto/widgets/touchinput/tst_touchinput.cpp
index d60fd1d7b..42178558c 100644
--- a/tests/auto/widgets/touchinput/tst_touchinput.cpp
+++ b/tests/auto/widgets/touchinput/tst_touchinput.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <util.h>
@@ -37,6 +12,12 @@
static QPointingDevice* s_touchDevice = nullptr;
+struct Page : QWebEnginePage
+{
+ QStringList alerts;
+ void javaScriptAlert(const QUrl &/*origin*/, const QString &msg) override { alerts.append(msg); }
+};
+
class TouchInputTest : public QObject
{
Q_OBJECT
@@ -54,29 +35,38 @@ private Q_SLOTS:
void pinchZoom_data();
void pinchZoom();
void complexSequence();
+ void buttonClickHandler();
+ void htmlSelectPopup();
private:
+ Page page;
QWebEngineView view;
QSignalSpy loadSpy { &view, &QWebEngineView::loadFinished };
QPoint notextCenter, textCenter, inputCenter;
QString activeElement() { return evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(); }
+ void makeTouch(QWindow *w, const QPoint &p) {
+ QTest::touchEvent(w, s_touchDevice).press(1, p);
+ QTest::touchEvent(w, s_touchDevice).release(1, p);
+ }
+ void makeTouch(const QPoint &p) { makeTouch(view.windowHandle(), p); }
+
void gestureScroll(bool down) {
auto target = view.focusProxy();
QPoint p(target->width() / 2, target->height() / 4 * (down ? 3 : 1));
- QTest::touchEvent(target, s_touchDevice).press(42, p, target);
+ QTest::touchEvent(target, s_touchDevice).press(1, p, target);
QSignalSpy spy(view.page(), &QWebEnginePage::scrollPositionChanged);
for (int i = 0; i < 3; ++i) {
down ? p -= QPoint(5, 15) : p += QPoint(5, 15);
QTest::qWait(100); // too fast and events are recognized as fling gesture
- QTest::touchEvent(target, s_touchDevice).move(42, p, target);
+ QTest::touchEvent(target, s_touchDevice).move(1, p, target);
spy.wait();
}
- QTest::touchEvent(target, s_touchDevice).release(42, p, target);
+ QTest::touchEvent(target, s_touchDevice).release(1, p, target);
}
void gesturePinch(bool zoomIn, bool tapOneByOne = false) {
@@ -85,10 +75,10 @@ private:
auto t1 = p - QPoint(zoomIn ? 50 : 150, 10), t2 = p + QPoint(zoomIn ? 50 : 150, 10);
if (tapOneByOne) {
- QTest::touchEvent(target, s_touchDevice).press(42, t1, target);
- QTest::touchEvent(target, s_touchDevice).stationary(42).press(24, t2, target);
+ QTest::touchEvent(target, s_touchDevice).press(0, t1, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(0).press(1, t2, target);
} else {
- QTest::touchEvent(target, s_touchDevice).press(42, t1, target).press(24, t2, target);
+ QTest::touchEvent(target, s_touchDevice).press(0, t1, target).press(1, t2, target);
}
for (int i = 0; i < 3; ++i) {
@@ -100,14 +90,14 @@ private:
t2 -= QPoint(35, 5);
}
QTest::qWait(100); // too fast and events are recognized as fling gesture
- QTest::touchEvent(target, s_touchDevice).move(24, t1, target).move(42, t2, target);
+ QTest::touchEvent(target, s_touchDevice).move(1, t1, target).move(0, t2, target);
}
if (tapOneByOne) {
- QTest::touchEvent(target, s_touchDevice).stationary(42).release(24, t2, target);
- QTest::touchEvent(target, s_touchDevice).release(42, t1, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(0).release(1, t2, target);
+ QTest::touchEvent(target, s_touchDevice).release(0, t1, target);
} else {
- QTest::touchEvent(target, s_touchDevice).release(42, t1, target).release(24, t2, target);
+ QTest::touchEvent(target, s_touchDevice).release(0, t1, target).release(1, t2, target);
}
}
@@ -131,6 +121,7 @@ void TouchInputTest::initTestCase()
{
s_touchDevice = QTest::createTouchDevice();
+ view.setPage(&page);
view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
view.show(); view.resize(480, 320);
@@ -139,7 +130,10 @@ void TouchInputTest::initTestCase()
view.setHtml("<html><head><style>.rect { min-width: 240px; min-height: 120px; }</style></head><body>"
"<p id='text' style='width: 150px;'>The Qt Company</p>"
"<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
- "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
+ "<form><input id='input' style='width: 150px;' type='text' value='The Qt Company2' /></form>"
+ "<button id='btn' type='button' onclick='alert(\"button clicked!\")'>Click Me!</button>"
+ "<select id='select' onchange='alert(\"option changed to: \" + this.value)'>"
+ "<option value='O1'>O1</option><option value='O2'>O2</option><option value='O3'>O3</option></select>"
"<table style='width: 100%; padding: 15px; text-align: center;'>"
"<tr><td>BEFORE</td><td><div class='rect' style='background-color: #00f;'></div></td><td>AFTER</td></tr>"
"<tr><td>BEFORE</td><td><div class='rect' style='background-color: #0f0;'></div></td><td>AFTER</td></tr>"
@@ -163,6 +157,7 @@ void TouchInputTest::cleanup()
evaluateJavaScriptSync(view.page(), "window.scrollTo(0, 0)");
QTRY_COMPARE(getScrollPosition(), 0);
QTRY_COMPARE(pageScrollPosition(), 0);
+ page.alerts.clear();
}
void TouchInputTest::touchTap()
@@ -308,7 +303,7 @@ void TouchInputTest::pinchZoom()
for (int i = 0; i < 3; ++i) {
gesturePinch(/* zoomIn = */true, tapOneByOne);
- QTRY_VERIFY2(getScaleFactor(&scale) > 1.5, qPrintable(QString("i: %1, scale: %2").arg(i).arg(scale)));
+ QTRY_VERIFY2(getScaleFactor(&scale) > 1.0, qPrintable(QString("i: %1, scale: %2").arg(i).arg(scale)));
gesturePinch(/* zoomIn = */false, tapOneByOne);
QTRY_COMPARE(getScaleFactor(&scale), 1.0);
}
@@ -345,5 +340,33 @@ void TouchInputTest::complexSequence()
}
}
+void TouchInputTest::buttonClickHandler()
+{
+ auto buttonCenter = elementGeometry(view.page(), "btn").center();
+ makeTouch(buttonCenter);
+ QTRY_VERIFY(!page.alerts.isEmpty());
+ QCOMPARE(page.alerts.first(), "button clicked!");
+ QCOMPARE(page.alerts.size(), 1);
+ QEXPECT_FAIL("", "Shouldn't trigger twice due to synthesized mouse events for touch", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(page.alerts.size() == 2, 500);
+}
+
+void TouchInputTest::htmlSelectPopup()
+{
+ auto selectRect = elementGeometry(view.page(), "select");
+ makeTouch(selectRect.center());
+ QTRY_VERIFY(QApplication::activePopupWidget());
+ QCOMPARE(activeElement(), QStringLiteral("select"));
+
+ auto popup = QApplication::activePopupWidget();
+ makeTouch(popup->windowHandle(), QPoint(popup->width() / 2, popup->height() / 2));
+ QTRY_VERIFY(!QApplication::activePopupWidget());
+
+ QTRY_VERIFY(!page.alerts.isEmpty());
+ QCOMPARE(page.alerts.first(), "option changed to: O2");
+ QEXPECT_FAIL("", "Shouldn't trigger twice due to synthesized mouse events for touch", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(page.alerts.size() == 2, 500);
+}
+
QTEST_MAIN(TouchInputTest)
#include "tst_touchinput.moc"
diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt
new file mode 100644
index 000000000..d9f3e11ea
--- /dev/null
+++ b/tests/manual/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_subdirectory(examples)
+if(TARGET Qt::WebEngineQuick)
+ add_subdirectory(quick)
+endif()
+if(TARGET Qt::WebEngineWidgets)
+ add_subdirectory(widgets)
+endif()
diff --git a/tests/manual/examples/CMakeLists.txt b/tests/manual/examples/CMakeLists.txt
new file mode 100644
index 000000000..c56302f20
--- /dev/null
+++ b/tests/manual/examples/CMakeLists.txt
@@ -0,0 +1,6 @@
+if(TARGET Qt::WebEngineWidgets)
+ add_subdirectory(widgets)
+endif()
+if(TARGET Qt::WebEngineQuick)
+ add_subdirectory(quick)
+endif()
diff --git a/tests/manual/examples/quick/CMakeLists.txt b/tests/manual/examples/quick/CMakeLists.txt
new file mode 100644
index 000000000..c461f2dbb
--- /dev/null
+++ b/tests/manual/examples/quick/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_subdirectory(minimal)
+add_subdirectory(customdialogs)
+add_subdirectory(customtouchhandle)
+add_subdirectory(webengineaction)
diff --git a/examples/webenginequick/customdialogs/CMakeLists.txt b/tests/manual/examples/quick/customdialogs/CMakeLists.txt
index 47d773c48..bfbff79eb 100644
--- a/examples/webenginequick/customdialogs/CMakeLists.txt
+++ b/tests/manual/examples/quick/customdialogs/CMakeLists.txt
@@ -1,30 +1,21 @@
-cmake_minimum_required(VERSION 3.16)
-project(customdialogs LANGUAGES CXX)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(customdialogs LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/webenginequick/customdialogs")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS WebEngineQuick)
-
-qt_add_executable(customdialogs
- main.cpp
- server.cpp server.h
+qt_internal_add_manual_test(customdialogs
+ SOURCES main.cpp server.cpp server.h
)
+
set_target_properties(customdialogs PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
+
target_link_libraries(customdialogs PUBLIC
Qt::Core
Qt::Gui
@@ -63,14 +54,3 @@ qt_add_resources(customdialogs "customdialogs"
${customdialogs_resource_files}
)
-if(TARGET Qt::Widgets)
- target_link_libraries(customdialogs PUBLIC
- Qt::Widgets
- )
-endif()
-
-install(TARGETS customdialogs
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/tests/manual/examples/quick/customdialogs/MessageRectangle.qml b/tests/manual/examples/quick/customdialogs/MessageRectangle.qml
new file mode 100644
index 000000000..09a202cf3
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/MessageRectangle.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+Rectangle {
+ property alias text: messageText.text
+ width: parent.width
+ height: 30
+ visible: false
+ color: "#80c342"
+ Text {
+ id: messageText
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ font.pointSize: 12
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/SwitchButton.qml b/tests/manual/examples/quick/customdialogs/SwitchButton.qml
new file mode 100644
index 000000000..69fc1427e
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/SwitchButton.qml
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+Item {
+ width: parent.width
+ height: 40
+ property alias checked: switcher.checked
+ RowLayout {
+ anchors.centerIn: parent
+ Text {
+ text: qsTr("Use default dialogs")
+ font.pointSize: 12
+ }
+ Switch {
+ id: switcher
+ checked: true
+ }
+ }
+}
diff --git a/examples/webenginequick/customdialogs/WebView.qml b/tests/manual/examples/quick/customdialogs/WebView.qml
index fcb10b7da..5c99ee7e7 100644
--- a/examples/webenginequick/customdialogs/WebView.qml
+++ b/tests/manual/examples/quick/customdialogs/WebView.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtWebEngine
diff --git a/examples/webenginequick/customdialogs/customdialogs.pro b/tests/manual/examples/quick/customdialogs/customdialogs.pro
index 1b9a6778e..1b9a6778e 100644
--- a/examples/webenginequick/customdialogs/customdialogs.pro
+++ b/tests/manual/examples/quick/customdialogs/customdialogs.pro
diff --git a/examples/webenginequick/customdialogs/customdialogs.qrc b/tests/manual/examples/quick/customdialogs/customdialogs.qrc
index bb2677198..bb2677198 100644
--- a/examples/webenginequick/customdialogs/customdialogs.qrc
+++ b/tests/manual/examples/quick/customdialogs/customdialogs.qrc
diff --git a/tests/manual/examples/quick/customdialogs/forms/Authentication.qml b/tests/manual/examples/quick/customdialogs/forms/Authentication.qml
new file mode 100644
index 000000000..151a7c4aa
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/Authentication.qml
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtWebEngine
+
+AuthenticationForm {
+ property QtObject request
+ signal closeForm()
+
+ cancelButton.onClicked: {
+ request.dialogReject();
+ closeForm();
+ }
+
+ loginButton.onClicked: {
+ request.dialogReject();
+ closeForm();
+ }
+
+ Component.onCompleted: {
+ switch (request.type) {
+ case AuthenticationDialogRequest.AuthenticationTypeHTTP:
+ console.log("HTTP Authentication Required. Host says: " + request.realm);
+ break;
+ case AuthenticationDialogRequest.AuthenticationTypeProxy:
+ console.log("Proxy Authentication Required for: " + request.proxyHost);
+ break;
+ }
+ }
+}
diff --git a/examples/webenginequick/customdialogs/forms/AuthenticationForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/AuthenticationForm.ui.qml
index ab334aae0..f14986b20 100644
--- a/examples/webenginequick/customdialogs/forms/AuthenticationForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/AuthenticationForm.ui.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Layouts
@@ -78,6 +31,7 @@ Item {
Rectangle {
id: rectangle
+ width: parent.width
height: 30
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
gradient: Gradient {
@@ -119,6 +73,13 @@ Item {
height: 22
Layout.fillWidth: true
font.pointSize: 12
+ color: "black"
+
+ background: Rectangle {
+ color: "white"
+ border.color: "black"
+ border.width: 1
+ }
}
Text {
@@ -133,6 +94,14 @@ Item {
height: 26
Layout.fillWidth: true
font.pointSize: 12
+ color: "black"
+ echoMode: TextInput.Password
+
+ background: Rectangle {
+ color: "white"
+ border.color: "black"
+ border.width: 1
+ }
}
Item {
diff --git a/tests/manual/examples/quick/customdialogs/forms/ColorCell.qml b/tests/manual/examples/quick/customdialogs/forms/ColorCell.qml
new file mode 100644
index 000000000..57151780c
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/ColorCell.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+Rectangle {
+ id: rectangle
+ width: 50
+ height: 50
+ signal clicked()
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: rectangle.clicked()
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml b/tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml
new file mode 100644
index 000000000..63269ddff
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/ColorPicker.qml
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+ColorPickerForm {
+ property QtObject request
+ signal closeForm()
+
+ okButton.onClicked: {
+ request.dialogAccept(colorPicker.color);
+ closeForm();
+ }
+
+ cancelButton.onClicked: {
+ request.dialogReject();
+ closeForm();
+ }
+
+ function createCallback(color) {
+ return function() { colorPicker.color = color };
+ }
+
+ Component.onCompleted:{
+ for (var i = 0; i < grid.children.length; i++) {
+ var cell = grid.children[i];
+ cell.clicked.connect(createCallback(cell.color));
+ }
+ colorPicker.color = request.color;
+ }
+}
diff --git a/examples/webenginequick/customdialogs/forms/ColorPickerForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/ColorPickerForm.ui.qml
index c2de234e7..060aeef7d 100644
--- a/examples/webenginequick/customdialogs/forms/ColorPickerForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/ColorPickerForm.ui.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Layouts
@@ -77,6 +30,7 @@ Item {
}
Rectangle {
+ width: parent.width
height: 30
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
gradient: Gradient {
diff --git a/tests/manual/examples/quick/customdialogs/forms/CustomButton.qml b/tests/manual/examples/quick/customdialogs/forms/CustomButton.qml
new file mode 100644
index 000000000..00a06d558
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/CustomButton.qml
@@ -0,0 +1,61 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+Rectangle {
+ id: root
+ width: 200
+ height: 30
+ radius: 5
+ property string btnText: "Name"
+ property bool btnEnable: true
+ property bool btnBlue: true
+ opacity: btnEnable ? 1.0 : 0.5
+ signal clicked()
+ gradient: btnBlue ? blueButton : greenButton
+ Text {
+ id: textArea
+ x: 54
+ y: 5
+ color: "#ffffff"
+ text: parent.btnText
+ font.pointSize: 12
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ font.bold: false
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: {
+ if (btnEnable)
+ root.clicked();
+ }
+ }
+
+ Gradient {
+ id: blueButton
+ GradientStop {
+ position: 0
+ color: "#25a6e2"
+ }
+ GradientStop {
+ position: mouseArea.pressed && root.btnEnable ? 0.7 :1
+ color: "#188bd0"
+ }
+ }
+
+ Gradient {
+ id: greenButton
+ GradientStop {
+ position: 0
+ color: "#80c342"
+ }
+ GradientStop {
+ position: mouseArea.pressed && root.btnEnable ? 0.7 :1
+ color: "#5fac18"
+ }
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/FilePicker.qml b/tests/manual/examples/quick/customdialogs/forms/FilePicker.qml
new file mode 100644
index 000000000..45ffefb3a
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/FilePicker.qml
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+FilePickerForm {
+ property QtObject request
+ property string selectedFile
+ signal closeForm()
+
+ cancelButton.onClicked: {
+ request.dialogReject();
+ closeForm();
+ }
+
+ okButton.onClicked: {
+ request.dialogAccept('/' + selectedFile);
+ closeForm();
+ }
+
+ function createCallback(fileIndex) {
+ return function() {
+ for (var i = 0; i < files.children.length; i++) {
+ var file = files.children[i];
+ if (i === fileIndex) {
+ selectedFile = file.text;
+ file.selected = true;
+ } else {
+ file.selected = false;
+ }
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ selectedFile = request.defaultFileName;
+ for (var i = 0; i < files.children.length; i++) {
+ var file = files.children[i];
+ file.clicked.connect(createCallback(i));
+ if (file.text === selectedFile)
+ file.selected = true;
+ }
+ }
+}
diff --git a/examples/webenginequick/customdialogs/forms/FilePickerForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/FilePickerForm.ui.qml
index 8a230c982..1e99b1a91 100644
--- a/examples/webenginequick/customdialogs/forms/FilePickerForm.ui.qml
+++ b/tests/manual/examples/quick/customdialogs/forms/FilePickerForm.ui.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Layouts
@@ -77,6 +30,7 @@ Item {
Rectangle {
id: rectangle
+ width: parent.width
height: 30
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
gradient: Gradient {
diff --git a/tests/manual/examples/quick/customdialogs/forms/FileRow.qml b/tests/manual/examples/quick/customdialogs/forms/FileRow.qml
new file mode 100644
index 000000000..1a0cfc0a0
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/FileRow.qml
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+
+Item {
+ id: root
+ height: 30
+ property string text: "Filename"
+ property bool selected: false
+ signal clicked()
+
+ RowLayout {
+ id: fileRow
+ width: 100
+
+ Item {
+ id: item5
+ width: 10
+ height: 10
+ }
+
+ Rectangle {
+ id: rectangle2
+ width: 10
+ height: 10
+ color: selected ? "#80c342" : "#25a6e2"
+ }
+
+ Text {
+ id: filename
+ text: root.text
+ font.pointSize: 12
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ width: 200
+ height: 30
+ onClicked: root.clicked()
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/JavaScript.qml b/tests/manual/examples/quick/customdialogs/forms/JavaScript.qml
new file mode 100644
index 000000000..132c95697
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/JavaScript.qml
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtWebEngine
+
+JavaScriptForm {
+ property QtObject request
+ signal closeForm()
+
+ cancelButton.onClicked: {
+ request.dialogReject();
+ closeForm();
+ }
+
+ okButton.onClicked: {
+ request.dialogAccept(prompt.text);
+ closeForm();
+ }
+
+ Component.onCompleted: {
+ switch (request.type) {
+ case JavaScriptDialogRequest.DialogTypeAlert:
+ cancelButton.visible = false;
+ title = qsTr("Alert");
+ message = request.message;
+ prompt.text = "";
+ prompt.visible = false;
+ break;
+ case JavaScriptDialogRequest.DialogTypeConfirm:
+ title = qsTr("Confirm");
+ message = request.message;
+ prompt.text = "";
+ prompt.visible = false;
+ break;
+ case JavaScriptDialogRequest.DialogTypePrompt:
+ title = qsTr("Prompt");
+ message = request.message;
+ prompt.text = request.defaultText;
+ prompt.visible = true;
+ break;
+ }
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml
new file mode 100644
index 000000000..b535e7ef9
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/JavaScriptForm.ui.qml
@@ -0,0 +1,117 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+
+Item {
+ id: root
+ property alias cancelButton: cancelButton
+ property alias okButton: okButton
+ property string message: "Message"
+ property string title: "Title"
+ property alias prompt: prompt
+
+ ColumnLayout {
+ id: columnLayout
+ anchors.topMargin: 20
+ anchors.top: parent.top
+ anchors.bottomMargin: 20
+ anchors.bottom: parent.bottom
+ anchors.rightMargin: 20
+ anchors.right: parent.right
+ anchors.leftMargin: 20
+ anchors.left: parent.left
+
+ Image {
+ id: image
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ source: "qrc:/icon.svg"
+ }
+
+ Rectangle {
+ id: rectangle
+ width: parent.width
+ height: 30
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ gradient: Gradient {
+ GradientStop {
+ position: 0
+ color: "#25a6e2"
+ }
+
+ GradientStop {
+ color: "#188bd0"
+ }
+ }
+
+ Text {
+ id: title
+ x: 54
+ y: 5
+ color: "#ffffff"
+ text: qsTr("Title")
+ font.pointSize: 12
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Item {
+ width: 40
+ height: 40
+ }
+
+ Text {
+ id: message
+ text: root.message
+ font.pointSize: 12
+ }
+
+ TextField {
+ id: prompt
+ width: 300
+ height: 22
+ Layout.fillWidth: true
+ font.pointSize: 12
+ color: "black"
+
+ background: Rectangle {
+ color: "white"
+ border.color: "black"
+ border.width: 1
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ }
+
+ RowLayout {
+ id: rowLayout
+ width: 100
+ height: 100
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ CustomButton {
+ id: cancelButton
+ width: 90
+ height: 30
+ btnText: qsTr("Cancel")
+ btnBlue: false
+ }
+
+ CustomButton {
+ id: okButton
+ width: 90
+ height: 30
+ btnText: qsTr("OK")
+ btnBlue: false
+ }
+ }
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/Menu.qml b/tests/manual/examples/quick/customdialogs/forms/Menu.qml
new file mode 100644
index 000000000..b90802a0c
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/Menu.qml
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+MenuForm {
+ property QtObject request
+ signal closeForm()
+
+ followLink.onClicked: closeForm()
+ back.onClicked: closeForm()
+ forward.onClicked: closeForm()
+ reload.onClicked: closeForm()
+ copyLinkUrl.onClicked: closeForm()
+ saveLink.onClicked: closeForm()
+ close.onClicked: closeForm()
+
+ Component.onCompleted: {
+ back.btnEnable = false;
+ forward.btnEnable = false;
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml
new file mode 100644
index 000000000..b4c06bb7d
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/MenuForm.ui.qml
@@ -0,0 +1,65 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+
+Item {
+ property alias followLink: followLink
+ property alias back: back
+ property alias forward: forward
+ property alias reload: reload
+ property alias copyLinkUrl: copyLinkUrl
+ property alias saveLink: saveLink
+ property alias close: close
+
+ ColumnLayout {
+ id: columnLayout
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ Image {
+ id: image
+ width: 100
+ height: 100
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ source: "qrc:/icon.svg"
+ }
+
+ CustomButton {
+ id: followLink
+ btnText: qsTr("Follow")
+ }
+
+ CustomButton {
+ id: back
+ btnText: qsTr("Back")
+ }
+
+ CustomButton {
+ id: forward
+ btnText: qsTr("Forward")
+ }
+
+ CustomButton {
+ id: reload
+ btnText: qsTr("Reload")
+ }
+
+ CustomButton {
+ id: copyLinkUrl
+ btnText: qsTr("Copy Link URL")
+ }
+
+ CustomButton {
+ id: saveLink
+ btnText: qsTr("Save Link")
+ }
+
+ CustomButton {
+ id: close
+ btnBlue: false
+ btnText: qsTr("Close")
+ }
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml
new file mode 100644
index 000000000..1b0c19789
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenu.qml
@@ -0,0 +1,14 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+TouchSelectionMenuForm {
+ property QtObject request
+ signal closeForm()
+
+ cut.onClicked: closeForm()
+ copy.onClicked: closeForm()
+ paste.onClicked: closeForm()
+ contextMenu.onClicked: closeForm()
+}
diff --git a/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
new file mode 100644
index 000000000..bed39566f
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/forms/TouchSelectionMenuForm.ui.qml
@@ -0,0 +1,39 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+
+Item {
+ property alias cut: cut
+ property alias copy: copy
+ property alias paste: paste
+ property alias contextMenu: contextMenu
+
+ ColumnLayout {
+ id: columnLayout
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ CustomButton {
+ id: cut
+ btnText: qsTr("Cut")
+ }
+
+ CustomButton {
+ id: copy
+ btnText: qsTr("Copy")
+ }
+
+ CustomButton {
+ id: paste
+ btnText: qsTr("Paste")
+ }
+
+ CustomButton {
+ id: contextMenu
+ btnText: qsTr("...")
+ }
+
+ }
+}
diff --git a/examples/webenginequick/customdialogs/forms/forms.qmlproject b/tests/manual/examples/quick/customdialogs/forms/forms.qmlproject
index b06afaaf1..b06afaaf1 100644
--- a/examples/webenginequick/customdialogs/forms/forms.qmlproject
+++ b/tests/manual/examples/quick/customdialogs/forms/forms.qmlproject
diff --git a/examples/webenginequick/customdialogs/icon.svg b/tests/manual/examples/quick/customdialogs/icon.svg
index 48271180b..48271180b 100644
--- a/examples/webenginequick/customdialogs/icon.svg
+++ b/tests/manual/examples/quick/customdialogs/icon.svg
diff --git a/examples/webenginequick/customdialogs/index.html b/tests/manual/examples/quick/customdialogs/index.html
index d5de2827c..d5de2827c 100644
--- a/examples/webenginequick/customdialogs/index.html
+++ b/tests/manual/examples/quick/customdialogs/index.html
diff --git a/tests/manual/examples/quick/customdialogs/main.cpp b/tests/manual/examples/quick/customdialogs/main.cpp
new file mode 100644
index 000000000..c114ea935
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/main.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "server.h"
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+#include <QNetworkProxy>
+#include <QQmlApplicationEngine>
+#include <QTimer>
+#include <QtGui/QGuiApplication>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QtWebEngineQuick::initialize();
+
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ Server *server = new Server(&engine);
+
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ QTimer::singleShot(0, server, &Server::run);
+
+ QNetworkProxy proxy;
+ proxy.setType(QNetworkProxy::HttpProxy);
+ proxy.setHostName("localhost");
+ proxy.setPort(5555);
+ QNetworkProxy::setApplicationProxy(proxy);
+
+ return app.exec();
+}
+
diff --git a/tests/manual/examples/quick/customdialogs/main.qml b/tests/manual/examples/quick/customdialogs/main.qml
new file mode 100644
index 000000000..d0cb6f324
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/main.qml
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Window
+
+Window {
+ id: mainWindow
+ width: 800
+ height: 610
+ visible: true
+
+ StackView {
+ id: stackView
+ anchors.fill: parent
+ focus: true
+ initialItem: Item {
+ id: main
+ width: mainWindow.width
+ height: mainWindow.height
+ ColumnLayout {
+ anchors.fill: parent
+ SwitchButton {
+ id: switcher
+ Layout.fillWidth: true
+ }
+ WebView {
+ id: webView
+ useDefaultDialogs: switcher.checked
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+ }
+
+ function closeForm()
+ {
+ pop(main);
+ // reset url in case of proxy error
+ webView.url = "qrc:/index.html"
+ }
+
+ function openForm(form)
+ {
+ push(form.item, form.properties);
+ currentItem.closeForm.connect(closeForm);
+ }
+
+ }
+
+ Component.onCompleted: {
+ webView.openForm.connect(stackView.openForm);
+ }
+}
diff --git a/tests/manual/examples/quick/customdialogs/server.cpp b/tests/manual/examples/quick/customdialogs/server.cpp
new file mode 100644
index 000000000..efb870618
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/server.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "server.h"
+#include <QDataStream>
+#include <QTcpSocket>
+
+Server::Server(QObject *parent) : QObject(parent)
+{
+ connect(&m_server, &QTcpServer::newConnection, this, &Server::handleNewConnection);
+}
+
+void Server::run()
+{
+ if (!m_server.listen(QHostAddress::LocalHost, 5555))
+ qWarning() << "Could not start the server -> http/proxy authentication dialog"
+ " will not work. Error:" << m_server.errorString();
+}
+
+void Server::handleNewConnection()
+{
+ QTcpSocket *socket = m_server.nextPendingConnection();
+ connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
+ connect(socket, &QAbstractSocket::readyRead, this, &Server::handleReadReady);
+}
+
+void Server::handleReadReady()
+{
+ QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
+ Q_ASSERT(socket);
+ m_data.append(socket->readAll());
+
+ // simply wait for whole request
+ if (!m_data.endsWith("\r\n\r\n"))
+ return;
+ if (m_data.contains(QByteArrayLiteral("OPEN_AUTH"))) {
+ socket->write("HTTP/1.1 401 Unauthorized\nWWW-Authenticate: "
+ "Basic realm=\"Very Restricted Area\"\r\n\r\n");
+ m_data.clear();
+ return;
+ }
+
+ socket->write("HTTP/1.1 407 Proxy Auth Required\nProxy-Authenticate: "
+ "Basic realm=\"Proxy requires authentication\"\r\n"
+ "content-length: 0\r\n\r\n");
+ m_data.clear();
+}
diff --git a/tests/manual/examples/quick/customdialogs/server.h b/tests/manual/examples/quick/customdialogs/server.h
new file mode 100644
index 000000000..563465013
--- /dev/null
+++ b/tests/manual/examples/quick/customdialogs/server.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef SERVER_H
+#define SERVER_H
+
+#include <QObject>
+#include <QTcpServer>
+
+class Server : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit Server(QObject *parent = nullptr);
+
+public slots:
+ void run();
+
+private slots:
+ void handleNewConnection();
+ void handleReadReady();
+
+private:
+ QTcpServer m_server;
+ QByteArray m_data;
+};
+
+#endif // SERVER_H
diff --git a/examples/webenginequick/customdialogs/style.css b/tests/manual/examples/quick/customdialogs/style.css
index e4c25e7eb..e4c25e7eb 100644
--- a/examples/webenginequick/customdialogs/style.css
+++ b/tests/manual/examples/quick/customdialogs/style.css
diff --git a/tests/manual/examples/quick/customtouchhandle/CMakeLists.txt b/tests/manual/examples/quick/customtouchhandle/CMakeLists.txt
new file mode 100644
index 000000000..5574c28b8
--- /dev/null
+++ b/tests/manual/examples/quick/customtouchhandle/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(customtouchhandle LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(customtouchhandle
+ SOURCES main.cpp
+)
+
+set_target_properties(customtouchhandle PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(customtouchhandle PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineQuick
+)
+
+# Resources:
+set(qml_resource_files
+ "main.qml"
+)
+
+qt6_add_resources(customtouchhandle "qml"
+ PREFIX
+ "/"
+ FILES
+ ${qml_resource_files}
+)
+
diff --git a/examples/webenginequick/webengineaction/webengineaction.pro b/tests/manual/examples/quick/customtouchhandle/customtouchhandle.pro
index 7ef0a8bcf..a74ef3146 100644
--- a/examples/webenginequick/webengineaction/webengineaction.pro
+++ b/tests/manual/examples/quick/customtouchhandle/customtouchhandle.pro
@@ -6,5 +6,5 @@ SOURCES += main.cpp
RESOURCES += qml.qrc
-target.path = $$[QT_INSTALL_EXAMPLES]/webenginequick/webengineaction
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginequick/customtouchhandle
INSTALLS += target
diff --git a/tests/manual/examples/quick/customtouchhandle/main.cpp b/tests/manual/examples/quick/customtouchhandle/main.cpp
new file mode 100644
index 000000000..f1b70b024
--- /dev/null
+++ b/tests/manual/examples/quick/customtouchhandle/main.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ QtWebEngineQuick::initialize();
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
diff --git a/tests/manual/examples/quick/customtouchhandle/main.qml b/tests/manual/examples/quick/customtouchhandle/main.qml
new file mode 100644
index 000000000..c40b4c73b
--- /dev/null
+++ b/tests/manual/examples/quick/customtouchhandle/main.qml
@@ -0,0 +1,96 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+import QtWebEngine
+import QtQuick.Layouts
+import QtQuick.Controls
+
+ApplicationWindow {
+ width: 1024
+ height: 750
+ visible: true
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+
+ ToolButton {
+ property int itemAction: WebEngineView.Back
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ ToolButton {
+ property int itemAction: WebEngineView.Forward
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ ToolButton {
+ property int itemAction: webEngineView.loading ? WebEngineView.Stop : WebEngineView.Reload
+ text: webEngineView.action(itemAction).text
+ enabled: webEngineView.action(itemAction).enabled
+ onClicked: webEngineView.action(itemAction).trigger()
+ icon.name: webEngineView.action(itemAction).iconName
+ display: AbstractButton.TextUnderIcon
+ }
+
+ TextField {
+ Layout.fillWidth: true
+ text: webEngineView.url
+ selectByMouse: true
+ onEditingFinished: webEngineView.url = text
+ }
+
+ Label { text: 'Handle: ' }
+ ComboBox {
+ model: [ 'Default', 'Circle', 'Square' ]
+
+ onCurrentValueChanged: {
+ if (currentValue == 'Circle')
+ webEngineView.touchHandleDelegate = circleTouchHandle
+ else if (currentValue == 'Square')
+ webEngineView.touchHandleDelegate = rectTouchHandle
+ else
+ webEngineView.touchHandleDelegate = null
+ }
+
+ Component.onCompleted: currentIndex = indexOfValue('Square')
+ }
+ }
+ }
+
+ Component {
+ id: circleTouchHandle
+ Rectangle {
+ color: "blue"
+ border.color: "black"
+ border.width: 2
+ radius: 50
+ }
+ }
+
+ Component {
+ id: rectTouchHandle
+ Rectangle {
+ border.color: "black"
+ border.width: 2
+ radius: 2
+ onVisibleChanged: if (visible) { color = 'yellow'; cAnim.restart(); }
+ ColorAnimation on color { id: cAnim; to: 'red'; duration: 1000 }
+ }
+ }
+
+ WebEngineView {
+ anchors.fill: parent
+ id: webEngineView
+ url: "https://www.qt.io"
+ }
+}
diff --git a/examples/webenginequick/webengineaction/qml.qrc b/tests/manual/examples/quick/customtouchhandle/qml.qrc
index 5f6483ac3..5f6483ac3 100644
--- a/examples/webenginequick/webengineaction/qml.qrc
+++ b/tests/manual/examples/quick/customtouchhandle/qml.qrc
diff --git a/tests/manual/examples/quick/minimal/CMakeLists.txt b/tests/manual/examples/quick/minimal/CMakeLists.txt
new file mode 100644
index 000000000..42e2078f7
--- /dev/null
+++ b/tests/manual/examples/quick/minimal/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(minimal LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(webengine-minimal-qml
+ SOURCES
+ main.cpp
+)
+
+set_target_properties(webengine-minimal-qml PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(webengine-minimal-qml PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineQuick
+)
+
+# Resources:
+set(qml_resource_files
+ "main.qml"
+)
+
+qt_add_resources(webengine-minimal-qml "qml"
+ PREFIX
+ "/"
+ FILES
+ ${qml_resource_files}
+)
diff --git a/tests/manual/examples/quick/minimal/main.cpp b/tests/manual/examples/quick/minimal/main.cpp
new file mode 100644
index 000000000..16466ae06
--- /dev/null
+++ b/tests/manual/examples/quick/minimal/main.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ QtWebEngineQuick::initialize();
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
diff --git a/tests/manual/examples/quick/minimal/main.qml b/tests/manual/examples/quick/minimal/main.qml
new file mode 100644
index 000000000..6890b501b
--- /dev/null
+++ b/tests/manual/examples/quick/minimal/main.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+import QtWebEngine
+
+Window {
+ width: 1024
+ height: 750
+ visible: true
+ WebEngineView {
+ anchors.fill: parent
+ url: "chrome://qt"
+ }
+}
diff --git a/examples/webenginequick/minimal/minimal.pro b/tests/manual/examples/quick/minimal/minimal.pro
index acca6477c..acca6477c 100644
--- a/examples/webenginequick/minimal/minimal.pro
+++ b/tests/manual/examples/quick/minimal/minimal.pro
diff --git a/examples/webenginequick/minimal/qml.qrc b/tests/manual/examples/quick/minimal/qml.qrc
index 0ff3892d9..0ff3892d9 100644
--- a/examples/webenginequick/minimal/qml.qrc
+++ b/tests/manual/examples/quick/minimal/qml.qrc
diff --git a/tests/manual/examples/quick/webengineaction/CMakeLists.txt b/tests/manual/examples/quick/webengineaction/CMakeLists.txt
new file mode 100644
index 000000000..e16772faf
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(webengineaction LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(webengineaction
+ SOURCES
+ main.cpp
+ utils.h
+)
+
+set_target_properties(webengineaction PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(webengineaction PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineQuick
+)
+
+# Resources:
+set(qml_resource_files
+ "main.qml"
+)
+
+qt_add_resources(webengineaction "qml"
+ PREFIX
+ "/"
+ FILES
+ ${qml_resource_files}
+)
diff --git a/tests/manual/examples/quick/webengineaction/main.cpp b/tests/manual/examples/quick/webengineaction/main.cpp
new file mode 100644
index 000000000..a7bfaaf36
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/main.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "utils.h"
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QtWebEngineQuick::initialize();
+
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ Utils utils;
+
+ engine.rootContext()->setContextProperty("utils", &utils);
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
diff --git a/examples/webenginequick/webengineaction/main.qml b/tests/manual/examples/quick/webengineaction/main.qml
index fbb76411e..a1483b126 100644
--- a/examples/webenginequick/webengineaction/main.qml
+++ b/tests/manual/examples/quick/webengineaction/main.qml
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Window
@@ -97,7 +50,7 @@ ApplicationWindow {
text: webEngineView.url
selectByMouse: true
- onEditingFinished: webEngineView.url = text
+ onEditingFinished: webEngineView.url = utils.fromUserInput(text)
}
ToolButton {
diff --git a/tests/manual/quick/touchbrowser/qml.qrc b/tests/manual/examples/quick/webengineaction/qml.qrc
index 45210fe36..5f6483ac3 100644
--- a/tests/manual/quick/touchbrowser/qml.qrc
+++ b/tests/manual/examples/quick/webengineaction/qml.qrc
@@ -1,6 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
- <file>AddressBar.qml</file>
</qresource>
</RCC>
diff --git a/tests/manual/examples/quick/webengineaction/utils.h b/tests/manual/examples/quick/webengineaction/utils.h
new file mode 100644
index 000000000..d9a803907
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/utils.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QUrl>
+
+class Utils : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE static QUrl fromUserInput(const QString &userInput);
+};
+
+inline QUrl Utils::fromUserInput(const QString &userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+#endif // UTILS_H
diff --git a/tests/manual/examples/quick/webengineaction/webengineaction.pro b/tests/manual/examples/quick/webengineaction/webengineaction.pro
new file mode 100644
index 000000000..9286604a1
--- /dev/null
+++ b/tests/manual/examples/quick/webengineaction/webengineaction.pro
@@ -0,0 +1,8 @@
+TEMPLATE = app
+
+QT += webenginequick
+
+HEADERS += utils.h
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc
diff --git a/tests/manual/examples/widgets/CMakeLists.txt b/tests/manual/examples/widgets/CMakeLists.txt
new file mode 100644
index 000000000..d853ba634
--- /dev/null
+++ b/tests/manual/examples/widgets/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(minimal)
diff --git a/tests/manual/examples/widgets/minimal/CMakeLists.txt b/tests/manual/examples/widgets/minimal/CMakeLists.txt
new file mode 100644
index 000000000..3b39683ba
--- /dev/null
+++ b/tests/manual/examples/widgets/minimal/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(minimal LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+ endif()
+
+qt_internal_add_manual_test(minimal-widgets
+ SOURCES
+ main.cpp
+)
+
+set_target_properties(minimal-widgets PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(minimal-widgets PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+)
diff --git a/tests/manual/examples/widgets/minimal/main.cpp b/tests/manual/examples/widgets/minimal/main.cpp
new file mode 100644
index 000000000..425973116
--- /dev/null
+++ b/tests/manual/examples/widgets/minimal/main.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+#include <QWebEngineView>
+
+QUrl commandLineUrlArgument()
+{
+ const QStringList args = QCoreApplication::arguments();
+ for (const QString &arg : args.mid(1)) {
+ if (!arg.startsWith(QLatin1Char('-')))
+ return QUrl::fromUserInput(arg);
+ }
+ return QUrl(QStringLiteral("chrome://qt"));
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName("QtExamples");
+ QApplication app(argc, argv);
+
+ QWebEngineView view;
+ view.setUrl(commandLineUrlArgument());
+ view.resize(1024, 750);
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/minimal/minimal.pro b/tests/manual/examples/widgets/minimal/minimal.pro
index 849f4b9b6..849f4b9b6 100644
--- a/examples/webenginewidgets/minimal/minimal.pro
+++ b/tests/manual/examples/widgets/minimal/minimal.pro
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
deleted file mode 100644
index edf95846c..000000000
--- a/tests/manual/manual.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += \
- widgets \
- quick
-
-!qtHaveModule(webenginewidgets): SUBDIRS -= widgets
diff --git a/tests/manual/quick/CMakeLists.txt b/tests/manual/quick/CMakeLists.txt
new file mode 100644
index 000000000..d6c4b88a9
--- /dev/null
+++ b/tests/manual/quick/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(touchbrowser)
+add_subdirectory(geopermission)
diff --git a/tests/manual/quick/geopermission/CMakeLists.txt b/tests/manual/quick/geopermission/CMakeLists.txt
new file mode 100644
index 000000000..088f248e1
--- /dev/null
+++ b/tests/manual/quick/geopermission/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_geopermission LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(tst_geopermission
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Qml
+ Qt::Quick
+ Qt::WebEngineQuick
+)
+
+if(WIN32)
+ set_property(
+ TARGET tst_geopermission
+ APPEND PROPERTY
+ SOURCES tst_geopermission.exe.manifest)
+endif()
+
+set_target_properties(tst_geopermission PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.dev.webenginequick.tst_geopermission"
+)
+
+# Resources:
+set(resources_resource_files
+ "tst_geopermission.qml"
+ "geolocation.html"
+)
+
+qt_add_resources(tst_geopermission "resources"
+ PREFIX
+ "/"
+ FILES
+ ${resources_resource_files}
+)
+
+foreach(permission_plugin IN LISTS QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_permissions)
+ set(permission_plugin "${QT_CMAKE_EXPORT_NAMESPACE}::${permission_plugin}")
+ qt6_import_plugins(tst_geopermission INCLUDE ${permission_plugin})
+endforeach()
+
+if (APPLE)
+ set_target_properties(tst_geopermission PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist"
+ )
+
+ if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ # Need to sign application for location permissions to work
+ add_custom_command(TARGET tst_geopermission
+ POST_BUILD COMMAND codesign -s - tst_geopermission.app)
+ endif()
+endif()
+
diff --git a/tests/manual/quick/geopermission/Info.plist b/tests/manual/quick/geopermission/Info.plist
new file mode 100644
index 000000000..9853e1900
--- /dev/null
+++ b/tests/manual/quick/geopermission/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>NSLocationUsageDescription</key>
+ <string>Geolocation test would like to give web sites access to your location for demo purposes.</string>
+</dict>
+</plist>
diff --git a/tests/manual/quick/geopermission/geolocation.html b/tests/manual/quick/geopermission/geolocation.html
new file mode 100644
index 000000000..e8c54bc58
--- /dev/null
+++ b/tests/manual/quick/geopermission/geolocation.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<title>Geolocation Permission API Test</title>
+<script>
+
+var errorMessage;
+var handled = false;
+
+function successHandler(location) {
+ var message = document.getElementById("message");
+ message.innerHTML = "Latitude: " + location.coords.latitude +
+ "<br>Longitude: " + location.coords.longitude;
+
+ errorMessage = "";
+ handled = true;
+}
+
+function errorHandler(error) {
+ errorMessage = error.message;
+ handled = true;
+}
+
+<!-- One shot example -->
+navigator.geolocation.getCurrentPosition(successHandler, errorHandler);
+
+</script>
+</head>
+<body>
+<div id="message">Location unknown</div>
+</body>
+</html>
+
diff --git a/tests/manual/quick/geopermission/main.cpp b/tests/manual/quick/geopermission/main.cpp
new file mode 100644
index 000000000..e0ff6f3e7
--- /dev/null
+++ b/tests/manual/quick/geopermission/main.cpp
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+
+#include <QtQml/QQmlApplicationEngine>
+#include <QtQml/QQmlContext>
+#include <QQuickView>
+
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QCommandLineOption>
+#include <QtCore/QLoggingCategory>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication::setApplicationName("Geopermission test");
+ QCoreApplication::setOrganizationName("QtProject");
+
+ QtWebEngineQuick::initialize();
+
+ QGuiApplication app(argc, argv);
+
+ QQuickView view;
+
+ view.setTitle("Touch Browser");
+ view.setFlags(Qt::Window | Qt::WindowTitleHint);
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.setSource(QUrl("qrc:/tst_geopermission.qml"));
+
+ QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));
+
+ view.show();
+ if (view.size().isEmpty())
+ view.setGeometry(0, 0, 800, 600);
+
+ return app.exec();
+}
diff --git a/tests/manual/quick/geopermission/tst_geopermission.qml b/tests/manual/quick/geopermission/tst_geopermission.qml
new file mode 100644
index 000000000..36317c176
--- /dev/null
+++ b/tests/manual/quick/geopermission/tst_geopermission.qml
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtWebEngine
+
+WebEngineView {
+ id: webEngineView
+ width: 200
+ height: 200
+ url: Qt.resolvedUrl("qrc:/geolocation.html")
+ property bool deniedGeolocation: false
+ property bool geoPermissionRequested: false
+
+ onFeaturePermissionRequested: function(securityOrigin, feature) {
+ if (feature === WebEngineView.Geolocation) {
+ geoPermissionRequested = true
+ if (deniedGeolocation) {
+ webEngineView.grantFeaturePermission(securityOrigin, feature, false)
+ }
+ else {
+ webEngineView.grantFeaturePermission(securityOrigin, feature, true)
+ }
+ }
+ }
+
+}
diff --git a/tests/manual/quick/pdf/bookmarks-list.qml b/tests/manual/quick/pdf/bookmarks-list.qml
new file mode 100644
index 000000000..2be0d6848
--- /dev/null
+++ b/tests/manual/quick/pdf/bookmarks-list.qml
@@ -0,0 +1,136 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Pdf
+import QtQuick.Shapes
+
+ApplicationWindow {
+ id: root
+ width: 800
+ height: 940
+ title: doc.source
+ visible: true
+
+ property PdfDocument doc: PdfDocument { source: "test.pdf" }
+
+ Component.onCompleted: {
+ if (Application.arguments.length > 2)
+ doc.source = Application.arguments[Application.arguments.length - 1]
+ }
+ FileDialog {
+ id: fileDialog
+ title: "Open a PDF file"
+ nameFilters: [ "PDF files (*.pdf)" ]
+ onAccepted: doc.source = selectedFile
+ }
+
+ SplitView {
+ anchors.fill: parent
+
+ Pane {
+ SplitView.minimumWidth: 6
+ SplitView.preferredWidth: 200
+ clip: true
+ ListView {
+ ScrollIndicator.vertical: ScrollIndicator { }
+ anchors.fill: parent
+ delegate: ItemDelegate {
+ width: parent.width
+ text: model.title
+ background: Item { }
+ onClicked: image.currentFrame = page
+ }
+ model: PdfBookmarkModel {
+ document: root.doc
+ }
+ }
+ }
+
+ Flickable {
+ contentWidth: paper.width
+ contentHeight: paper.height
+ z: -1
+ Rectangle {
+ id: paper
+ width: image.width
+ height: image.height
+ PdfPageImage {
+ id: image
+ document: doc
+
+ property real zoomFactor: Math.sqrt(2)
+
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ enabled: image.currentFrame < image.frameCount - 1
+ onActivated: image.currentFrame++
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ enabled: image.currentFrame > 0
+ onActivated: image.currentFrame--
+ }
+ Shortcut {
+ sequence: StandardKey.ZoomIn
+ enabled: image.sourceSize.width < 5000
+ onActivated: {
+ image.sourceSize.width = image.implicitWidth * image.zoomFactor
+ image.sourceSize.height = image.implicitHeight * image.zoomFactor
+ }
+ }
+ Shortcut {
+ sequence: StandardKey.ZoomOut
+ enabled: image.width > 50
+ onActivated: {
+ image.sourceSize.width = image.implicitWidth / image.zoomFactor
+ image.sourceSize.height = image.implicitHeight / image.zoomFactor
+ }
+ }
+ Shortcut {
+ sequence: "Ctrl+0"
+ onActivated: image.sourceSize = undefined
+ }
+ Shortcut {
+ sequence: StandardKey.Open
+ onActivated: fileDialog.open()
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+ }
+
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: doc
+ page: image.currentFrame
+ }
+ delegate: Rectangle {
+ color: "transparent"
+ border.color: "lightgrey"
+ x: rect.x
+ y: rect.y
+ width: rect.width
+ height: rect.height
+ HoverHandler { cursorShape: Qt.PointingHandCursor }
+ TapHandler {
+ onTapped: {
+ if (page >= 0)
+ image.currentFrame = page
+ else
+ Qt.openUrlExternally(url)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Text {
+ anchors { bottom: parent.bottom; right: parent.right; margins: 6 }
+ text: "page " + doc.pageLabel(image.currentFrame) + " of " + doc.pageCount
+ }
+}
diff --git a/tests/manual/quick/pdf/bookmarks.qml b/tests/manual/quick/pdf/bookmarks.qml
new file mode 100644
index 000000000..e12629b31
--- /dev/null
+++ b/tests/manual/quick/pdf/bookmarks.qml
@@ -0,0 +1,147 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Pdf
+import QtQuick.Shapes
+
+ApplicationWindow {
+ id: root
+ width: 800
+ height: 940
+ color: "darkgrey"
+ title: doc.source
+ visible: true
+
+ property PdfDocument doc: PdfDocument { source: "test.pdf" }
+
+ Component.onCompleted: {
+ if (Application.arguments.length > 2)
+ doc.source = Application.arguments[Application.arguments.length - 1]
+ }
+ FileDialog {
+ id: fileDialog
+ title: "Open a PDF file"
+ nameFilters: [ "PDF files (*.pdf)" ]
+ onAccepted: doc.source = selectedFile
+ }
+
+ SplitView {
+ anchors.fill: parent
+
+ Pane {
+ SplitView.minimumWidth: 6
+ SplitView.preferredWidth: 200
+ TreeView {
+ id: bookmarksTree
+ anchors.fill: parent
+ columnWidthProvider: function() { return width }
+ onWidthChanged: forceLayout() // workaround to avoid column width getting stuck
+ clip: true
+ delegate: TreeViewDelegate {
+ width: parent.width
+ onClicked: image.currentFrame = page
+ }
+ model: PdfBookmarkModel {
+ document: root.doc
+ }
+ ScrollIndicator.vertical: ScrollIndicator {
+ // get the ScrollIndicator out into the margin area of the Pane...
+ // no need to overlap the tree when so much space is wasted anyway
+ parent: bookmarksTree.parent
+ anchors {
+ top: bookmarksTree.top
+ left: bookmarksTree.right
+ bottom: bookmarksTree.bottom
+ }
+ }
+ }
+ }
+
+ ScrollView {
+ contentWidth: paper.width
+ contentHeight: paper.height
+
+ Rectangle {
+ id: paper
+ width: image.width
+ height: image.height
+ PdfPageImage {
+ id: image
+ document: doc
+
+ property real zoomFactor: Math.sqrt(2)
+
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ enabled: image.currentFrame < image.frameCount - 1
+ onActivated: image.currentFrame++
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ enabled: image.currentFrame > 0
+ onActivated: image.currentFrame--
+ }
+ Shortcut {
+ sequence: StandardKey.ZoomIn
+ enabled: image.sourceSize.width < 5000
+ onActivated: {
+ image.sourceSize.width = image.implicitWidth * image.zoomFactor
+ image.sourceSize.height = image.implicitHeight * image.zoomFactor
+ }
+ }
+ Shortcut {
+ sequence: StandardKey.ZoomOut
+ enabled: image.width > 50
+ onActivated: {
+ image.sourceSize.width = image.implicitWidth / image.zoomFactor
+ image.sourceSize.height = image.implicitHeight / image.zoomFactor
+ }
+ }
+ Shortcut {
+ sequence: "Ctrl+0"
+ onActivated: image.sourceSize = undefined
+ }
+ Shortcut {
+ sequence: StandardKey.Open
+ onActivated: fileDialog.open()
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+ }
+
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: doc
+ page: image.currentFrame
+ }
+ delegate: Rectangle {
+ color: "transparent"
+ border.color: "lightgrey"
+ x: rect.x
+ y: rect.y
+ width: rect.width
+ height: rect.height
+ HoverHandler { cursorShape: Qt.PointingHandCursor }
+ TapHandler {
+ onTapped: {
+ if (page >= 0)
+ image.currentFrame = page
+ else
+ Qt.openUrlExternally(url)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Label {
+ anchors { bottom: parent.bottom; right: parent.right; margins: 6 }
+ text: "page " + doc.pageLabel(image.currentFrame) + " of " + doc.pageCount
+ }
+}
diff --git a/tests/manual/quick/pdf/gridview.qml b/tests/manual/quick/pdf/gridview.qml
new file mode 100644
index 000000000..773e72388
--- /dev/null
+++ b/tests/manual/quick/pdf/gridview.qml
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Pdf
+
+Window {
+ width: 320
+ height: 440
+ color: "lightgrey"
+ title: doc.source
+ visible: true
+
+ property real cellSize: 150
+
+ PdfDocument {
+ id: doc
+ source: "test.pdf"
+ }
+
+ GridView {
+ id: view
+ anchors.fill: parent
+ anchors.margins: 10
+ model: doc.pageModel
+ cellWidth: cellSize
+ cellHeight: cellSize
+ delegate: Item {
+ required property int index
+ required property string label
+ required property size pointSize
+ width: view.cellWidth
+ height: view.cellHeight
+ Rectangle {
+ id: paper
+ width: image.width
+ height: image.height
+ x: (parent.width - width) / 2
+ y: (parent.height - height - pageNumber.height) / 2
+ PdfPageImage {
+ id: image
+ document: doc
+ currentFrame: index
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ property bool landscape: pointSize.width > pointSize.height
+ width: landscape ? Math.min(view.cellWidth, pointSize.width)
+ : height * pointSize.width / pointSize.height
+ height: landscape ? width * pointSize.height / pointSize.width
+ : Math.min(view.cellHeight - pageNumber.height, pointSize.height)
+ sourceSize.width: width
+ sourceSize.height: height
+ }
+ }
+ Text {
+ id: pageNumber
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "Page " + label
+ }
+ }
+ }
+}
diff --git a/tests/manual/quick/pdf/listview.qml b/tests/manual/quick/pdf/listview.qml
index 361ae7d89..d01be9e86 100644
--- a/tests/manual/quick/pdf/listview.qml
+++ b/tests/manual/quick/pdf/listview.qml
@@ -1,55 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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.14
-import QtQuick.Window 2.14
-import QtQuick.Pdf 5.15
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Pdf
Window {
width: 600
@@ -82,7 +34,7 @@ Window {
}
}
Text {
- text: "Page " + (image.currentFrame + 1)
+ text: "Page " + doc.pageLabel(image.currentFrame)
}
}
}
diff --git a/tests/manual/quick/pdf/multipleDocuments.qml b/tests/manual/quick/pdf/multipleDocuments.qml
new file mode 100644
index 000000000..055808ab6
--- /dev/null
+++ b/tests/manual/quick/pdf/multipleDocuments.qml
@@ -0,0 +1,182 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Layouts
+import QtQuick.Pdf
+import Qt.labs.animation
+
+ApplicationWindow {
+ id: root
+ width: 1280
+ height: 1024
+ color: "transparent"
+ flags: Qt.FramelessWindowHint
+ visibility: Window.FullScreen
+ property string source // for main.cpp
+ property real scaleStep: Math.sqrt(2)
+
+ Component {
+ id: pdfWindow
+
+ PdfPageView {
+ property alias source: document.source
+
+ Rectangle {
+ visible: parent.activeFocus
+ color: "transparent"
+ border.color: "cyan"
+ border.width: 3
+ anchors.fill: parent
+ anchors.margins: -border.width
+ anchors.topMargin: -toolbar.height - border.width
+ }
+
+ ToolBar {
+ id: toolbar
+ width: parent.width
+ y: -height
+ RowLayout {
+ anchors.fill: parent
+ anchors.rightMargin: 6
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.ZoomIn
+ enabled: pageView.sourceSize.width < 10000
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-in.svg"
+ onTriggered: pageView.renderScale *= root.scaleStep
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.ZoomOut
+ enabled: pageView.sourceSize.width > 50
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-out.svg"
+ onTriggered: pageView.renderScale /= root.scaleStep
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+0"
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-original.svg"
+ onTriggered: pageView.resetScale()
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/go-previous-view-page.svg"
+ enabled: pageView.backEnabled
+ onTriggered: pageView.back()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "go back"
+ }
+ SpinBox {
+ id: currentPageSB
+ from: 1
+ to: document.pageCount
+ editable: true
+ value: pageView.currentPage + 1
+ onValueModified: pageView.goToPage(value - 1)
+ Layout.maximumWidth: 60
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/go-next-view-page.svg"
+ enabled: pageView.forwardEnabled
+ onTriggered: pageView.forward()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "go forward"
+ }
+ Text {
+ text: document.title
+ elide: Text.ElideRight
+ Layout.fillWidth: true
+ }
+ DragHandler {
+ target: pageView
+ }
+ TapHandler {
+ onTapped: pageView.z++
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.Close
+ text: "☒"
+ onTriggered: pageView.destroy()
+ }
+ }
+ }
+ }
+
+ id: pageView
+ document: PdfDocument {
+ id: document
+ source: Qt.resolvedUrl(root.source)
+ onStatusChanged: (status) => { if (status === PdfDocument.Error) errorDialog.open() }
+ }
+
+ DragHandler {
+ acceptedButtons: Qt.MiddleButton
+ }
+ DragHandler {
+ acceptedDevices: PointerDevice.TouchScreen
+ }
+ HoverHandler {
+ onHoveredChanged: if (hovered) pageView.forceActiveFocus()
+ }
+
+ Dialog {
+ id: errorDialog
+ title: "Error loading " + document.source
+ standardButtons: Dialog.Ok
+ modal: true
+ closePolicy: Popup.CloseOnEscape
+ anchors.centerIn: parent
+ width: 300
+
+ Label {
+ id: errorField
+ text: document.error
+ }
+ }
+ }
+ }
+
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ onActivated: root.activeFocusItem.goToPage(root.activeFocusItem.currentPage - 1)
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ onActivated: root.activeFocusItem.goToPage(root.activeFocusItem.currentPage + 1)
+ }
+ Shortcut {
+ sequence: StandardKey.Open
+ onActivated: fileDialog.open()
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+
+ function open(src) {
+ var win = pdfWindow.createObject(root, { source: src, y: 50 })
+ }
+
+ Component.onCompleted: {
+ if (Application.arguments.length > 2)
+ root.open(Application.arguments[Application.arguments.length - 1])
+ }
+
+ FileDialog {
+ id: fileDialog
+ title: "Open a PDF file"
+ nameFilters: [ "PDF files (*.pdf)" ]
+ onAccepted: root.open(selectedFile)
+ }
+}
diff --git a/tests/manual/quick/pdf/pdfPageView.qml b/tests/manual/quick/pdf/pdfPageView.qml
new file mode 100644
index 000000000..22c0d5ac2
--- /dev/null
+++ b/tests/manual/quick/pdf/pdfPageView.qml
@@ -0,0 +1,316 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Layouts
+import QtQuick.Pdf
+import Qt.labs.animation
+
+ApplicationWindow {
+ id: root
+ width: 800
+ height: 1024
+ color: "lightgrey"
+ title: document.title
+ visible: true
+ property string source // for main.cpp
+ property real scaleStep: Math.sqrt(2)
+
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+ anchors.rightMargin: 6
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.Open
+ icon.source: "../../../../examples/pdf/singlepage/resources/document-open.svg"
+ onTriggered: fileDialog.open()
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.ZoomIn
+ enabled: pageView.sourceSize.width < 10000
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-in.svg"
+ onTriggered: pageView.renderScale *= root.scaleStep
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.ZoomOut
+ enabled: pageView.sourceSize.width > 50
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-out.svg"
+ onTriggered: pageView.renderScale /= root.scaleStep
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-fit-width.svg"
+ onTriggered: pageView.scaleToWidth(root.contentItem.width, root.contentItem.height)
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-fit-best.svg"
+ onTriggered: pageView.scaleToPage(root.contentItem.width, root.contentItem.height)
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+0"
+ icon.source: "../../../../examples/pdf/singlepage/resources/zoom-original.svg"
+ onTriggered: pageView.resetScale()
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+L"
+ icon.source: "../../../../examples/pdf/singlepage/resources/rotate-left.svg"
+ onTriggered: pageView.rotation -= 90
+ }
+ }
+ ToolButton {
+ action: Action {
+ shortcut: "Ctrl+R"
+ icon.source: "../../../../examples/pdf/singlepage/resources/rotate-right.svg"
+ onTriggered: pageView.rotation += 90
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/go-previous-view-page.svg"
+ enabled: pageView.backEnabled
+ onTriggered: pageView.back()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "go back"
+ }
+ SpinBox {
+ id: currentPageSB
+ from: 0
+ to: document.pageCount
+ editable: true
+ value: pageView.currentPage
+ onValueModified: pageView.goToPage(value)
+
+ textFromValue: function(value) { return document.pageLabel(value) }
+ valueFromText: function(text) {
+ for (var i = 0; i < document.pageCount; ++i) {
+ if (document.pageLabel(i).toLowerCase().indexOf(text.toLowerCase()) === 0)
+ return i
+ }
+ return spinBox.value
+ }
+
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ onActivated: pageView.goToPage(currentPageSB.value - 1)
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ onActivated: pageView.goToPage(currentPageSB.value + 1)
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf//resources/go-next-view-page.svg"
+ enabled: pageView.forwardEnabled
+ onTriggered: pageView.forward()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "go forward"
+ }
+ ToolButton {
+ action: Action {
+ shortcut: StandardKey.Copy
+ icon.source: "../../../../examples/pdf/singlepage/resources/edit-copy.svg"
+ enabled: pageView.selectedText !== ""
+ onTriggered: pageView.copySelectionToClipboard()
+ }
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+ }
+ }
+
+ FileDialog {
+ id: fileDialog
+ title: "Open a PDF file"
+ nameFilters: [ "PDF files (*.pdf)" ]
+ onAccepted: document.source = selectedFile
+ }
+
+ Component.onCompleted: {
+ if (Application.arguments.length > 2)
+ document.source = Application.arguments[Application.arguments.length - 1]
+ }
+
+ Dialog {
+ id: errorDialog
+ title: "Error loading " + document.source
+ standardButtons: Dialog.Ok
+ modal: true
+ closePolicy: Popup.CloseOnEscape
+ anchors.centerIn: parent
+ width: 300
+
+ Label {
+ id: errorField
+ text: document.error
+ }
+ }
+
+ PdfPageView {
+ id: pageView
+ x: searchDrawer.position * searchDrawer.width // TODO binding gets broken during centering
+ document: PdfDocument {
+ id: document
+ source: Qt.resolvedUrl(root.source)
+ onStatusChanged: (status) => { if (status === PdfDocument.Error) errorDialog.open() }
+ }
+ searchString: searchField.text
+ onRenderScaleChanged: pageView.returnToBounds()
+
+ DragHandler {
+ acceptedButtons: Qt.MiddleButton
+ onActiveChanged: if (!active) pageView.returnToBounds()
+ }
+ DragHandler {
+ acceptedDevices: PointerDevice.TouchScreen
+ onActiveChanged: if (!active) pageView.returnToBounds()
+ }
+
+ BoundaryRule on x {
+ id: brx
+ minimumOvershoot: 100
+ maximumOvershoot: 100
+ minimum: Math.min(0, root.width - pageView.width)
+ maximum: 0
+ }
+
+ BoundaryRule on y {
+ id: bry
+ minimumOvershoot: 100
+ maximumOvershoot: 100
+ minimum: Math.min(0, root.height - pageView.height)
+ maximum: 0
+ }
+
+ function returnToBounds() {
+ bry.returnToBounds()
+ brx.returnToBounds()
+ }
+ }
+
+ WheelHandler {
+ target: pageView
+ property: "x"
+ orientation: Qt.Horizontal
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
+ acceptedModifiers: Qt.NoModifier
+ onActiveChanged: if (!active) brx.returnToBounds()
+ }
+ WheelHandler {
+ target: pageView
+ property: "y"
+ orientation: Qt.Vertical
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
+ acceptedModifiers: Qt.NoModifier
+ onActiveChanged: if (!active) bry.returnToBounds()
+ }
+
+ Drawer {
+ id: searchDrawer
+ edge: Qt.LeftEdge
+ modal: false
+ width: searchLayout.implicitWidth
+ y: root.header.height
+ height: root.contentItem.height
+ dim: false
+ Shortcut {
+ sequence: StandardKey.Find
+ onActivated: {
+ searchDrawer.open()
+ searchField.forceActiveFocus()
+ }
+ }
+ ColumnLayout {
+ id: searchLayout
+ anchors.fill: parent
+ anchors.margins: 2
+ RowLayout {
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/go-up-search.svg"
+ shortcut: StandardKey.FindPrevious
+ onTriggered: pageView.searchBack()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "find previous"
+ }
+ TextField {
+ id: searchField
+ placeholderText: "search"
+ Layout.minimumWidth: 200
+ Layout.fillWidth: true
+ Image {
+ visible: searchField.text !== ""
+ source: "../../../../examples/pdf/singlepage/resources/edit-clear.svg"
+ anchors {
+ right: parent.right
+ top: parent.top
+ bottom: parent.bottom
+ margins: 3
+ rightMargin: 5
+ }
+ TapHandler {
+ onTapped: searchField.clear()
+ }
+ }
+ }
+ ToolButton {
+ action: Action {
+ icon.source: "../../../../examples/pdf/singlepage/resources/go-down-search.svg"
+ shortcut: StandardKey.FindNext
+ onTriggered: pageView.searchForward()
+ }
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 2000
+ ToolTip.text: "find next"
+ }
+ }
+ ListView {
+ id: searchResultsList
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ clip: true
+ model: pageView.searchModel
+ ScrollBar.vertical: ScrollBar { }
+ delegate: ItemDelegate {
+ width: parent ? parent.width : 0
+ text: "page " + document.pageLabel(page) + ": " + contextBefore + pageView.searchString + contextAfter
+ highlighted: ListView.isCurrentItem
+ onClicked: {
+ searchResultsList.currentIndex = index
+ pageView.goToLocation(page, location, 0)
+ pageView.searchModel.currentResult = indexOnPage
+ }
+ }
+ }
+ }
+ }
+
+ footer: Label {
+ property size implicitPointSize: document.pagePointSize(pageView.currentPage)
+ text: "page " + (pageView.currentPage + 1) + " of " + document.pageCount +
+ " scale " + pageView.renderScale.toFixed(2) +
+ " original " + implicitPointSize.width.toFixed(1) + "x" + implicitPointSize.height.toFixed(1) + "pts"
+ visible: document.status === PdfDocument.Ready
+ }
+}
diff --git a/tests/manual/quick/pdf/pessimizedListView.qml b/tests/manual/quick/pdf/pessimizedListView.qml
index 4ae0edabe..1b514668e 100644
--- a/tests/manual/quick/pdf/pessimizedListView.qml
+++ b/tests/manual/quick/pdf/pessimizedListView.qml
@@ -1,57 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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.14
-import QtQuick.Controls 2.14
-import QtQuick.Layouts 1.14
-import QtQuick.Pdf 5.15
-import Qt.labs.platform 1.1 as P
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Layouts
+import QtQuick.Pdf
ApplicationWindow {
width: 900
@@ -127,11 +80,11 @@ ApplicationWindow {
source: "test.pdf"
}
- P.FileDialog {
+ FileDialog {
id: fileDialog
title: "Open a PDF file"
nameFilters: [ "PDF files (*.pdf)" ]
- onAccepted: doc.source = file
+ onAccepted: doc.source = selectedFile
}
ListView {
@@ -150,15 +103,15 @@ ApplicationWindow {
anchors.centerIn: parent
running: image.status === Image.Loading
}
- Image {
+ PdfPageImage {
id: image
+ document: doc
scale: imageScale
anchors.centerIn: parent
sourceSize.width: doc.pagePointSize(index).width * oversamplingSB.value
height: 100
fillMode: Image.PreserveAspectFit
objectName: "PDF page " + index
- source: doc.source
currentFrame: index
asynchronous: asyncCB.checked
cache: cacheCB.checked
diff --git a/tests/manual/quick/pdf/simplest.qml b/tests/manual/quick/pdf/simplest.qml
index 0571493af..3f39bb213 100644
--- a/tests/manual/quick/pdf/simplest.qml
+++ b/tests/manual/quick/pdf/simplest.qml
@@ -1,53 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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.14
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
Image {
id: image
diff --git a/tests/manual/quick/pdf/test.pdf b/tests/manual/quick/pdf/test.pdf
index a9dc1bc29..0832dfbed 100644
--- a/tests/manual/quick/pdf/test.pdf
+++ b/tests/manual/quick/pdf/test.pdf
Binary files differ
diff --git a/tests/manual/quick/pdf/underscoredLinks.qml b/tests/manual/quick/pdf/underscoredLinks.qml
new file mode 100644
index 000000000..514008ca2
--- /dev/null
+++ b/tests/manual/quick/pdf/underscoredLinks.qml
@@ -0,0 +1,146 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Pdf
+import QtQuick.Shapes
+
+ApplicationWindow {
+ id: root
+ width: 800
+ height: 940
+ color: "darkgrey"
+ title: doc.source
+ visible: true
+
+ property PdfDocument doc: PdfDocument { source: "test.pdf" }
+
+ Component.onCompleted: {
+ if (Application.arguments.length > 2)
+ doc.source = Application.arguments[Application.arguments.length - 1]
+ }
+ FileDialog {
+ id: fileDialog
+ title: "Open a PDF file"
+ nameFilters: [ "PDF files (*.pdf)" ]
+ onAccepted: doc.source = selectedFile
+ }
+ ScrollView {
+ anchors.fill: parent
+ contentWidth: paper.width
+ contentHeight: paper.height
+
+ Rectangle {
+ id: paper
+ width: image.width
+ height: image.height
+ PdfPageImage {
+ id: image
+ document: doc
+
+ property real zoomFactor: Math.sqrt(2)
+
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ enabled: image.currentFrame < image.frameCount - 1
+ onActivated: image.currentFrame++
+ }
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ enabled: image.currentFrame > 0
+ onActivated: image.currentFrame--
+ }
+ Shortcut {
+ sequence: StandardKey.ZoomIn
+ enabled: image.sourceSize.width < 5000
+ onActivated: {
+ image.sourceSize.width = image.implicitWidth * image.zoomFactor
+ image.sourceSize.height = image.implicitHeight * image.zoomFactor
+ }
+ }
+ Shortcut {
+ sequence: StandardKey.ZoomOut
+ enabled: image.width > 50
+ onActivated: {
+ image.sourceSize.width = image.implicitWidth / image.zoomFactor
+ image.sourceSize.height = image.implicitHeight / image.zoomFactor
+ }
+ }
+ Shortcut {
+ sequence: "Ctrl+0"
+ onActivated: image.sourceSize = undefined
+ }
+ Shortcut {
+ sequence: StandardKey.Open
+ onActivated: fileDialog.open()
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+ }
+
+ Menu {
+ id: linkContextMenu
+ property var currentLink
+ MenuItem {
+ text: "Go"
+ onTriggered: {
+ if (linkContextMenu.currentLink.page >= 0)
+ image.currentFrame = linkContextMenu.currentLink.page
+ else
+ Qt.openUrlExternally(linkContextMenu.currentLink.url)
+ }
+ }
+ MenuItem {
+ text: "Copy"
+ onTriggered: linkContextMenu.currentLink.copyToClipboard()
+ }
+ }
+
+ Repeater {
+ model: PdfLinkModel {
+ id: linkModel
+ document: doc
+ page: image.currentFrame
+ }
+ delegate: PdfLinkDelegate {
+ x: rectangle.x
+ y: rectangle.y
+ width: rectangle.width
+ height: rectangle.height
+ onTapped:
+ (link) => {
+ if (link.page >= 0)
+ image.currentFrame = link.page
+ else
+ Qt.openUrlExternally(url)
+ }
+ onContextMenuRequested:
+ (link) => {
+ linkContextMenu.currentLink = link
+ linkContextMenu.x = x
+ linkContextMenu.y = y
+ linkContextMenu.open()
+ }
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ strokeWidth: 1
+ strokeColor: palette.link
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 0; startY: height
+ PathLine { x: width; y: height }
+ }
+ }
+ }
+ }
+ }
+ }
+ Label {
+ anchors { bottom: parent.bottom; right: parent.right; margins: 6 }
+ text: "page " + (image.currentFrame + 1) + " of " + doc.pageCount
+ }
+}
diff --git a/tests/manual/quick/pdf/withdoc.qml b/tests/manual/quick/pdf/withdoc.qml
index 2d82a6abf..d4bf12e29 100644
--- a/tests/manual/quick/pdf/withdoc.qml
+++ b/tests/manual/quick/pdf/withdoc.qml
@@ -1,58 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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.14
-import QtQuick.Controls 2.14
-import Qt.labs.platform 1.1 as Platform
-import QtQuick.Pdf 5.15
-import QtQuick.Shapes 1.14
-import QtQuick.Window 2.14
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Pdf
+import QtQuick.Shapes
Window {
width: 800
@@ -64,21 +16,42 @@ Window {
PdfDocument {
id: doc
source: "test.pdf"
+ onPasswordRequired: function() { passwordDialog.open() }
}
- Platform.FileDialog {
+ FileDialog {
id: fileDialog
title: "Open a PDF file"
nameFilters: [ "PDF files (*.pdf)" ]
- onAccepted: doc.source = file
+ onAccepted: doc.source = selectedFile
+ }
+
+ Dialog {
+ id: passwordDialog
+ title: "Password"
+ standardButtons: Dialog.Ok | Dialog.Cancel
+ modal: true
+ closePolicy: Popup.CloseOnEscape
+ anchors.centerIn: parent
+ width: 300
+
+ contentItem: TextField {
+ id: passwordField
+ placeholderText: qsTr("Please provide the password")
+ echoMode: TextInput.Password
+ width: parent.width
+ onAccepted: passwordDialog.accept()
+ }
+ onOpened: function() { passwordField.forceActiveFocus() }
+ onAccepted: doc.password = passwordField.text
}
PdfSelection {
id: selection
document: doc
page: image.currentFrame
- fromPoint: dragHandler.centroid.pressPosition
- toPoint: dragHandler.centroid.position
+ from: dragHandler.centroid.pressPosition
+ to: dragHandler.centroid.position
hold: !dragHandler.active
}
@@ -109,9 +82,9 @@ Window {
id: paper
width: image.width
height: image.height
- Image {
+ PdfPageImage {
id: image
- source: doc.status === PdfDocument.Ready ? doc.source : ""
+ document: doc
property real zoomFactor: Math.sqrt(2)
@@ -185,7 +158,7 @@ Window {
y: rect.y
width: rect.width
height: rect.height
-// HoverHandler { cursorShape: Qt.PointingHandCursor } // 5.15 onward (QTBUG-68073)
+ HoverHandler { cursorShape: Qt.PointingHandCursor }
TapHandler {
onTapped: {
if (page >= 0)
@@ -201,6 +174,6 @@ Window {
}
Text {
anchors.bottom: parent.bottom
- text: "page " + (image.currentFrame + 1) + " of " + doc.pageCount
+ text: "page " + (image.currentFrame + 1) + " of " + doc.pageCount + " label: " + doc.pageLabel(image.currentFrame)
}
}
diff --git a/tests/manual/quick/quick.pro b/tests/manual/quick/quick.pro
deleted file mode 100644
index 8522763f8..000000000
--- a/tests/manual/quick/quick.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += \
- faviconbrowser \
- touchbrowser
diff --git a/tests/manual/quick/touchbrowser/AddressBar.qml b/tests/manual/quick/touchbrowser/AddressBar.qml
index 1daae6dbf..42188c94e 100644
--- a/tests/manual/quick/touchbrowser/AddressBar.qml
+++ b/tests/manual/quick/touchbrowser/AddressBar.qml
@@ -1,34 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.5
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Controls
Rectangle {
id: root
@@ -59,6 +33,14 @@ Rectangle {
TextField {
id: addressField
anchors.fill: parent
+ leftPadding: 30
+
+ background: Rectangle {
+ color: "transparent"
+ border.color: "black"
+ border.width: 1
+ radius: root.radius
+ }
Image {
anchors.verticalCenter: addressField.verticalCenter
@@ -78,17 +60,6 @@ Rectangle {
visible: root.progress < 100
}
- style: TextFieldStyle {
- padding.left: 30
-
- background: Rectangle {
- color: "transparent"
- border.color: "black"
- border.width: 1
- radius: root.radius
- }
- }
-
onActiveFocusChanged: {
if (activeFocus)
selectAll();
diff --git a/tests/manual/quick/touchbrowser/CMakeLists.txt b/tests/manual/quick/touchbrowser/CMakeLists.txt
new file mode 100644
index 000000000..0d3275e58
--- /dev/null
+++ b/tests/manual/quick/touchbrowser/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.19)
+ project(touchbrowser LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+set(CMAKE_AUTORCC ON)
+set(TOUCHMOCKING_DIR "../../touchmocking")
+
+include_directories(${TOUCHMOCKING_DIR})
+add_definitions(-DQUICK_TOUCHBROWSER)
+
+qt_internal_add_manual_test(touchbrowser-quick
+ GUI
+ SOURCES
+ main.cpp
+ resources.qrc
+ ${TOUCHMOCKING_DIR}/touchmockingapplication.cpp
+ ${TOUCHMOCKING_DIR}/touchmockingapplication.h
+ ${TOUCHMOCKING_DIR}/utils.h
+ LIBRARIES
+ Qt::Core
+ Qt::Quick
+ Qt::WebEngineQuick
+ ENABLE_AUTOGEN_TOOLS
+ moc
+)
+
diff --git a/tests/manual/quick/touchbrowser/MockTouchPoint.qml b/tests/manual/quick/touchbrowser/MockTouchPoint.qml
new file mode 100644
index 000000000..895e12e70
--- /dev/null
+++ b/tests/manual/quick/touchbrowser/MockTouchPoint.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+import QtQuick
+
+Item {
+ id: mockTouchPoint
+
+ property bool pressed: false
+ property int pointId: 0
+
+ Image {
+ source: "qrc:/touchpoint.png"
+ x: -(width / 2)
+ y: -(height / 2)
+ opacity: mockTouchPoint.pressed ? 0.6 : 0.0
+
+ Behavior on opacity {
+ NumberAnimation { duration: 200 }
+ }
+
+ Text {
+ text: mockTouchPoint.pointId
+ anchors.centerIn: parent
+ }
+ }
+}
diff --git a/tests/manual/quick/touchbrowser/main.cpp b/tests/manual/quick/touchbrowser/main.cpp
index ffbe81179..1f4d7d869 100644
--- a/tests/manual/quick/touchbrowser/main.cpp
+++ b/tests/manual/quick/touchbrowser/main.cpp
@@ -1,48 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#if defined(DESKTOP_BUILD)
#include "touchmockingapplication.h"
-#endif
#include "utils.h"
-#include <QtGui/QGuiApplication>
-#include <QtQml/QQmlApplicationEngine>
-#include <QtQml/QQmlContext>
-#include <QtQuick/QQuickView>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QQuickView>
+#include <QtWebEngineQuick>
static QUrl startupUrl()
{
QUrl ret;
QStringList args(qApp->arguments());
args.takeFirst();
- for (const QString &arg : qAsConst(args)) {
+ for (const QString &arg : std::as_const(args)) {
if (arg.startsWith(QLatin1Char('-')))
continue;
ret = Utils::fromUserInput(arg);
@@ -54,31 +27,10 @@ static QUrl startupUrl()
int main(int argc, char **argv)
{
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
-
- // We use touch mocking on desktop and apply all the mobile switches.
- QByteArrayList args = QByteArrayList()
- << QByteArrayLiteral("--enable-embedded-switches")
- << QByteArrayLiteral("--log-level=0");
- const int count = args.size() + argc;
- QList<char*> qargv(count);
-
- qargv[0] = argv[0];
- for (int i = 0; i < args.size(); ++i)
- qargv[i + 1] = args[i].data();
- for (int i = args.size() + 1; i < count; ++i)
- qargv[i] = argv[i - args.size()];
-
- int qAppArgCount = qargv.size();
-
QtWebEngineQuick::initialize();
-#if defined(DESKTOP_BUILD)
- TouchMockingApplication app(qAppArgCount, qargv.data());
-#else
- QGuiApplication app(qAppArgCount, qargv.data());
-#endif
+ TouchMockingApplication app(argc, argv);
+ app.setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
QQuickView view;
Utils utils;
diff --git a/tests/manual/quick/touchbrowser/main.qml b/tests/manual/quick/touchbrowser/main.qml
index 926b3a941..83ede7d75 100644
--- a/tests/manual/quick/touchbrowser/main.qml
+++ b/tests/manual/quick/touchbrowser/main.qml
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-import QtQuick 2.5
-import QtQuick.Layouts 1.3
-import QtWebEngine 1.3
+import QtQuick
+import QtQuick.Layouts
+import QtWebEngine
Item {
function load(url) {
diff --git a/tests/manual/quick/touchbrowser/resources.qrc b/tests/manual/quick/touchbrowser/resources.qrc
new file mode 100644
index 000000000..87d655a27
--- /dev/null
+++ b/tests/manual/quick/touchbrowser/resources.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>AddressBar.qml</file>
+ <file alias="touchpoint.png">../../touchmocking/touchpoint.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/quick/touchbrowser/touchbrowser.pro b/tests/manual/quick/touchbrowser/touchbrowser.pro
index 92e4e6703..710584df8 100644
--- a/tests/manual/quick/touchbrowser/touchbrowser.pro
+++ b/tests/manual/quick/touchbrowser/touchbrowser.pro
@@ -1,19 +1,15 @@
TEMPLATE = app
-QT += quick webenginequick
-CONFIG += c++11
+DEFINES += QUICK_TOUCHBROWSER
+QT += core gui quick webenginequick
-SOURCES += \
- main.cpp
+INCLUDEPATH += ../../touchmocking
+SOURCES += \
+ main.cpp \
+ ../../touchmocking/touchmockingapplication.cpp
HEADERS += \
- utils.h
-
-RESOURCES += qml.qrc
+ ../../touchmocking/touchmockingapplication.h \
+ ../../touchmocking/utils.h
-!cross_compile {
- DEFINES += DESKTOP_BUILD
- SOURCES += touchmockingapplication.cpp
- HEADERS += touchmockingapplication.h
- QT += gui-private
-}
+RESOURCES += resources.qrc
diff --git a/tests/manual/quick/touchbrowser/touchmockingapplication.cpp b/tests/manual/quick/touchbrowser/touchmockingapplication.cpp
deleted file mode 100644
index 41b731a6a..000000000
--- a/tests/manual/quick/touchbrowser/touchmockingapplication.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "touchmockingapplication.h"
-
-#include <qpa/qwindowsysteminterface.h>
-#include <QtCore/QEvent>
-#include <QtGui/QMouseEvent>
-#include <QtGui/QTouchDevice>
-#include <QtGui/QTouchEvent>
-#include <QtQuick/QQuickItem>
-#include <QtQuick/QQuickView>
-
-static inline bool isTouchEvent(const QEvent* event)
-{
- switch (event->type()) {
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- return true;
- default:
- return false;
- }
-}
-
-static inline bool isMouseEvent(const QEvent* event)
-{
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- return true;
- default:
- return false;
- }
-}
-
-TouchMockingApplication::TouchMockingApplication(int& argc, char** argv)
- : QGuiApplication(argc, argv)
- , m_realTouchEventReceived(false)
- , m_pendingFakeTouchEventCount(0)
- , m_holdingControl(false)
-{
-}
-
-bool TouchMockingApplication::notify(QObject* target, QEvent* event)
-{
- // We try to be smart, if we received real touch event, we are probably on a device
- // with touch screen, and we should not have touch mocking.
-
- if (!event->spontaneous() || m_realTouchEventReceived)
- return QGuiApplication::notify(target, event);
-
- if (isTouchEvent(event)) {
- if (m_pendingFakeTouchEventCount)
- --m_pendingFakeTouchEventCount;
- else
- m_realTouchEventReceived = true;
- return QGuiApplication::notify(target, event);
- }
-
- QQuickView* window = qobject_cast<QQuickView*>(target);
- if (!window)
- return QGuiApplication::notify(target, event);
-
- m_holdingControl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
-
- if (event->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(event)->key() == Qt::Key_Control) {
- foreach (int id, m_heldTouchPoints)
- if (m_touchPoints.contains(id) && !QGuiApplication::mouseButtons().testFlag(Qt::MouseButton(id))) {
- m_touchPoints[id].setState(Qt::TouchPointReleased);
- m_heldTouchPoints.remove(id);
- } else
- m_touchPoints[id].setState(Qt::TouchPointStationary);
-
- sendTouchEvent(window, m_heldTouchPoints.isEmpty() ? QEvent::TouchEnd : QEvent::TouchUpdate, static_cast<QKeyEvent*>(event)->timestamp());
- }
-
- if (isMouseEvent(event)) {
- const QMouseEvent* const mouseEvent = static_cast<QMouseEvent*>(event);
-
- QTouchEvent::TouchPoint touchPoint;
- touchPoint.setPressure(1);
-
- QEvent::Type touchType = QEvent::None;
-
- switch (mouseEvent->type()) {
- case QEvent::MouseButtonPress:
- touchPoint.setId(mouseEvent->button());
- if (m_touchPoints.contains(touchPoint.id())) {
- touchPoint.setState(Qt::TouchPointMoved);
- touchType = QEvent::TouchUpdate;
- } else {
- touchPoint.setState(Qt::TouchPointPressed);
- // Check if more buttons are held down than just the event triggering one.
- if (mouseEvent->buttons() > mouseEvent->button())
- touchType = QEvent::TouchUpdate;
- else
- touchType = QEvent::TouchBegin;
- }
- break;
- case QEvent::MouseMove:
- if (!mouseEvent->buttons()) {
- // We have to swallow the event instead of propagating it,
- // since we avoid sending the mouse release events and if the
- // Flickable is the mouse grabber it would receive the event
- // and would move the content.
- event->accept();
- return true;
- }
- touchType = QEvent::TouchUpdate;
- touchPoint.setId(mouseEvent->buttons());
- touchPoint.setState(Qt::TouchPointMoved);
- break;
- case QEvent::MouseButtonRelease:
- // Check if any buttons are still held down after this event.
- if (mouseEvent->buttons())
- touchType = QEvent::TouchUpdate;
- else
- touchType = QEvent::TouchEnd;
- touchPoint.setId(mouseEvent->button());
- touchPoint.setState(Qt::TouchPointReleased);
- break;
- case QEvent::MouseButtonDblClick:
- // Eat double-clicks, their accompanying press event is all we need.
- event->accept();
- return true;
- default:
- Q_ASSERT_X(false, "multi-touch mocking", "unhandled event type");
- }
-
- // A move can have resulted in multiple buttons, so we need check them individually.
- if (touchPoint.id() & Qt::LeftButton)
- updateTouchPoint(mouseEvent, touchPoint, Qt::LeftButton);
- if (touchPoint.id() & Qt::MiddleButton)
- updateTouchPoint(mouseEvent, touchPoint, Qt::MiddleButton);
- if (touchPoint.id() & Qt::RightButton)
- updateTouchPoint(mouseEvent, touchPoint, Qt::RightButton);
-
- if (m_holdingControl && touchPoint.state() == Qt::TouchPointReleased) {
- // We avoid sending the release event because the Flickable is
- // listening to mouse events and would start a bounce-back
- // animation if it received a mouse release.
- event->accept();
- return true;
- }
-
- // Update states for all other touch-points
- for (QHash<int, QTouchEvent::TouchPoint>::iterator it = m_touchPoints.begin(), end = m_touchPoints.end(); it != end; ++it) {
- if (!(it.value().id() & touchPoint.id()))
- it.value().setState(Qt::TouchPointStationary);
- }
-
- Q_ASSERT(touchType != QEvent::None);
-
- if (!sendTouchEvent(window, touchType, mouseEvent->timestamp()))
- return QGuiApplication::notify(target, event);
-
- event->accept();
- return true;
- }
-
- return QGuiApplication::notify(target, event);
-}
-
-void TouchMockingApplication::updateTouchPoint(const QMouseEvent* mouseEvent, QTouchEvent::TouchPoint touchPoint, Qt::MouseButton mouseButton)
-{
- // Ignore inserting additional touch points if Ctrl isn't held because it produces
- // inconsistent touch events and results in assers in the gesture recognizers.
- if (!m_holdingControl && m_touchPoints.size() && !m_touchPoints.contains(mouseButton))
- return;
-
- if (m_holdingControl && touchPoint.state() == Qt::TouchPointReleased) {
- m_heldTouchPoints.insert(mouseButton);
- return;
- }
-
- // Gesture recognition uses the screen position for the initial threshold
- // but since the canvas translates touch events we actually need to pass
- // the screen position as the scene position to deliver the appropriate
- // coordinates to the target.
- touchPoint.setPos(mouseEvent->localPos());
- touchPoint.setScenePos(mouseEvent->screenPos());
-
- if (touchPoint.state() == Qt::TouchPointPressed)
- touchPoint.setStartScenePos(mouseEvent->screenPos());
- else {
- const QTouchEvent::TouchPoint& oldTouchPoint = m_touchPoints[mouseButton];
- touchPoint.setStartScenePos(oldTouchPoint.startScenePos());
- touchPoint.setLastPos(oldTouchPoint.pos());
- touchPoint.setLastScenePos(oldTouchPoint.scenePos());
- }
-
- // Update current touch-point.
- touchPoint.setId(mouseButton);
- m_touchPoints.insert(mouseButton, touchPoint);
-}
-
-bool TouchMockingApplication::sendTouchEvent(QQuickView* window, QEvent::Type type, ulong timestamp)
-{
- static QTouchDevice* device = 0;
- if (!device) {
- device = new QTouchDevice;
- device->setType(QTouchDevice::TouchScreen);
- QWindowSystemInterface::registerTouchDevice(device);
- }
-
- m_pendingFakeTouchEventCount++;
-
- const QList<QTouchEvent::TouchPoint>& currentTouchPoints = m_touchPoints.values();
- Qt::TouchPointStates touchPointStates = Qt::TouchPointState();
- foreach (const QTouchEvent::TouchPoint& touchPoint, currentTouchPoints)
- touchPointStates |= touchPoint.state();
-
- QTouchEvent event(type, device, Qt::NoModifier, touchPointStates, currentTouchPoints);
- event.setTimestamp(timestamp);
- event.setAccepted(false);
-
- QGuiApplication::notify(window, &event);
-
- updateVisualMockTouchPoints(window,m_holdingControl ? currentTouchPoints : QList<QTouchEvent::TouchPoint>());
-
- // Get rid of touch-points that are no longer valid
- foreach (const QTouchEvent::TouchPoint& touchPoint, currentTouchPoints) {
- if (touchPoint.state() == Qt::TouchPointReleased)
- m_touchPoints.remove(touchPoint.id());
- }
-
- return event.isAccepted();
-}
-
-void TouchMockingApplication::updateVisualMockTouchPoints(QQuickView* window,const QList<QTouchEvent::TouchPoint>& touchPoints)
-{
- if (touchPoints.isEmpty()) {
- // Hide all touch indicator items.
- foreach (QQuickItem* item, m_activeMockComponents.values())
- item->setProperty("pressed", false);
-
- return;
- }
-
- foreach (const QTouchEvent::TouchPoint& touchPoint, touchPoints) {
- QQuickItem* mockTouchPointItem = m_activeMockComponents.value(touchPoint.id());
-
- if (!mockTouchPointItem) {
- QQmlComponent touchMockPointComponent(window->engine(), QUrl("qrc:///qml/MockTouchPoint.qml"));
- mockTouchPointItem = qobject_cast<QQuickItem*>(touchMockPointComponent.create());
- Q_ASSERT(mockTouchPointItem);
- m_activeMockComponents.insert(touchPoint.id(), mockTouchPointItem);
- mockTouchPointItem->setProperty("pointId", QVariant(touchPoint.id()));
- mockTouchPointItem->setParent(window->rootObject());
- mockTouchPointItem->setParentItem(window->rootObject());
- }
-
- mockTouchPointItem->setX(touchPoint.pos().x());
- mockTouchPointItem->setY(touchPoint.pos().y());
- mockTouchPointItem->setWidth(touchPoint.ellipseDiameters().width());
- mockTouchPointItem->setHeight(touchPoint.ellipseDiameters().height());
- mockTouchPointItem->setProperty("pressed", QVariant(touchPoint.state() != Qt::TouchPointReleased));
- }
-}
diff --git a/tests/manual/quick/touchbrowser/touchmockingapplication.h b/tests/manual/quick/touchbrowser/touchmockingapplication.h
deleted file mode 100644
index cdabe871f..000000000
--- a/tests/manual/quick/touchbrowser/touchmockingapplication.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef TOUCHMOCKINGAPPLICATION_H
-#define TOUCHMOCKINGAPPLICATION_H
-
-#include <QtCore/QHash>
-#include <QtCore/QSet>
-#include <QtCore/QUrl>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QTouchEvent>
-
-QT_BEGIN_NAMESPACE
-class QQuickView;
-class QQuickItem;
-QT_END_NAMESPACE
-
-class TouchMockingApplication : public QGuiApplication
-{
- Q_OBJECT
-
-public:
- TouchMockingApplication(int &argc, char **argv);
-
- virtual bool notify(QObject *, QEvent *) override;
-
-private:
- void updateTouchPoint(const QMouseEvent *, QTouchEvent::TouchPoint, Qt::MouseButton);
- bool sendTouchEvent(QQuickView *, QEvent::Type, ulong timestamp);
- void updateVisualMockTouchPoints(QQuickView *,const QList<QTouchEvent::TouchPoint> &touchPoints);
-
-private:
- bool m_realTouchEventReceived;
- int m_pendingFakeTouchEventCount;
-
- QPointF m_lastPos;
- QPointF m_lastScreenPos;
- QPointF m_startScreenPos;
-
- QHash<int, QTouchEvent::TouchPoint> m_touchPoints;
- QSet<int> m_heldTouchPoints;
- QHash<int, QQuickItem*> m_activeMockComponents;
-
- bool m_holdingControl;
-};
-
-#endif // TOUCHMOCKINGAPPLICATION_H
diff --git a/tests/manual/quick/touchbrowser/utils.h b/tests/manual/quick/touchbrowser/utils.h
deleted file mode 100644
index b7aeefce0..000000000
--- a/tests/manual/quick/touchbrowser/utils.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <QtCore/QFileInfo>
-#include <QtCore/QUrl>
-
-class Utils : public QObject {
- Q_OBJECT
-public:
- Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
-};
-
-inline QUrl Utils::fromUserInput(const QString& userInput)
-{
- QFileInfo fileInfo(userInput);
- if (fileInfo.exists())
- return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
- return QUrl::fromUserInput(userInput);
-}
-
-#endif // UTILS_H
diff --git a/tests/manual/touchmocking/touchmockingapplication.cpp b/tests/manual/touchmocking/touchmockingapplication.cpp
new file mode 100644
index 000000000..feedae5cd
--- /dev/null
+++ b/tests/manual/touchmocking/touchmockingapplication.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "touchmockingapplication.h"
+
+#include <QCursor>
+#include <QEvent>
+#include <QPixmap>
+
+#if defined(QUICK_TOUCHBROWSER)
+# include <QQuickView>
+#endif
+
+#if defined(WIDGET_TOUCHBROWSER)
+# include <QMainWindow>
+#endif
+
+static inline bool isMouseEvent(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ return true;
+ default:
+ return false;
+ }
+}
+
+TouchMockingApplication::TouchMockingApplication(int &argc, char **argv)
+ : Application(argc, argv), m_touchPoint(new QCursor(QPixmap(":touchpoint.png")))
+{
+}
+
+TouchMockingApplication::~TouchMockingApplication()
+{
+ delete m_touchPoint;
+}
+
+bool TouchMockingApplication::notify(QObject *target, QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ setOverrideCursor(*m_touchPoint);
+ break;
+ case QEvent::TouchEnd:
+ restoreCursor();
+ break;
+ default:
+ break;
+ }
+
+// All mouse events that are not accepted by the application will be translated to touch events
+// instead (see Qt::AA_SynthesizeTouchForUnhandledMouseEvents).
+#if defined(QUICK_TOUCHBROWSER)
+ if (isMouseEvent(event) && qobject_cast<QQuickView *>(target)) {
+ event->ignore();
+ return false;
+ }
+#elif defined(WIDGET_TOUCHBROWSER)
+ // Popups ignore touch evenets so we send MouseEvents directly.
+ if (isMouseEvent(event)) {
+ if (activePopupWidget()) {
+ restoreCursor();
+ } else {
+ event->ignore();
+ return false;
+ }
+ }
+#endif
+ return Application::notify(target, event);
+}
+
+void TouchMockingApplication::restoreCursor()
+{
+ while (overrideCursor())
+ restoreOverrideCursor();
+}
diff --git a/tests/manual/touchmocking/touchmockingapplication.h b/tests/manual/touchmocking/touchmockingapplication.h
new file mode 100644
index 000000000..4f6e744fc
--- /dev/null
+++ b/tests/manual/touchmocking/touchmockingapplication.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef TOUCHMOCKINGAPPLICATION_H
+#define TOUCHMOCKINGAPPLICATION_H
+
+#if defined(QUICK_TOUCHBROWSER)
+# include <QGuiApplication>
+using Application = QGuiApplication;
+#elif defined(WIDGET_TOUCHBROWSER)
+# include <QApplication>
+using Application = QApplication;
+#endif
+
+QT_BEGIN_NAMESPACE
+class QCursor;
+QT_END_NAMESPACE
+
+class TouchMockingApplication : public Application
+{
+ Q_OBJECT
+
+public:
+ TouchMockingApplication(int &argc, char **argv);
+ ~TouchMockingApplication();
+
+ virtual bool notify(QObject *, QEvent *) override;
+
+private:
+ void restoreCursor();
+
+ QCursor *m_touchPoint;
+};
+
+#endif // TOUCHMOCKINGAPPLICATION_H
diff --git a/tests/manual/touchmocking/touchpoint.png b/tests/manual/touchmocking/touchpoint.png
new file mode 100644
index 000000000..7649ee991
--- /dev/null
+++ b/tests/manual/touchmocking/touchpoint.png
Binary files differ
diff --git a/tests/manual/touchmocking/utils.h b/tests/manual/touchmocking/utils.h
new file mode 100644
index 000000000..12d493d3f
--- /dev/null
+++ b/tests/manual/touchmocking/utils.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QFileInfo>
+#include <QUrl>
+
+class Utils : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE static QUrl fromUserInput(const QString &userInput);
+};
+
+inline QUrl Utils::fromUserInput(const QString &userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+#endif // UTILS_H
diff --git a/tests/manual/widgets/CMakeLists.txt b/tests/manual/widgets/CMakeLists.txt
new file mode 100644
index 000000000..7c19f9e43
--- /dev/null
+++ b/tests/manual/widgets/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_subdirectory(inputmethods)
+add_subdirectory(geolocation)
+add_subdirectory(touchbrowser)
+if(QT_FEATURE_opengl)
+ add_subdirectory(webgl)
+endif()
+if(TARGET Qt6::HttpServer)
+ add_subdirectory(webrtc)
+endif()
diff --git a/tests/manual/widgets/geolocation/CMakeLists.txt b/tests/manual/widgets/geolocation/CMakeLists.txt
new file mode 100644
index 000000000..2ca8c2f52
--- /dev/null
+++ b/tests/manual/widgets/geolocation/CMakeLists.txt
@@ -0,0 +1,55 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(geolocation LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(geolocation
+ GUI
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Test
+ Qt::WebEngineWidgets
+ ENABLE_AUTOGEN_TOOLS
+ moc
+)
+
+set_target_properties(geolocation PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+ MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.dev.webenginewidgets.geolocation"
+)
+
+set(geolocation_resource_files
+ "geolocation.html"
+)
+
+qt_add_resources(geolocation "geolocation"
+ PREFIX
+ "/"
+ FILES
+ ${geolocation_resource_files}
+)
+
+ foreach(permission_plugin IN LISTS QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_permissions)
+ set(permission_plugin "${QT_CMAKE_EXPORT_NAMESPACE}::${permission_plugin}")
+ qt6_import_plugins(geolocation INCLUDE ${permission_plugin})
+ endforeach()
+
+if (APPLE)
+ set_target_properties(geolocation PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist"
+ )
+
+ if (NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ # Need to sign application for location permissions to work
+ add_custom_command(TARGET geolocation
+ POST_BUILD COMMAND codesign -s - geolocation.app)
+ endif()
+endif()
diff --git a/tests/manual/widgets/geolocation/Info.plist b/tests/manual/widgets/geolocation/Info.plist
new file mode 100644
index 000000000..9853e1900
--- /dev/null
+++ b/tests/manual/widgets/geolocation/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>NSLocationUsageDescription</key>
+ <string>Geolocation test would like to give web sites access to your location for demo purposes.</string>
+</dict>
+</plist>
diff --git a/tests/manual/widgets/geolocation/geolocation.html b/tests/manual/widgets/geolocation/geolocation.html
new file mode 100644
index 000000000..e8c54bc58
--- /dev/null
+++ b/tests/manual/widgets/geolocation/geolocation.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<title>Geolocation Permission API Test</title>
+<script>
+
+var errorMessage;
+var handled = false;
+
+function successHandler(location) {
+ var message = document.getElementById("message");
+ message.innerHTML = "Latitude: " + location.coords.latitude +
+ "<br>Longitude: " + location.coords.longitude;
+
+ errorMessage = "";
+ handled = true;
+}
+
+function errorHandler(error) {
+ errorMessage = error.message;
+ handled = true;
+}
+
+<!-- One shot example -->
+navigator.geolocation.getCurrentPosition(successHandler, errorHandler);
+
+</script>
+</head>
+<body>
+<div id="message">Location unknown</div>
+</body>
+</html>
+
diff --git a/tests/manual/widgets/geolocation/main.cpp b/tests/manual/widgets/geolocation/main.cpp
new file mode 100644
index 000000000..f33cf5798
--- /dev/null
+++ b/tests/manual/widgets/geolocation/main.cpp
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QApplication>
+#include <QFormLayout>
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QMainWindow>
+#include <QMessageBox>
+#include <QVBoxLayout>
+#include <QWebEnginePage>
+#include <QWebEngineView>
+
+class GeoPermissionWebView : public QWebEngineView {
+ Q_OBJECT
+
+public slots:
+ void handleFeaturePermissionRequested(const QUrl &securityOrigin,
+ QWebEnginePage::Feature feature)
+ {
+ qWarning("Feature Permission");
+ QString title = tr("Permission Request");
+ QString question = QLatin1String("Allow access to geolocation?");
+ if (!question.isEmpty() && QMessageBox::question(window(), title, question) == QMessageBox::Yes)
+ page()->setFeaturePermission(securityOrigin, feature,
+ QWebEnginePage::PermissionGrantedByUser);
+ else
+ page()->setFeaturePermission(securityOrigin, feature,
+ QWebEnginePage::PermissionDeniedByUser);
+ }
+
+};
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QMainWindow w;
+ GeoPermissionWebView webview;
+ QWebEnginePage page;
+ QObject::connect(&page, &QWebEnginePage::featurePermissionRequested, &webview,
+ &GeoPermissionWebView::handleFeaturePermissionRequested);
+ webview.setPage(&page);
+ page.load(QUrl("qrc:/geolocation.html"));
+ w.setCentralWidget(&webview);
+ w.show();
+
+ return a.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/inputmethods/CMakeLists.txt b/tests/manual/widgets/inputmethods/CMakeLists.txt
new file mode 100644
index 000000000..acd5bca50
--- /dev/null
+++ b/tests/manual/widgets/inputmethods/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(inputmethods LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(inputmethods
+ GUI
+ SOURCES
+ colorpicker.cpp
+ controlview.cpp
+ main.cpp
+ referenceview.cpp
+ testview.cpp
+ webview.cpp
+ LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::Test
+ Qt::WebEngineWidgets
+ ENABLE_AUTOGEN_TOOLS
+ moc
+)
+
+set(inputmethods_resource_files
+ "testdata.csv"
+)
+
+qt_add_resources(inputmethods "inputmethods"
+ PREFIX
+ "/"
+ FILES
+ ${inputmethods_resource_files}
+)
diff --git a/tests/manual/widgets/inputmethods/colorpicker.cpp b/tests/manual/widgets/inputmethods/colorpicker.cpp
index ee2e2e43f..cc0840bcd 100644
--- a/tests/manual/widgets/inputmethods/colorpicker.cpp
+++ b/tests/manual/widgets/inputmethods/colorpicker.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "colorpicker.h"
diff --git a/tests/manual/widgets/inputmethods/colorpicker.h b/tests/manual/widgets/inputmethods/colorpicker.h
index f5448ad2d..0b6b3257a 100644
--- a/tests/manual/widgets/inputmethods/colorpicker.h
+++ b/tests/manual/widgets/inputmethods/colorpicker.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef COLORPICKER_H
#define COLORPICKER_H
@@ -32,8 +7,10 @@
#include <QColor>
#include <QWidget>
+QT_BEGIN_NAMESPACE
class QLineEdit;
class QPushButton;
+QT_END_NAMESPACE
class ColorPicker : public QWidget
{
diff --git a/tests/manual/widgets/inputmethods/controlview.cpp b/tests/manual/widgets/inputmethods/controlview.cpp
index 4538ced4b..86bf8cca9 100644
--- a/tests/manual/widgets/inputmethods/controlview.cpp
+++ b/tests/manual/widgets/inputmethods/controlview.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "controlview.h"
@@ -69,7 +44,7 @@ ControlView::ControlView(QWidget *parent)
layout->addRow(m_sendEventButton);
setLayout(layout);
- connect(m_sendEventButton, &QPushButton::clicked, this, &ControlView::createAndSendInputMethodEvent);
+ connect(m_sendEventButton, &QPushButton::clicked, this, &ControlView::requestInputMethodEvent);
}
void ControlView::receiveInputMethodData(int start,
@@ -87,7 +62,12 @@ void ControlView::receiveInputMethodData(int start,
m_inputLine->setText(input);
}
-void ControlView::createAndSendInputMethodEvent()
+const QString ControlView::getText() const
+{
+ return m_inputLine->text();
+}
+
+const QList<QInputMethodEvent::Attribute> ControlView::getAtrributes() const
{
int start = m_startSpin->value();
int length = m_lengthSpin->value();
@@ -102,7 +82,6 @@ void ControlView::createAndSendInputMethodEvent()
QList<QInputMethodEvent::Attribute> attrs;
attrs.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format));
- QInputMethodEvent im(m_inputLine->text(), attrs);
- emit sendInputMethodEvent(im);
+ return attrs;
}
diff --git a/tests/manual/widgets/inputmethods/controlview.h b/tests/manual/widgets/inputmethods/controlview.h
index 0ef10f6a8..caa08593f 100644
--- a/tests/manual/widgets/inputmethods/controlview.h
+++ b/tests/manual/widgets/inputmethods/controlview.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CONTROLVIEW_H
#define CONTROLVIEW_H
@@ -33,12 +8,15 @@
#include <QTextCharFormat>
#include <QWidget>
-class ColorPicker;
+QT_BEGIN_NAMESPACE
class QComboBox;
class QLabel;
class QLineEdit;
class QPushButton;
class QSpinBox;
+QT_END_NAMESPACE
+
+class ColorPicker;
class ControlView : public QWidget
{
@@ -46,12 +24,13 @@ class ControlView : public QWidget
public:
explicit ControlView(QWidget *parent = 0);
+ const QString getText() const;
+ const QList<QInputMethodEvent::Attribute> getAtrributes() const;
+
public slots:
void receiveInputMethodData(int, int, QTextCharFormat::UnderlineStyle, const QColor &, const QColor &, const QString &);
- void createAndSendInputMethodEvent();
-
signals:
- void sendInputMethodEvent(QInputMethodEvent);
+ void requestInputMethodEvent();
private:
QComboBox *m_underlineStyleCombo;
diff --git a/tests/manual/widgets/inputmethods/main.cpp b/tests/manual/widgets/inputmethods/main.cpp
index a96deb83a..2378e95ae 100644
--- a/tests/manual/widgets/inputmethods/main.cpp
+++ b/tests/manual/widgets/inputmethods/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QApplication>
#include <QFormLayout>
@@ -49,7 +24,12 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = 0);
+private slots:
+ void sendInputMethodEvents();
+
private:
+ void closeEvent(QCloseEvent *event) override;
+
ControlView *m_controlView;
ReferenceView *m_referenceView;
WebView *m_webView;
@@ -109,29 +89,44 @@ MainWindow::MainWindow(QWidget *parent)
centralLayout->addLayout(leftLayout);
centralLayout->addWidget(m_testView);
- connect(m_testView, &TestView::sendInputMethodData, m_controlView, &ControlView::receiveInputMethodData);
- connect(m_testView, &TestView::requestInputMethodEvent, m_controlView, &ControlView::createAndSendInputMethodEvent);
-
- connect(m_controlView, &ControlView::sendInputMethodEvent, [=](QInputMethodEvent im) {
- bool processed;
- QString resultText;
-
- processed = QApplication::sendEvent(m_referenceView->referenceInput(), &im);
- resultText = processed ? QStringLiteral("<font color='green'>TRUE</font>")
- : QStringLiteral("<font color='red'>FALSE</font>");
- m_referenceProcessed->setText(resultText);
-
- processed = QApplication::sendEvent(m_webView->focusProxy(), &im);
- resultText = processed ? QStringLiteral("<font color='green'>TRUE</font>")
- : QStringLiteral("<font color='red'>FALSE</font>");
- m_webProcessed->setText(resultText);
- });
+ connect(m_testView, &TestView::sendInputMethodData, m_controlView,
+ &ControlView::receiveInputMethodData);
+ connect(m_testView, &TestView::requestInputMethodEvent, this,
+ &MainWindow::sendInputMethodEvents);
+ connect(m_controlView, &ControlView::requestInputMethodEvent, this,
+ &MainWindow::sendInputMethodEvents);
centralWidget->setLayout(centralLayout);
setCentralWidget(centralWidget);
setWindowTitle(tr("Input Methods Format Manual Test"));
}
+void MainWindow::sendInputMethodEvents()
+{
+ bool processed;
+ QString resultText;
+
+ QString text = m_controlView->getText();
+ QList<QInputMethodEvent::Attribute> attrs = m_controlView->getAtrributes();
+ QInputMethodEvent im(text, attrs);
+
+ processed = QApplication::sendEvent(m_referenceView->referenceInput(), &im);
+ resultText = processed ? QStringLiteral("<font color='green'>TRUE</font>")
+ : QStringLiteral("<font color='red'>FALSE</font>");
+ m_referenceProcessed->setText(resultText);
+
+ processed = QApplication::sendEvent(m_webView->focusProxy(), &im);
+ resultText = processed ? QStringLiteral("<font color='green'>TRUE</font>")
+ : QStringLiteral("<font color='red'>FALSE</font>");
+ m_webProcessed->setText(resultText);
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ m_testView->cancelTest();
+ QMainWindow::closeEvent(event);
+}
+
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
diff --git a/tests/manual/widgets/inputmethods/referenceview.cpp b/tests/manual/widgets/inputmethods/referenceview.cpp
index 906a3001e..27e784fbc 100644
--- a/tests/manual/widgets/inputmethods/referenceview.cpp
+++ b/tests/manual/widgets/inputmethods/referenceview.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "referenceview.h"
diff --git a/tests/manual/widgets/inputmethods/referenceview.h b/tests/manual/widgets/inputmethods/referenceview.h
index 4025d4886..d943a93d0 100644
--- a/tests/manual/widgets/inputmethods/referenceview.h
+++ b/tests/manual/widgets/inputmethods/referenceview.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef REFERENCEVIEW_H
#define REFERENCEVIEW_H
diff --git a/tests/manual/widgets/inputmethods/testview.cpp b/tests/manual/widgets/inputmethods/testview.cpp
index 14e355caf..d57b22cc5 100644
--- a/tests/manual/widgets/inputmethods/testview.cpp
+++ b/tests/manual/widgets/inputmethods/testview.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "testview.h"
@@ -94,11 +69,19 @@ void TestView::loadTestData(const QString &testDataPath)
testDataFile.close();
}
+void TestView::cancelTest()
+{
+ if (!m_testRunning)
+ return;
+
+ m_testRunning = false;
+ m_testButton->setText(tr("Start Test"));
+}
+
void TestView::startOrCancelTest()
{
if (m_testRunning) {
- m_testRunning = false;
- m_testButton->setText(tr("Start Test"));
+ cancelTest();
return;
}
@@ -120,10 +103,7 @@ void TestView::startOrCancelTest()
QTest::qWait(1000);
}
- if (m_testRunning) {
- m_testRunning = false;
- m_testButton->setText(tr("Start Test"));
- }
+ cancelTest();
}
void TestView::collectAndSendData()
diff --git a/tests/manual/widgets/inputmethods/testview.h b/tests/manual/widgets/inputmethods/testview.h
index 4934a5f87..b99e60d75 100644
--- a/tests/manual/widgets/inputmethods/testview.h
+++ b/tests/manual/widgets/inputmethods/testview.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTVIEW_H
#define TESTVIEW_H
@@ -32,8 +7,10 @@
#include <QTextCharFormat>
#include <QWidget>
+QT_BEGIN_NAMESPACE
class QPushButton;
class QTableView;
+QT_END_NAMESPACE
class TestView : public QWidget
{
@@ -41,6 +18,8 @@ class TestView : public QWidget
public:
explicit TestView(QWidget *parent = 0);
+ void cancelTest();
+
public slots:
void loadTestData(const QString &);
void startOrCancelTest();
diff --git a/tests/manual/widgets/inputmethods/webview.cpp b/tests/manual/widgets/inputmethods/webview.cpp
index 62e210ecf..915d73a7f 100644
--- a/tests/manual/widgets/inputmethods/webview.cpp
+++ b/tests/manual/widgets/inputmethods/webview.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "webview.h"
#include <QWebEngineSettings>
diff --git a/tests/manual/widgets/inputmethods/webview.h b/tests/manual/widgets/inputmethods/webview.h
index be57fbf29..a46dcb2f6 100644
--- a/tests/manual/widgets/inputmethods/webview.h
+++ b/tests/manual/widgets/inputmethods/webview.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef WEBVIEW_H
#define WEBVIEW_H
diff --git a/tests/manual/widgets/touchbrowser/CMakeLists.txt b/tests/manual/widgets/touchbrowser/CMakeLists.txt
new file mode 100644
index 000000000..de60ad2b4
--- /dev/null
+++ b/tests/manual/widgets/touchbrowser/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.19)
+ project(touchbrowser LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+set(CMAKE_AUTORCC ON)
+set(TOUCHMOCKING_DIR "../../touchmocking")
+
+include_directories(${TOUCHMOCKING_DIR})
+add_definitions(-DWIDGET_TOUCHBROWSER)
+
+qt_internal_add_manual_test(touchbrowser-widget
+ GUI
+ SOURCES
+ main.cpp
+ resources.qrc
+ ${TOUCHMOCKING_DIR}/touchmockingapplication.cpp
+ ${TOUCHMOCKING_DIR}/touchmockingapplication.h
+ ${TOUCHMOCKING_DIR}/utils.h
+ LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+ ENABLE_AUTOGEN_TOOLS
+ moc
+)
diff --git a/tests/manual/widgets/touchbrowser/main.cpp b/tests/manual/widgets/touchbrowser/main.cpp
new file mode 100644
index 000000000..18baf79e8
--- /dev/null
+++ b/tests/manual/widgets/touchbrowser/main.cpp
@@ -0,0 +1,62 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "touchmockingapplication.h"
+#include "utils.h"
+
+#include <QApplication>
+#include <QLineEdit>
+#include <QMainWindow>
+#include <QToolBar>
+#include <QWebEngineView>
+
+
+static QUrl startupUrl()
+{
+ QUrl ret;
+ QStringList args(qApp->arguments());
+ args.takeFirst();
+ for (const QString &arg : std::as_const(args)) {
+ if (arg.startsWith(QLatin1Char('-')))
+ continue;
+ ret = Utils::fromUserInput(arg);
+ if (ret.isValid())
+ return ret;
+ }
+ return QUrl(QStringLiteral("https://www.qt.io/"));
+}
+
+int main(int argc, char **argv)
+{
+ TouchMockingApplication app(argc, argv);
+ app.setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
+
+ QMainWindow window;
+ QWebEngineView view(&window);
+ QToolBar addressBar("AddressBar", &window);
+ QLineEdit lineEdit(&addressBar);
+
+ view.setAttribute(Qt::WA_AcceptTouchEvents, true);
+ view.setUrl(startupUrl());
+ window.resize(1024, 750);
+ window.setCentralWidget(&view);
+
+ addressBar.setAttribute(Qt::WA_AcceptTouchEvents, true);
+ addressBar.setMovable(false);
+ addressBar.toggleViewAction()->setEnabled(false);
+
+ lineEdit.setAttribute(Qt::WA_AcceptTouchEvents, true);
+ lineEdit.setClearButtonEnabled(true);
+
+ addressBar.addWidget(&lineEdit);
+ QObject::connect(&lineEdit, &QLineEdit::returnPressed, [&]() {
+ QUrl url = Utils::fromUserInput(lineEdit.text());
+ lineEdit.setText(url.toDisplayString());
+ view.setUrl(url);
+ });
+
+ window.addToolBar(&addressBar);
+ window.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/widgets/touchbrowser/resources.qrc b/tests/manual/widgets/touchbrowser/resources.qrc
new file mode 100644
index 000000000..b621823ea
--- /dev/null
+++ b/tests/manual/widgets/touchbrowser/resources.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="touchpoint.png">../../touchmocking/touchpoint.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/widgets/touchbrowser/touchbrowser.pro b/tests/manual/widgets/touchbrowser/touchbrowser.pro
new file mode 100644
index 000000000..1587f390a
--- /dev/null
+++ b/tests/manual/widgets/touchbrowser/touchbrowser.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+
+DEFINES += WIDGET_TOUCHBROWSER
+QT += core gui webenginewidgets
+
+INCLUDEPATH += ../../touchmocking
+
+SOURCES += \
+ main.cpp \
+ ../../touchmocking/touchmockingapplication.cpp
+HEADERS += \
+ ../../touchmocking/touchmockingapplication.h \
+ ../../touchmocking/utils.h
+
+RESOURCES += resources.qrc
diff --git a/tests/manual/widgets/webgl/CMakeLists.txt b/tests/manual/widgets/webgl/CMakeLists.txt
new file mode 100644
index 000000000..034a06a79
--- /dev/null
+++ b/tests/manual/widgets/webgl/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(webgl LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(webgl
+ GUI
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::WebEngineWidgets
+ ENABLE_AUTOGEN_TOOLS
+ moc
+)
diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp
index c18a15bac..7037c34db 100644
--- a/tests/manual/widgets/webgl/main.cpp
+++ b/tests/manual/widgets/webgl/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/QDebug>
#include <QtCore/QLoggingCategory>
diff --git a/tests/manual/widgets/webrtc/CMakeLists.txt b/tests/manual/widgets/webrtc/CMakeLists.txt
new file mode 100644
index 000000000..3f98f1fd6
--- /dev/null
+++ b/tests/manual/widgets/webrtc/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.19)
+ project(webrtc LANGUAGES CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+qt_internal_add_manual_test(webrtc
+ GUI
+ SOURCES
+ main.cpp
+ mediaPicker.ui
+ qrc.qrc
+ LIBRARIES
+ Qt::Core
+ Qt::HttpServer
+ Qt::Gui
+ Qt::WebEngineWidgets
+)
diff --git a/tests/manual/widgets/webrtc/index.html b/tests/manual/widgets/webrtc/index.html
new file mode 100644
index 000000000..433d643c3
--- /dev/null
+++ b/tests/manual/widgets/webrtc/index.html
@@ -0,0 +1,86 @@
+<!doctype html>
+<html>
+ <head>
+ <style>
+ body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-wrap: wrap;
+ flex-flow: column;
+ }
+ buttons {
+ justify-content: space-around;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="buttons" >
+ <input value ="getDisplayMedia" onclick="getDisplayMedia(true, true);" type="button">
+ <input value = "chooseDesktopMedia" onclick="chooseDesktopMedia();" type="button">
+ <input value ="Stop" onclick="stop();" type="button">
+ </div>
+ <div id="content"></div>
+ </body>
+ <script>
+ const EXTENSION_ID = "nkeimhogjdpnpccoofpliimaahmaaome"; // hangout services extension
+ const content = document.getElementById("content");
+ const video = document.createElement("video");
+ video.setAttribute("width", 640);
+ video.setAttribute("height", 640);
+ video.setAttribute("style", "background-color: black;");
+ content.appendChild(video);
+
+ async function getDisplayMedia(v = true, a = true) {
+ stop();
+ navigator.mediaDevices.getDisplayMedia({ video: v, audio: a })
+ .then(stream => {
+ start(stream);
+ }, error => {
+ console.error(error);
+ });
+ }
+
+ function chooseDesktopMedia() {
+ stop();
+ // Connect to the 'chooseDesktopMedia' listener within the hangout services extension.
+ let port = chrome.runtime.connect(EXTENSION_ID, {name: "chooseDesktopMedia"})
+
+ // The 'chooseDesktopMedia' api returns a streamId that
+ // identifies a media source in the constraints of 'getUserMedia'
+ // (see chromeMediaSourceId)
+ port.onMessage.addListener(result => {
+ navigator.mediaDevices.getUserMedia({
+ video: {
+ mandatory: {
+ chromeMediaSource: "desktop",
+ chromeMediaSourceId: result.value.streamId
+ },
+ }
+ }).then(stream => {
+ start(stream);
+ }, error => {
+ console.error(error);
+ })
+ })
+
+ // Trigger the listener on the other side,
+ // we should see the picker dialog after this call.
+ port.postMessage({method: "chooseDesktopMedia"})
+ }
+
+ function stop() {
+ if (video.srcObject)
+ for (const track of video.srcObject.getTracks())
+ track.stop()
+ video.srcObject = null;
+ video.setAttribute("style", "background-color: black;");
+ }
+
+ function start(stream) {
+ video.srcObject = stream;
+ video.play();
+ }
+
+ </script>
+</html>
diff --git a/tests/manual/widgets/webrtc/main.cpp b/tests/manual/widgets/webrtc/main.cpp
new file mode 100644
index 000000000..328e4ae36
--- /dev/null
+++ b/tests/manual/widgets/webrtc/main.cpp
@@ -0,0 +1,112 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+#include <QByteArray>
+#include <QDialog>
+#include <QFile>
+#include <QHttpServer>
+#include <QListView>
+#include <QMessageBox>
+#include <QWebEnginePage>
+#include <QWebEngineProfile>
+#include <QWebEngineSettings>
+#include <QWebEngineView>
+
+#include "ui_mediaPicker.h"
+#include <QWebEngineDesktopMediaRequest>
+
+// Test the screen/window selection and capturing APIs using QWebEngineDesktopMediaRequest,
+// getDisplayMedia (js) and chooseDesktopMedia (hangouts)
+
+// Note: Wayland compositors require Pipewire support in QWE
+
+class Page : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ Page(QWebEngineProfile *profile, QObject *parent = nullptr);
+private slots:
+ void handlePermissionRequest(const QUrl &origin, Feature feature);
+ void handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request);
+};
+
+Page::Page(QWebEngineProfile *profile, QObject *parent) : QWebEnginePage(profile, parent)
+{
+ settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
+ connect(this, &QWebEnginePage::featurePermissionRequested, this,
+ &Page::handlePermissionRequest);
+ connect(this, &QWebEnginePage::desktopMediaRequested, this, &Page::handleDesktopMediaRequest);
+}
+
+void Page::handlePermissionRequest(const QUrl &origin, Feature feature)
+{
+ if (QMessageBox::question(QApplication::activeWindow(), tr("Permission request"),
+ tr("allow access?"))
+ == QMessageBox::Yes)
+ setFeaturePermission(origin, feature, PermissionGrantedByUser);
+ else
+ setFeaturePermission(origin, feature, PermissionDeniedByUser);
+}
+
+void Page::handleDesktopMediaRequest(const QWebEngineDesktopMediaRequest &request)
+{
+ Ui::MediaPickerDialog mediaPickerDialog;
+ QDialog dialog;
+ dialog.setModal(true);
+ mediaPickerDialog.setupUi(&dialog);
+
+ auto *screensView = mediaPickerDialog.screensView;
+ auto *windowsView = mediaPickerDialog.windowsView;
+ auto *screensModel = request.screensModel();
+ auto *windowsModel = request.windowsModel();
+
+ screensView->setModel(screensModel);
+ windowsView->setModel(windowsModel);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ if (mediaPickerDialog.tabWidget->currentIndex() == 0)
+ request.selectWindow(windowsView->selectionModel()->selectedIndexes().first());
+ else
+ request.selectScreen(screensView->selectionModel()->selectedIndexes().first());
+ } else {
+ request.cancel();
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QHttpServer server;
+
+ QFile file(":index.html");
+
+ if (!file.open(QIODeviceBase::ReadOnly)) {
+ qWarning("failed to open file!");
+ return 0;
+ }
+
+ QByteArray data = file.readAll();
+ if (data.isEmpty()) {
+ qWarning("failed to read file!");
+ return 0;
+ }
+
+ server.route("/index.html", [data]() {
+ return data;
+ });
+
+ server.listen(QHostAddress::Any, 3000);
+
+ QWebEngineView view;
+ Page *page = new Page(QWebEngineProfile::defaultProfile(), &view);
+ view.setPage(page);
+ view.resize(1024, 750);
+ view.setUrl(QUrl("http://localhost:3000/index.html"));
+ view.show();
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/webrtc/mediaPicker.ui b/tests/manual/widgets/webrtc/mediaPicker.ui
new file mode 100644
index 000000000..8bfab3f9b
--- /dev/null
+++ b/tests/manual/widgets/webrtc/mediaPicker.ui
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MediaPickerDialog</class>
+ <widget class="QDialog" name="MediaPickerDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Choose what to share</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="windows">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::NoContextMenu</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <attribute name="title">
+ <string>Windows</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QListView" name="windowsView"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="screens">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::NoContextMenu</enum>
+ </property>
+ <attribute name="title">
+ <string>Screens</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QListView" name="screensView"/>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>MediaPickerDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>MediaPickerDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tests/manual/widgets/webrtc/qrc.qrc b/tests/manual/widgets/webrtc/qrc.qrc
new file mode 100644
index 000000000..c3322b454
--- /dev/null
+++ b/tests/manual/widgets/webrtc/qrc.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>index.html</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro
deleted file mode 100644
index 34e88f0e3..000000000
--- a/tests/manual/widgets/widgets.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE= subdirs
-
-SUBDIRS += \
- inputmethods \
- webgl
diff --git a/tests/quicktestbrowser/ApplicationRoot.qml b/tests/quicktestbrowser/ApplicationRoot.qml
deleted file mode 100644
index a2e83e1e6..000000000
--- a/tests/quicktestbrowser/ApplicationRoot.qml
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-import QtWebEngine 1.1
-
-QtObject {
- id: root
-
- property bool thirdPartyCookiesEnabled: true
-
- property QtObject testProfile: WebEngineProfile {
- storageName: "Test"
- }
-
- property QtObject otrProfile: WebEngineProfile {
- offTheRecord: true
- }
-
- property Component browserWindowComponent: BrowserWindow {
- applicationRoot: root
- onClosing: destroy()
- }
- property Component browserDialogComponent: BrowserDialog {
- onClosing: destroy()
- }
- function createWindow(profile) {
- var newWindow = browserWindowComponent.createObject(root)
- newWindow.currentWebView.profile = profile
- profile.downloadRequested.connect(newWindow.onDownloadRequested)
- profile.presentNotification.connect(newWindow.onPresentNotification)
- return newWindow
- }
- function createDialog(profile) {
- var newDialog = browserDialogComponent.createObject(root)
- newDialog.currentWebView.profile = profile
- return newDialog
- }
- function load(url) {
- var browserWindow = createWindow(testProfile)
- browserWindow.currentWebView.url = url
- }
-}
diff --git a/tests/quicktestbrowser/BrowserDialog.qml b/tests/quicktestbrowser/BrowserDialog.qml
deleted file mode 100644
index 9f286125e..000000000
--- a/tests/quicktestbrowser/BrowserDialog.qml
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-import QtQuick.Window 2.2
-import QtWebEngine 1.1
-
-Window {
- property alias currentWebView: webView
- flags: Qt.Dialog
- width: 800
- height: 600
- visible: true
- onClosing: destroy()
- WebEngineView {
- id: webView
- anchors.fill: parent
- }
-}
diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml
deleted file mode 100644
index 128674f02..000000000
--- a/tests/quicktestbrowser/BrowserWindow.qml
+++ /dev/null
@@ -1,532 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-import QtWebEngine 1.2
-
-import QtQuick.Controls 1.0
-import QtQuick.Controls.Styles 1.0
-import QtQuick.Layouts 1.0
-import QtQuick.Window 2.1
-import QtQuick.Controls.Private 1.0
-import Qt.labs.settings 1.0
-import QtQuick.Dialogs 1.2
-
-ApplicationWindow {
- id: browserWindow
- property QtObject applicationRoot
- property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item.webView : 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()
- fullScreenNotification.hide()
- }
- }
- }
-
- height: 600
- width: 800
- visible: true
- title: currentWebView && currentWebView.title
-
- Settings {
- id : appSettings
- property alias autoLoadImages: loadImages.checked;
- property alias javaScriptEnabled: javaScriptEnabled.checked;
- property alias errorPageEnabled: errorPageEnabled.checked;
- property alias pluginsEnabled: pluginsEnabled.checked;
- property alias thirdPartyCookiesEnabled: thirdPartyCookiesEnabled.checked;
- }
-
- // Make sure the Qt.WindowFullscreenButtonHint is set on OS X.
- Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint
-
- // Create a styleItem to determine the platform.
- // When using style "mac", ToolButtons are not supposed to accept focus.
- StyleItem { id: styleItem }
- property bool platformIsMac: styleItem.style == "mac"
-
- Action {
- shortcut: "Ctrl+D"
- onTriggered: {
- downloadView.visible = !downloadView.visible
- }
- }
-
- Action {
- id: focus
- shortcut: "Ctrl+L"
- onTriggered: {
- addressBar.forceActiveFocus();
- addressBar.selectAll();
- }
- }
- Action {
- shortcut: "Ctrl+R"
- onTriggered: {
- if (currentWebView)
- currentWebView.reload()
- }
- }
- Action {
- shortcut: "Ctrl+T"
- onTriggered: {
- tabs.createEmptyTab(currentWebView.profile)
- tabs.currentIndex = tabs.count - 1
- addressBar.forceActiveFocus();
- addressBar.selectAll();
- }
- }
- Action {
- shortcut: "Ctrl+W"
- onTriggered: {
- if (tabs.count == 1)
- browserWindow.close()
- else
- tabs.removeTab(tabs.currentIndex)
- }
- }
-
- Action {
- shortcut: "Escape"
- onTriggered: {
- if (browserWindow.isFullScreen)
- browserWindow.visibility = browserWindow.previousVisibility
- }
- }
- Action {
- shortcut: "Ctrl+0"
- onTriggered: zoomController.reset()
- }
- Action {
- shortcut: "Ctrl+-"
- onTriggered: zoomController.zoomOut()
- }
- Action {
- shortcut: "Ctrl+="
- onTriggered: zoomController.zoomIn()
- }
-
- Menu {
- id: backHistoryMenu
-
- Instantiator {
- model: currentWebView && currentWebView.history.backItems
- MenuItem {
- text: model.title
- onTriggered: currentWebView.goBackOrForward(model.offset)
- }
-
- onObjectAdded: backHistoryMenu.insertItem(index, object)
- onObjectRemoved: backHistoryMenu.removeItem(object)
- }
- }
-
- Menu {
- id: forwardHistoryMenu
-
- Instantiator {
- model: currentWebView && currentWebView.history.forwardItems
- MenuItem {
- text: model.title
- onTriggered: currentWebView.goBackOrForward(model.offset)
- }
-
- onObjectAdded: forwardHistoryMenu.insertItem(index, object)
- onObjectRemoved: forwardHistoryMenu.removeItem(object)
- }
- }
-
- toolBar: ToolBar {
- id: navigationBar
- RowLayout {
- anchors.fill: parent;
- ButtonWithMenu {
- id: backButton
- iconSource: "icons/go-previous.png"
- enabled: currentWebView && currentWebView.canGoBack
- activeFocusOnTab: !browserWindow.platformIsMac
- onClicked: currentWebView.goBack()
- longPressMenu: backHistoryMenu
- }
- ButtonWithMenu {
- id: forwardButton
- iconSource: "icons/go-next.png"
- enabled: currentWebView && currentWebView.canGoForward
- activeFocusOnTab: !browserWindow.platformIsMac
- onClicked: currentWebView.goForward()
- longPressMenu: forwardHistoryMenu
- }
- ToolButton {
- id: reloadButton
- iconSource: currentWebView && currentWebView.loading ? "icons/process-stop.png" : "icons/view-refresh.png"
- onClicked: currentWebView && currentWebView.loading ? currentWebView.stop() : currentWebView.reload()
- activeFocusOnTab: !browserWindow.platformIsMac
- }
- TextField {
- id: addressBar
- Image {
- anchors.verticalCenter: addressBar.verticalCenter;
- x: 5
- z: 2
- id: faviconImage
- width: 16; height: 16
- source: currentWebView && currentWebView.icon
- }
- style: TextFieldStyle {
- padding {
- left: 26;
- }
- }
- focus: true
- Layout.fillWidth: true
- text: currentWebView && currentWebView.url
- onAccepted: currentWebView.url = utils.fromUserInput(text)
- }
- ToolButton {
- id: settingsMenuButton
- menu: Menu {
- MenuItem {
- id: loadImages
- text: "Autoload images"
- checkable: true
- checked: true
- }
- MenuItem {
- id: javaScriptEnabled
- text: "JavaScript On"
- checkable: true
- checked: true
- }
- MenuItem {
- id: errorPageEnabled
- text: "ErrorPage On"
- checkable: true
- checked: true
- }
- MenuItem {
- id: pluginsEnabled
- text: "Plugins On"
- checkable: true
- checked: true
- }
- MenuItem {
- id: thirdPartyCookiesEnabled
- text: "Third party cookies enabled"
- checkable: true
- checked: true
- onToggled: applicationRoot.thirdPartyCookiesEnabled = checked
- }
- MenuItem {
- id: offTheRecordEnabled
- text: "Off The Record"
- checkable: true
- checked: currentWebView.profile.offTheRecord
- onToggled: currentWebView.profile = checked ? otrProfile : testProfile;
- }
- MenuItem {
- id: httpDiskCacheEnabled
- text: "HTTP Disk Cache"
- checkable: !currentWebView.profile.offTheRecord
- checked: (currentWebView.profile.httpCacheType == WebEngineProfile.DiskHttpCache)
- onToggled: currentWebView.profile.httpCacheType = checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache;
- }
- }
- }
- }
- ProgressBar {
- id: progressBar
- height: 3
- anchors {
- left: parent.left
- top: parent.bottom
- right: parent.right
- leftMargin: -parent.leftMargin
- rightMargin: -parent.rightMargin
- }
- style: ProgressBarStyle {
- background: Item {}
- }
- z: -2;
- minimumValue: 0
- maximumValue: 100
- value: (currentWebView && currentWebView.loadProgress < 100) ? currentWebView.loadProgress : 0
- }
- }
-
- TabView {
- id: tabs
- function createEmptyTab(profile) {
- var tab = addTab("", tabComponent)
- // We must do this first to make sure that tab.active gets set so that tab.item gets instantiated immediately.
- tab.active = true
- tab.title = Qt.binding(function() { return tab.item.title })
- tab.item.webView.profile = profile
- return tab
- }
-
- anchors.fill: parent
- Component.onCompleted: createEmptyTab(testProfile)
-
- Component {
- id: tabComponent
- Item {
- property alias webView: webEngineView
- property alias title: webEngineView.title
- Action {
- shortcut: "Ctrl+F"
- onTriggered: {
- findBar.visible = !findBar.visible
- if (findBar.visible) {
- findTextField.forceActiveFocus()
- }
- }
- }
- FeaturePermissionBar {
- id: permBar
- view: webEngineView
- anchors {
- left: parent.left
- right: parent.right
- top: parent.top
- }
- z: 3
- }
-
- WebEngineView {
- id: webEngineView
-
- anchors {
- fill: parent
- top: permBar.bottom
- }
-
- focus: true
-
- states: [
- State {
- name: "FullScreen"
- PropertyChanges {
- target: tabs
- frameVisible: false
- tabsVisible: false
- }
- PropertyChanges {
- target: navigationBar
- visible: false
- }
- }
- ]
- settings.autoLoadImages: appSettings.autoLoadImages
- settings.javascriptEnabled: appSettings.javaScriptEnabled
- settings.errorPageEnabled: appSettings.errorPageEnabled
- settings.pluginsEnabled: appSettings.pluginsEnabled
-
- onCertificateError: {
- if (!acceptedCertificates.shouldAutoAccept(error)){
- error.defer()
- sslDialog.enqueue(error)
- } else{
- error.ignoreCertificateError()
- }
- }
-
- onNewWindowRequested: {
- if (!request.userInitiated)
- print("Warning: Blocked a popup window.")
- else if (request.destination == WebEngineView.NewViewInTab) {
- var tab = tabs.createEmptyTab(currentWebView.profile)
- tabs.currentIndex = tabs.count - 1
- request.openIn(tab.item.webView)
- } else if (request.destination == WebEngineView.NewViewInBackgroundTab) {
- var tab = tabs.createEmptyTab(currentWebView.profile)
- request.openIn(tab.item.webView)
- } else if (request.destination == WebEngineView.NewViewInDialog) {
- var dialog = applicationRoot.createDialog(currentWebView.profile)
- request.openIn(dialog.currentWebView)
- } else {
- var window = applicationRoot.createWindow(currentWebView.profile)
- request.openIn(window.currentWebView)
- }
- }
-
- onFullScreenRequested: {
- if (request.toggleOn) {
- webEngineView.state = "FullScreen"
- browserWindow.previousVisibility = browserWindow.visibility
- browserWindow.showFullScreen()
- fullScreenNotification.show()
- } else {
- webEngineView.state = ""
- browserWindow.visibility = browserWindow.previousVisibility
- fullScreenNotification.hide()
- }
- request.accept()
- }
-
- onFeaturePermissionRequested: {
- permBar.securityOrigin = securityOrigin;
- permBar.requestedFeature = feature;
- permBar.visible = true;
- }
- }
-
- Rectangle {
- id: findBar
- anchors.top: webEngineView.top
- anchors.right: webEngineView.right
- width: 240
- height: 35
- border.color: "lightgray"
- border.width: 1
- radius: 5
- visible: false
- color: browserWindow.color
-
- RowLayout {
- anchors.centerIn: findBar
- TextField {
- id: findTextField
- onAccepted: {
- webEngineView.findText(text)
- }
- }
- ToolButton {
- id: findBackwardButton
- iconSource: "icons/go-previous.png"
- onClicked: webEngineView.findText(findTextField.text, WebEngineView.FindBackward)
- }
- ToolButton {
- id: findForwardButton
- iconSource: "icons/go-next.png"
- onClicked: webEngineView.findText(findTextField.text)
- }
- ToolButton {
- id: findCancelButton
- iconSource: "icons/process-stop.png"
- onClicked: findBar.visible = false
- }
- }
- }
- }
- }
- }
-
- QtObject{
- id:acceptedCertificates
-
- property var acceptedUrls : []
-
- function shouldAutoAccept(certificateError){
- var domain = utils.domainFromString(certificateError.url)
- return acceptedUrls.indexOf(domain) >= 0
- }
- }
-
- MessageDialog {
- id: sslDialog
-
- property var certErrors: []
- icon: StandardIcon.Warning
- standardButtons: StandardButton.No | StandardButton.Yes
- title: "Server's certificate not trusted"
- text: "Do you wish to continue?"
- detailedText: "If you wish so, you may continue with an unverified certificate. " +
- "Accepting an unverified certificate means " +
- "you may not be connected with the host you tried to connect to.\n" +
- "Do you wish to override the security check and continue?"
- onYes: {
- var cert = certErrors.shift()
- var domain = utils.domainFromString(cert.url)
- acceptedCertificates.acceptedUrls.push(domain)
- cert.ignoreCertificateError()
- presentError()
- }
- onNo: reject()
- onRejected: reject()
-
- function reject(){
- certErrors.shift().rejectCertificate()
- presentError()
- }
- function enqueue(error){
- certErrors.push(error)
- presentError()
- }
- function presentError(){
- visible = certErrors.length > 0
- }
- }
-
- FullScreenNotification {
- id: fullScreenNotification
- }
-
- DownloadView {
- id: downloadView
- visible: false
- anchors.fill: parent
- }
-
- function onDownloadRequested(download) {
- downloadView.visible = true
- downloadView.append(download)
- download.accept()
- }
-
- MessageDialog {
- id: notificationDialog
- width: 200
- standardButtons: StandardButton.Ok
- }
-
- function onPresentNotification(notification) {
- notificationDialog.title = notification.title
- notificationDialog.text = notification.origin.toString() + '\n' + notification.message
- notificationDialog.open()
- }
-
- ZoomController {
- id: zoomController
- y: parent.mapFromItem(currentWebView, 0 , 0).y - 4
- anchors.right: parent.right
- width: (parent.width > 800) ? parent.width * 0.25 : 220
- anchors.rightMargin: (parent.width > 400) ? 100 : 0
- }
- Binding {
- target: currentWebView
- property: "zoomFactor"
- value: zoomController.zoomFactor
- }
-}
diff --git a/tests/quicktestbrowser/ButtonWithMenu.qml b/tests/quicktestbrowser/ButtonWithMenu.qml
deleted file mode 100644
index b8d4f743c..000000000
--- a/tests/quicktestbrowser/ButtonWithMenu.qml
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-
-// The QtQuick controls guys are slackers, so we need to make our own stuff
-
-ToolButton {
- id: root
- property Menu longPressMenu
- function showMenu() {
- longPressMenu.__popup(Qt.rect(0, root.height, 0, 0), 0)
- }
-
- Binding {
- target: longPressMenu
- property: "__visualItem"
- value: root
- }
-
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.LeftButton | Qt.RightButton
- onClicked: {
- if (mouse.button == Qt.RightButton)
- showMenu()
- else
- root.clicked()
- }
- onPressAndHold: showMenu()
- }
-}
diff --git a/tests/quicktestbrowser/DownloadView.qml b/tests/quicktestbrowser/DownloadView.qml
deleted file mode 100644
index eb945eccc..000000000
--- a/tests/quicktestbrowser/DownloadView.qml
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtQuick.Controls.Styles 1.0
-import QtWebEngine 1.0
-import QtQuick.Layouts 1.0
-
-Rectangle {
- id: downloadView
- color: "lightgray"
-
- ListModel {
- id: downloadModel
- property var downloads: []
- }
-
- function append(download) {
- downloadModel.append(download)
- downloadModel.downloads.push(download)
- }
-
- Component {
- id: downloadItemDelegate
-
- Rectangle {
- width: listView.width
- height: childrenRect.height
- anchors.margins: 10
- radius: 3
- color: "transparent"
- border.color: "black"
- Rectangle {
- id: progressBar
-
- property real progress: downloadModel.downloads[index]
- ? downloadModel.downloads[index].receivedBytes / downloadModel.downloads[index].totalBytes : 0
-
- radius: 3
- color: width == listView.width ? "green" : "#2b74c7"
- width: listView.width * progress
- height: cancelButton.height
-
- Behavior on width {
- SmoothedAnimation { duration: 100 }
- }
- }
- Rectangle {
- anchors {
- left: parent.left
- right: parent.right
- leftMargin: 20
- }
- Label {
- id: label
- text: path
- anchors {
- verticalCenter: cancelButton.verticalCenter
- left: parent.left
- right: cancelButton.left
- }
- }
- Button {
- id: cancelButton
- anchors.right: parent.right
- iconSource: "icons/process-stop.png"
- onClicked: {
- var download = downloadModel.downloads[index]
-
- download.cancel()
-
- downloadModel.downloads = downloadModel.downloads.filter(function (el) {
- return el.id !== download.id;
- });
- downloadModel.remove(index)
- }
- }
- }
- }
-
- }
- ListView {
- id: listView
- anchors {
- topMargin: 10
- top: parent.top
- bottom: parent.bottom
- horizontalCenter: parent.horizontalCenter
- }
- width: parent.width - 20
- spacing: 5
-
- model: downloadModel
- delegate: downloadItemDelegate
-
- Text {
- visible: !listView.count
- horizontalAlignment: Text.AlignHCenter
- height: 30
- anchors {
- top: parent.top
- left: parent.left
- right: parent.right
- }
- font.pixelSize: 20
- text: "No active downloads."
- }
-
- Rectangle {
- color: "gray"
- anchors {
- bottom: parent.bottom
- left: parent.left
- right: parent.right
- }
- height: 30
- Button {
- id: okButton
- text: "OK"
- anchors.centerIn: parent
- onClicked: {
- downloadView.visible = false
- }
- }
- }
- }
-}
diff --git a/tests/quicktestbrowser/FeaturePermissionBar.qml b/tests/quicktestbrowser/FeaturePermissionBar.qml
deleted file mode 100644
index 500d13206..000000000
--- a/tests/quicktestbrowser/FeaturePermissionBar.qml
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtWebEngine 1.1
-import QtQuick.Layouts 1.0
-
-Rectangle {
- property var requestedFeature;
- property url securityOrigin;
- property WebEngineView view;
-
- id: permissionBar
- visible: false
- height: acceptButton.height + 4
-
-
- function textForFeature(feature) {
- switch (feature) {
- case WebEngineView.Geolocation: return 'Allow %1 to access your location information?'
- case WebEngineView.MediaAudioCapture: return 'Allow %1 to access your microphone?'
- case WebEngineView.MediaVideoCapture: return 'Allow %1 to access your webcam?'
- case WebEngineView.MediaAudioVideoCapture: return 'Allow %1 to access your microphone and webcam?'
- case WebEngineView.DesktopVideoCapture: return 'Allow %1 to capture video of your desktop?'
- case WebEngineView.DesktopAudioVideoCapture: return 'Allow %1 to capture audio and video of your desktop?'
- case WebEngineView.Notifications: return 'Allow %1 to show notification on your desktop?'
- default: break
- }
- return 'Grant permission for %1 to unknown or unsupported feature [' + feature + ']?'
- }
-
- onRequestedFeatureChanged: {
- message.text = textForFeature(requestedFeature).arg(securityOrigin);
- }
-
- RowLayout {
- anchors {
- fill: permissionBar
- leftMargin: 5
- rightMargin: 5
- }
- Label {
- id: message
- Layout.fillWidth: true
- }
-
- Button {
- id: acceptButton
- text: "Accept"
- Layout.alignment: Qt.AlignRight
- onClicked: {
- view.grantFeaturePermission(securityOrigin, requestedFeature, true);
- permissionBar.visible = false;
- }
- }
-
- Button {
- text: "Deny"
- Layout.alignment: Qt.AlignRight
- onClicked: {
- view.grantFeaturePermission(securityOrigin, requestedFeature, false);
- permissionBar.visible = false
- }
- }
- }
-}
diff --git a/tests/quicktestbrowser/FullScreenNotification.qml b/tests/quicktestbrowser/FullScreenNotification.qml
deleted file mode 100644
index 90f27cca6..000000000
--- a/tests/quicktestbrowser/FullScreenNotification.qml
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $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/ZoomController.qml b/tests/quicktestbrowser/ZoomController.qml
deleted file mode 100644
index 122ae8815..000000000
--- a/tests/quicktestbrowser/ZoomController.qml
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Layouts 1.1
-
-Rectangle {
- property alias zoomFactor: slider.value ;
- function zoomIn() {
- visible = true
- visibilityTimer.restart()
- zoomFactor = zoomFactor + 0.25;
- }
- function zoomOut() {
- visible = true
- visibilityTimer.restart()
- zoomFactor = zoomFactor - 0.25;
- }
- function reset() { zoomFactor = 1.0 }
-
- width: 220
- height: 30
- color: palette.window
- visible: false
- radius: 4
-
- SystemPalette {
- id: palette
- }
- Timer {
- id: visibilityTimer
- interval: 3000
- repeat: false
- onTriggered: zoomController.visible = false
- }
-
- RowLayout {
- anchors.margins: 4
- anchors.fill: parent
- ToolButton {
- id: plusButton
- text: '+'
- onClicked: zoomIn()
- }
- ToolButton {
- text: '\u2014'
- id: minusButton
- onClicked: zoomOut()
- }
- Slider {
- id: slider
- maximumValue: 5.0
- minimumValue: 0.25
- Layout.fillWidth: true;
- stepSize: 0.05
- value: 1
- onValueChanged: visibilityTimer.restart()
- }
- Button {
- text: "Reset"
- onClicked: reset()
- }
- }
-}
diff --git a/tests/quicktestbrowser/main.cpp b/tests/quicktestbrowser/main.cpp
deleted file mode 100644
index cb21518c9..000000000
--- a/tests/quicktestbrowser/main.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "utils.h"
-
-#ifndef QT_NO_WIDGETS
-#include <QtWidgets/QApplication>
-typedef QApplication Application;
-#else
-#include <QtGui/QGuiApplication>
-typedef QGuiApplication Application;
-#endif
-#include <QtQml/QQmlApplicationEngine>
-#include <QtQml/QQmlContext>
-#include <QtQml/QQmlComponent>
-#include <QtWebEngineQuick/qtwebenginequickglobal.h>
-#include <QtWebEngineQuick/QQuickWebEngineProfile>
-#include <QtWebEngineCore/qwebenginecookiestore.h>
-
-static QUrl startupUrl()
-{
- QUrl ret;
- QStringList args(qApp->arguments());
- args.takeFirst();
- for (const QString &arg : qAsConst(args)) {
- if (arg.startsWith(QLatin1Char('-')))
- continue;
- ret = Utils::fromUserInput(arg);
- if (ret.isValid())
- return ret;
- }
- return QUrl(QStringLiteral("http://qt.io/"));
-}
-
-int main(int argc, char **argv)
-{
- Application app(argc, argv);
-
- // Enable dev tools by default for the test browser
- if (qgetenv("QTWEBENGINE_REMOTE_DEBUGGING").isNull())
- qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "1337");
- QtWebEngineQuick::initialize();
-
- QQmlApplicationEngine appEngine;
- Utils utils;
- appEngine.rootContext()->setContextProperty("utils", &utils);
- appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
-
- QObject *rootObject = appEngine.rootObjects().first();
-
- QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(rootObject);
-
- const QMetaObject *rootMeta = rootObject->metaObject();
- int index = rootMeta->indexOfProperty("thirdPartyCookiesEnabled");
- Q_ASSERT(index != -1);
- QMetaProperty thirdPartyCookiesProperty = rootMeta->property(index);
- profile->cookieStore()->setCookieFilter(
- [rootObject,&thirdPartyCookiesProperty](const QWebEngineCookieStore::FilterRequest &request)
- {
- return !request.thirdParty || thirdPartyCookiesProperty.read(rootObject).toBool();
- });
-
- index = rootMeta->indexOfProperty("testProfile");
- Q_ASSERT(index != -1);
- QMetaProperty profileProperty = rootMeta->property(index);
- profileProperty.write(rootObject, QVariant::fromValue(profile));
-
- QMetaObject::invokeMethod(rootObject, "load", Q_ARG(QVariant, startupUrl()));
-
- return app.exec();
-}
diff --git a/tests/quicktestbrowser/quicktestbrowser.pro b/tests/quicktestbrowser/quicktestbrowser.pro
deleted file mode 100644
index 304135836..000000000
--- a/tests/quicktestbrowser/quicktestbrowser.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-requires(qtConfig(accessibility))
-
-TEMPLATE = app
-TARGET = quicktestbrowser
-
-macx: CONFIG -= app_bundle
-
-HEADERS = utils.h
-SOURCES = main.cpp
-
-OTHER_FILES += ApplicationRoot.qml \
- BrowserDialog.qml \
- BrowserWindow.qml \
- ButtonWithMenu.qml \
- ContextMenuExtras.qml \
- DownloadView.qml \
- FeaturePermissionBar.qml \
- FullScreenNotification.qml
-
-RESOURCES += resources.qrc
-
-QT += qml quick webenginequick
-
-qtHaveModule(widgets) {
- QT += widgets # QApplication is required to get native styling with QtQuickControls
-}
diff --git a/tests/quicktestbrowser/resources.qrc b/tests/quicktestbrowser/resources.qrc
deleted file mode 100644
index 8fbe286fb..000000000
--- a/tests/quicktestbrowser/resources.qrc
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
- <qresource prefix="/">
- <file>ApplicationRoot.qml</file>
- <file>BrowserDialog.qml</file>
- <file>BrowserWindow.qml</file>
- <file>FeaturePermissionBar.qml</file>
- <file>FullScreenNotification.qml</file>
- <file>ButtonWithMenu.qml</file>
- <file>DownloadView.qml</file>
- <file>ZoomController.qml</file>
- </qresource>
- <qresource prefix="icons">
- <!-- To the risk of this breaking more often, do not duplicate the resources since this application won't be deployed -->
- <file alias="go-next.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/go-next.png</file>
- <file alias="go-previous.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/go-previous.png</file>
- <file alias="process-stop.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/process-stop.png</file>
- <file alias="view-refresh.png">../../examples/webenginequick/quicknanobrowser/icons/3rdparty/view-refresh.png</file>
- </qresource>
-</RCC>
diff --git a/tests/quicktestbrowser/utils.h b/tests/quicktestbrowser/utils.h
deleted file mode 100644
index d4f3dba0e..000000000
--- a/tests/quicktestbrowser/utils.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <QtCore/QFileInfo>
-#include <QtCore/QUrl>
-
-class Utils : public QObject {
- Q_OBJECT
-public:
- Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
- Q_INVOKABLE static QString domainFromString(const QString& urlString);
-};
-
-inline QUrl Utils::fromUserInput(const QString& userInput)
-{
- QFileInfo fileInfo(userInput);
- if (fileInfo.exists())
- return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
- return QUrl::fromUserInput(userInput);
-}
-
-inline QString Utils::domainFromString(const QString& urlString)
-{
- return QUrl::fromUserInput(urlString).host();
-}
-
-#endif // UTILS_H
diff --git a/tools/buildscripts/qtwebengine_utils.py b/tools/buildscripts/qtwebengine_utils.py
index 85f9a5d27..32bccbf4d 100755
--- a/tools/buildscripts/qtwebengine_utils.py
+++ b/tools/buildscripts/qtwebengine_utils.py
@@ -1,32 +1,6 @@
-#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+#!/usr/bin/env python3
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import os
import subprocess
diff --git a/tools/buildscripts/repack_locales.py b/tools/buildscripts/repack_locales.py
index dc4452d94..99b91867c 100755
--- a/tools/buildscripts/repack_locales.py
+++ b/tools/buildscripts/repack_locales.py
@@ -1,32 +1,7 @@
-#!/usr/bin/env python
-#############################################################################
-##
-## Copyright (c) 2012 The Chromium Authors. All rights reserved.
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+#!/usr/bin/env python3
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
# This is esentially a trimmed down version of chrome's repack_locales script
"""Helper script to repack paks for a list of locales.
diff --git a/tools/scripts/check_patches.py b/tools/scripts/check_patches.py
index 7437f1587..e14d54f63 100755
--- a/tools/scripts/check_patches.py
+++ b/tools/scripts/check_patches.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
diff --git a/tools/scripts/cipd_package.py b/tools/scripts/cipd_package.py
new file mode 100644
index 000000000..8ab448c86
--- /dev/null
+++ b/tools/scripts/cipd_package.py
@@ -0,0 +1,103 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import glob
+import os
+import re
+import subprocess
+import sys
+import version_resolver as resolver
+
+androidx_package_name = 'chromium/third_party/androidx'
+
+def subprocessCall(args):
+ print(args)
+ return subprocess.call(args)
+
+def subprocessCheckOutput(args):
+ print(args)
+ return subprocess.check_output(args).decode()
+
+class PackageDEPSParser(resolver.DEPSParser):
+ def __init__(self):
+ super().__init__()
+
+ def createEntitiesFromScope(self, scope):
+ entities = []
+ for dep in scope:
+ if (type(scope[dep]) == dict and 'packages' in scope[dep] \
+ and 'dep_type' in scope[dep] and scope[dep]['dep_type'] == 'cipd'):
+ subdir = self.subdir(dep)
+ if subdir is None:
+ continue
+ entity = CIPDEntity(subdir, sp=self.topmost_supermodule_path_prefix)
+ path = entity.pathRelativeToTopMostSupermodule()
+ for pkg in scope[dep]['packages']:
+ p = Package(pkg['package'], pkg['version'], path)
+ entity.packages.append(p)
+ entities.append(entity)
+ return entities
+
+ def parse(self, deps_content, module_whitelist = []):
+ exec(deps_content, self.global_scope, self.local_scope)
+ entities = []
+ entities.extend(self.createEntitiesFromScope(self.local_scope['deps']))
+ return entities
+
+class Package:
+ def __init__(self, name, version, path):
+ self.name = name
+ self.version = version
+ self.path = path
+ self.fileName = name.replace('/','.') + '.pkg'
+
+ def fetchAndDeploy(self):
+ if os.path.isdir(self.path):
+ currentDir = os.getcwd()
+ os.chdir(self.path)
+ subprocessCall(['cipd', 'pkg-fetch', self.name ,'-out' , self.fileName, '-version', self.version ])
+ subprocessCall(['cipd', 'pkg-deploy', self.fileName , '-root', '.' ])
+ os.chdir(currentDir)
+ else:
+ print('-- missing directory' + self.path + ' skipping')
+
+ def listFiles(self):
+ if os.path.isdir(self.path):
+ currentDir = os.getcwd()
+ os.chdir(self.path)
+ files = []
+ if os.path.isfile(self.fileName):
+ files = subprocessCheckOutput(['cipd', 'pkg-inspect', self.fileName]).splitlines()
+ files = map( lambda x: x.replace( ' F ', self.path + '/'), files)
+ else:
+ print('-- missing package file ' + self.path + ' skipping')
+ os.chdir(currentDir)
+ return files
+ else:
+ print('-- missing directory' + self.path + ' skipping')
+ return []
+
+class CIPDEntity:
+ def __init__(self, path='', packages=[], os=[], sp=''):
+ self.path = path
+ self.packages = []
+ self.topmost_supermodule_path_prefix = sp
+
+ def pathRelativeToTopMostSupermodule(self):
+ return os.path.normpath(os.path.join(self.topmost_supermodule_path_prefix, self.path))
+
+ def findPackage(self, package):
+ pkg = [p for p in self.packages if p.name == package]
+ if len(pkg) > 1:
+ raise Exception(package + " is ambiguous package name for" + self.path)
+ return pkg[0] if pkg else None
+
+ def readEntities(self):
+ cipd_packages = []
+ cipd_packages = resolver.read(PackageDEPSParser)
+ print('DEPS file provides the following packages:')
+ for cipd_package in cipd_packages:
+ print(cipd_package.pathRelativeToTopMostSupermodule() + ':')
+ for package in cipd_package.packages:
+ print(' * {:<80}'.format(package.name) + package.version)
+ return cipd_packages
diff --git a/tools/scripts/get_version.py b/tools/scripts/get_version.py
index d3928f6e5..897b9866e 100755
--- a/tools/scripts/get_version.py
+++ b/tools/scripts/get_version.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import sys
import json
diff --git a/tools/scripts/git_submodule.py b/tools/scripts/git_submodule.py
index 43a652b11..3d301d16b 100644
--- a/tools/scripts/git_submodule.py
+++ b/tools/scripts/git_submodule.py
@@ -1,34 +1,10 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
import re
+import string
import subprocess
import sys
import version_resolver as resolver
@@ -36,22 +12,21 @@ import version_resolver as resolver
extra_os = ['mac', 'win']
def subprocessCall(args):
- print args
+ print(args)
return subprocess.call(args)
def subprocessCheckOutput(args):
- print args
- return subprocess.check_output(args)
+ print(args)
+ return subprocess.check_output(args).decode()
-class DEPSParser:
+# Special string formatter that support flat key names with '.' in them
+class DepsFormatter(string.Formatter):
+ def get_field(self, field_name, args, kwargs):
+ return (self.get_value(field_name, args, kwargs), field_name)
+
+class SubmoduleDEPSParser(resolver.DEPSParser):
def __init__(self):
- self.global_scope = {
- 'Var': lambda var_name: '{%s}' % var_name,
- 'Str': str,
- 'deps_os': {},
- }
- self.local_scope = {}
- self.topmost_supermodule_path_prefix = ''
+ super().__init__()
def get_vars(self):
"""Returns a dictionary of effective variable values
@@ -62,10 +37,7 @@ class DEPSParser:
#result.update(self.custom_vars or {})
return result
- def get_recursedeps(self):
- return self.local_scope["recursedeps"]
-
- def createSubmodulesFromScope(self, scope, os):
+ def createSubmodulesFromScope(self, scope, os, module_whitelist = []):
submodules = []
for dep in scope:
url = ''
@@ -74,29 +46,23 @@ class DEPSParser:
elif (type(scope[dep]) == dict and 'url' in scope[dep]):
url = scope[dep]['url']
- if ('condition' in scope[dep]) and (not 'checkout_linux' in scope[dep]['condition']):
- url = ''
-
+ if ('condition' in scope[dep]) and \
+ (not 'checkout_linux' in scope[dep]['condition']) and \
+ (not dep in module_whitelist):
+ continue
if url:
- url = url.format(**self.get_vars())
+ url = DepsFormatter().vformat(url, [], self.get_vars())
repo_rev = url.split('@')
repo = repo_rev[0]
rev = repo_rev[1]
- subdir = dep
- if subdir.startswith('src/'):
- subdir = subdir[4:]
- # Don't skip submodules that have a supermodule path prefix set (at the moment these
- # are 2nd level deep submodules).
- elif not self.topmost_supermodule_path_prefix:
- # Ignore the information about chromium itself since we get that from git,
- # also ignore anything outside src/ (e.g. depot_tools)
+ subdir = self.subdir(dep)
+ if subdir is None:
continue
-
submodule = Submodule(subdir, repo, sp=self.topmost_supermodule_path_prefix)
submodule.os = os
if not submodule.matchesOS():
- print '-- skipping ' + submodule.pathRelativeToTopMostSupermodule() + ' for this operating system. --'
+ print('-- skipping ' + submodule.pathRelativeToTopMostSupermodule() + ' for this operating system. --')
continue
if len(rev) == 40: # Length of a git shasum
@@ -108,11 +74,11 @@ class DEPSParser:
submodules.append(submodule)
return submodules
- def parse(self, deps_content):
+ def parse(self, deps_content, module_whitelist = []):
exec(deps_content, self.global_scope, self.local_scope)
submodules = []
- submodules.extend(self.createSubmodulesFromScope(self.local_scope['deps'], 'all'))
+ submodules.extend(self.createSubmodulesFromScope(self.local_scope['deps'], 'all', module_whitelist))
if 'deps_os' in self.local_scope:
for os_dep in self.local_scope['deps_os']:
submodules.extend(self.createSubmodulesFromScope(self.local_scope['deps_os'][os_dep], os_dep))
@@ -201,7 +167,7 @@ class Submodule:
def findGitDir(self):
try:
return subprocessCheckOutput(['git', 'rev-parse', '--git-dir']).strip()
- except subprocess.CalledProcessError, e:
+ except subprocess.CalledProcessError as e:
sys.exit("git dir could not be determined! - Initialization failed! " + e.output)
def reset(self):
@@ -210,27 +176,27 @@ class Submodule:
gitdir = self.findGitDir()
if os.path.isdir(os.path.join(gitdir, 'rebase-merge')):
if os.path.isfile(os.path.join(gitdir, 'MERGE_HEAD')):
- print 'merge in progress... aborting merge.'
+ print('merge in progress... aborting merge.')
subprocessCall(['git', 'merge', '--abort'])
else:
- print 'rebase in progress... aborting merge.'
+ print('rebase in progress... aborting merge.')
subprocessCall(['git', 'rebase', '--abort'])
if os.path.isdir(os.path.join(gitdir, 'rebase-apply')):
- print 'am in progress... aborting am.'
+ print('am in progress... aborting am.')
subprocessCall(['git', 'am', '--abort'])
subprocessCall(['git', 'reset', '--hard'])
os.chdir(currentDir)
def initialize(self):
if self.matchesOS():
- print '\n\n-- initializing ' + self.pathRelativeToTopMostSupermodule() + ' --'
+ print('\n\n-- initializing ' + self.pathRelativeToTopMostSupermodule() + ' --')
oldCwd = os.getcwd()
# The submodule operations should be done relative to the current submodule's
# supermodule.
if self.topmost_supermodule_path_prefix:
if not os.path.isdir(self.path):
- print '-- creating ' + self.path + ' as dir is missing. --'
+ print('-- creating ' + self.path + ' as dir is missing. --')
os.makedirs(self.path)
os.chdir(self.topmost_supermodule_path_prefix)
@@ -254,7 +220,7 @@ class Submodule:
os.chdir(oldCwd)
else:
- print '-- skipping ' + self.path + ' for this operating system. --'
+ print('-- skipping ' + self.path + ' for this operating system. --')
def listFiles(self):
if self.matchesOS() and os.path.isdir(self.pathRelativeToTopMostSupermodule()):
@@ -264,7 +230,7 @@ class Submodule:
os.chdir(currentDir)
return files
else:
- print '-- skipping ' + self.path + ' for this operating system. --'
+ print('-- skipping ' + self.path + ' for this operating system. --')
return []
def parseGitModulesFileContents(self, gitmodules_lines):
@@ -319,10 +285,10 @@ class Submodule:
def readSubmodules(self, use_deps=False):
submodules = []
if use_deps:
- submodules = resolver.readSubmodules()
- print 'DEPS file provides the following submodules:'
+ submodules = resolver.read(SubmoduleDEPSParser)
+ print('DEPS file provides the following submodules:')
for submodule in submodules:
- print '{:<80}'.format(submodule.pathRelativeToTopMostSupermodule()) + '{:<120}'.format(submodule.url) + submodule.ref
+ print('{:<80}'.format(submodule.pathRelativeToTopMostSupermodule()) + '{:<120}'.format(submodule.url) + submodule.ref)
else: # Try .gitmodules instead
gitmodules_file_name = '.gitmodules'
submodules = self.readSubmodulesFromGitModules(self, gitmodules_file_name, self.path)
diff --git a/tools/scripts/gn_find_mocables.py b/tools/scripts/gn_find_mocables.py
index 4dc2576e3..68f648889 100644
--- a/tools/scripts/gn_find_mocables.py
+++ b/tools/scripts/gn_find_mocables.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import re
import sys
@@ -32,7 +7,7 @@ import os
mocables = set()
includedMocs = set()
-files = sys.argv[2:]
+files = sys.argv[1:]
for f in filter(os.path.isfile, files):
inBlockComment = False
diff --git a/tools/scripts/gn_run_binary.py b/tools/scripts/gn_run_binary.py
index 5debf02ab..0e30e23ed 100644
--- a/tools/scripts/gn_run_binary.py
+++ b/tools/scripts/gn_run_binary.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import sys
diff --git a/tools/scripts/init-repository.py b/tools/scripts/init-repository.py
index 221f74a65..e6ec0c440 100755
--- a/tools/scripts/init-repository.py
+++ b/tools/scripts/init-repository.py
@@ -1,32 +1,6 @@
-#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+#!/usr/bin/env python3
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
@@ -38,6 +12,7 @@ import argparse
qtwebengine_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
import git_submodule as GitSubmodule
+import cipd_package as CIPDPackage
import version_resolver as resolver
chromium_src = os.environ.get('CHROMIUM_SRC_DIR')
@@ -47,13 +22,14 @@ use_external_chromium = False
parser = argparse.ArgumentParser(description='Initialize QtWebEngine repository.')
parser.add_argument('--baseline-upstream', action='store_true', help='initialize using upstream Chromium submodule w/o applying patches (for maintenance purposes only)')
+parser.add_argument('--use_cipd', action='store_true', help='fetch and deploy packages with cipd')
group = parser.add_mutually_exclusive_group()
group.add_argument('-u', '--upstream', action='store_true', help='initialize using upstream Chromium submodule')
group.add_argument('-s', '--snapshot', action='store_true', help='initialize using flat Chromium snapshot submodule (default)')
args = parser.parse_args()
-
if args.baseline_upstream:
args.upstream = True
+ args.use_cipd = True
if chromium_src:
chromium_src = os.path.abspath(chromium_src)
@@ -66,7 +42,7 @@ if not chromium_src or not os.path.isdir(chromium_src):
ninja_src = os.path.join(qtwebengine_root, 'src/3rdparty/ninja')
gn_src = os.path.join(qtwebengine_root, 'src/3rdparty/gn')
args.snapshot = True
- print 'CHROMIUM_SRC_DIR not set, using Chromium in' + chromium_src
+ print('CHROMIUM_SRC_DIR not set, using Chromium in' + chromium_src)
if not args.baseline_upstream:
# Write our chromium sources directory into git config.
@@ -79,7 +55,7 @@ def updateLastChange():
return
currentDir = os.getcwd()
os.chdir(chromium_src)
- print 'updating LASTCHANGE files'
+ print('updating LASTCHANGE files')
subprocess.call(['python', 'build/util/lastchange.py', '-o', 'build/util/LASTCHANGE'])
subprocess.call(['python', 'build/util/lastchange.py', '-m', 'SKIA_COMMIT_HASH', '-s', 'third_party/skia', '--header', 'skia/ext/skia_commit_hash.h'])
subprocess.call(['python', 'build/util/lastchange.py', '-m', 'GPU_LISTS_VERSION', '--revision-id-only', '--header', 'gpu/config/gpu_lists_version.h'])
@@ -93,7 +69,7 @@ def initUpstreamSubmodules():
chromium_ref = 'refs/tags/' + resolver.currentVersion()
os.chdir(qtwebengine_root)
- current_submodules = subprocess.check_output(['git', 'submodule'])
+ current_submodules = subprocess.check_output(['git', 'submodule']).decode()
if not 'src/3rdparty_upstream/gn' in current_submodules:
subprocess.call(['git', 'submodule', 'add', gn_url, 'src/3rdparty_upstream/gn'])
if not 'src/3rdparty_upstream/ninja' in current_submodules:
@@ -123,6 +99,7 @@ def initUpstreamSubmodules():
chromiumSubmodule.os = 'all'
chromiumSubmodule.initialize()
chromiumSubmodule.initSubmodules()
+ subprocess.call(['src/3rdparty_upstream/chromium/third_party/node/update_npm_deps'])
# Unstage repositories so we do not accidentally commit them.
subprocess.call(['git', 'reset', '-q', 'HEAD', 'src/3rdparty_upstream/gn'])
@@ -135,12 +112,31 @@ def initSnapshot():
snapshot.os = 'all'
snapshot.initialize()
+def initPackages():
+ # 'androidx' it is the only so far cipd package we need
+ third_party_upstream_chromium = os.path.join(qtwebengine_root, 'src/3rdparty_upstream/chromium')
+ currentDir = os.getcwd()
+ os.chdir(third_party_upstream_chromium)
+ cipd = CIPDPackage.CIPDEntity(third_party_upstream_chromium)
+ cipd_entites = cipd.readEntities()
+ for e in cipd_entites:
+ pkg = e.findPackage(CIPDPackage.androidx_package_name)
+ if pkg:
+ print('-- fetching and deploying ' + CIPDPackage.androidx_package_name)
+ pkg.fetchAndDeploy()
+ os.chdir(currentDir)
+
os.chdir(qtwebengine_root)
if args.upstream:
initUpstreamSubmodules()
updateLastChange()
if not args.baseline_upstream and not use_external_chromium:
- subprocess.call(['python', os.path.join(qtwebengine_root, 'tools', 'scripts', 'patch_upstream.py')])
+ subprocess.call(['python3', os.path.join(qtwebengine_root, 'tools', 'scripts', 'patch_upstream.py')])
if args.snapshot:
initSnapshot()
+if args.use_cipd:
+ cipdNotFound = subprocess.call(['which', 'cipd'])
+ if cipdNotFound:
+ raise Exception("You need cipd from depo tools.Try setting ./src/3rdparty_upstream/chromium/third_party/depot_tools/cipd in your PATH.")
+ initPackages()
diff --git a/tools/scripts/make_archive.sh b/tools/scripts/make_archive.sh
index a98061e65..fe61dfa2b 100755
--- a/tools/scripts/make_archive.sh
+++ b/tools/scripts/make_archive.sh
@@ -1,32 +1,6 @@
#!/bin/bash
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
if [ $# -ne 3 ]; then
echo "Usage: $0 git-ref release-name version"
diff --git a/tools/scripts/patch_upstream.py b/tools/scripts/patch_upstream.py
index b1fd78076..53f3fdb91 100755
--- a/tools/scripts/patch_upstream.py
+++ b/tools/scripts/patch_upstream.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 8b03076bc..e312dd64c 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -1,43 +1,18 @@
-#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+#!/usr/bin/env python3
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
import subprocess
import sys
-import imp
+import importlib
import errno
import shutil
from distutils.version import StrictVersion
import git_submodule as GitSubmodule
+import cipd_package as CIPDPackage
qtwebengine_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
os.chdir(qtwebengine_root)
@@ -58,10 +33,14 @@ def isInChromiumBlacklist(file_path):
if file_path.endswith('.gn') or file_path.endswith('.gni') or file_path.endswith('.typemap') or \
file_path.endswith('.mojom'):
return False
+ # Add android dependencies info so gn build tree can be parsed
+ if file_path.endswith('.info') or file_path.endswith('.pydeps'):
+ return False
+ if file_path.endswith('.mailmap') or file_path.endswith('.tat.gz.sha1'):
+ return True
if (file_path.startswith('android_webview')
or file_path.startswith('apps/')
or file_path.startswith('ash/')
- or file_path.startswith('base/android')
or file_path.startswith('buildtools/clang_format/script')
or file_path.startswith('buildtools/third_party/libc++')
or file_path.startswith('buildtools/third_party/libc++abi')
@@ -75,11 +54,19 @@ def isInChromiumBlacklist(file_path):
and not file_path.startswith('chrome/browser/custom_handlers/')
and not file_path.startswith('chrome/browser/devtools/')
and not file_path.startswith('chrome/browser/extensions/api/')
+ and not file_path.startswith('chrome/browser/gcm/')
and not file_path.startswith('chrome/browser/media/webrtc/')
and not file_path.startswith('chrome/browser/net/')
and not file_path.startswith('chrome/browser/prefs/')
and not file_path.startswith('chrome/browser/printing/')
+ and not file_path.startswith('chrome/browser/profiles/incognito_helpers')
+ and not file_path.startswith('chrome/browser/profiles/profile_keyed_service_factory')
+ and not file_path.startswith('chrome/browser/profiles/profile_selections')
+ and not file_path.startswith('chrome/browser/push_messaging/')
and not file_path.startswith('chrome/browser/renderer_host/')
+ and not file_path.startswith('chrome/browser/share/core/')
+ and not file_path.startswith('chrome/browser/share/proto/')
+ and not file_path.startswith('chrome/browser/signin/')
and not file_path.startswith('chrome/browser/spellchecker')
and not file_path.startswith('chrome/browser/tab_contents/')
and not file_path.startswith('chrome/browser/ui/webui/')
@@ -90,10 +77,12 @@ def isInChromiumBlacklist(file_path):
and not (file_path.startswith('chrome/common/')
and not file_path.startswith('chrome/common/extensions/docs'))
and not file_path.startswith('chrome/renderer/')
+ and not file_path.startswith('chrome/test/chromedriver/')
and not file_path.startswith('chrome/tools/convert_dict/')
and not file_path.endswith('.grd')
and not file_path.endswith('.grdp')
- and not file_path.endswith('chrome_version.rc.version'))
+ and not file_path.endswith('chrome_version.rc.version')
+ and not file_path.endswith('service_sandbox_type.h'))
or file_path.startswith('chrome_elf')
or file_path.startswith('chromecast')
or file_path.startswith('chromeos')
@@ -103,10 +92,9 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('components/cronet/')
or file_path.startswith('components/drive/')
or file_path.startswith('components/invalidation/')
- or file_path.startswith('components/gcm_driver/')
or file_path.startswith('components/nacl/')
or file_path.startswith('components/omnibox/')
- or file_path.startswith('components/policy/')
+ or file_path.startswith('components/policy/resources/')
or file_path.startswith('components/proximity_auth/')
or (file_path.startswith('components/resources/terms/')
and not file_path.endswith('terms_chromium.html'))
@@ -118,10 +106,10 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('components/translate/')
))
or file_path.startswith('content/public/android/java')
- or (file_path.startswith('content/shell')
- and not file_path.startswith('content/shell/common')
- and not file_path.endswith('.grd'))
+ or file_path.startswith('content/shell/android/')
+ or file_path.startswith('content/shell/browser/')
or file_path.startswith('courgette')
+ or file_path.startswith('docs/website/')
or file_path.startswith('google_update')
or file_path.startswith('ios')
or file_path.startswith('media/base/android/java')
@@ -130,7 +118,10 @@ def isInChromiumBlacklist(file_path):
or (file_path.startswith('net/data/')
and '_unittest/' in file_path)
or file_path.startswith('net/data/fuzzer_data/')
- or file_path.startswith('remoting')
+ or (file_path.startswith('remoting')
+ and not file_path.endswith('VERSION')
+ and not file_path.endswith('branding_Chromium')
+ and not file_path.endswith('remove_spaces.py'))
or file_path.startswith('rlz')
or file_path.startswith('testing/android')
or file_path.startswith('testing/buildbot')
@@ -139,6 +130,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/accessibility')
or file_path.startswith('third_party/afl')
or file_path.startswith('third_party/android_')
+ or file_path.startswith('third_party/androidx')
or file_path.startswith('third_party/angle/third_party/deqp')
or file_path.startswith('third_party/angle/third_party/glmark2')
or file_path.startswith('third_party/angle/third_party/VK-GL-CTS')
@@ -166,13 +158,61 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/chromite')
or file_path.startswith('third_party/colorama')
or file_path.startswith('third_party/depot_tools')
- or file_path.startswith('third_party/devtools-frontend/src/node-modules/')
+ or file_path.startswith('third_party/devtools-frontend/src/third_party/image_diff')
+ or (file_path.startswith('third_party/node/node_modules/')
+ and not file_path.startswith('third_party/node/node_modules/@babel/')
+ and not file_path.startswith('third_party/node/node_modules/@types/d3')
+ and not file_path.startswith('third_party/node/node_modules/@types/trusted-types/')
+ and not file_path.startswith('third_party/node/node_modules/ansi-styles/')
+ and not file_path.startswith('third_party/node/node_modules/balanced-match/')
+ and not file_path.startswith('third_party/node/node_modules/brace-expansion/')
+ and not file_path.startswith('third_party/node/node_modules/cancel-token/')
+ and not file_path.startswith('third_party/node/node_modules/chalk/')
+ and not file_path.startswith('third_party/node/node_modules/color-convert/')
+ and not file_path.startswith('third_party/node/node_modules/color-name/')
+ and not file_path.startswith('third_party/node/node_modules/commander/')
+ and not file_path.startswith('third_party/node/node_modules/concat-map/')
+ and not file_path.startswith('third_party/node/node_modules/cssbeautify/')
+ and not file_path.startswith('third_party/node/node_modules/debug/')
+ and not file_path.startswith('third_party/node/node_modules/escape-string-regexp/')
+ and not file_path.startswith('third_party/node/node_modules/esutils/')
+ and not file_path.startswith('third_party/node/node_modules/function-bind/')
+ and not file_path.startswith('third_party/node/node_modules/globals/')
+ and not file_path.startswith('third_party/node/node_modules/has-ansi/')
+ and not file_path.startswith('third_party/node/node_modules/has-flag/')
+ and not file_path.startswith('third_party/node/node_modules/has/')
+ and not file_path.startswith('third_party/node/node_modules/indent/')
+ and not file_path.startswith('third_party/node/node_modules/is-core-module/')
+ and not file_path.startswith('third_party/node/node_modules/is-windows/')
+ and not file_path.startswith('third_party/node/node_modules/@jridgewell/')
+ and not file_path.startswith('third_party/node/node_modules/js-tokens/')
+ and not file_path.startswith('third_party/node/node_modules/jsesc/')
+ and not file_path.startswith('third_party/node/node_modules/jsonschema/')
+ and not file_path.startswith('third_party/node/node_modules/lodash.camelcase/')
+ and not file_path.startswith('third_party/node/node_modules/lodash.sortby/')
+ and not file_path.startswith('third_party/node/node_modules/minimatch/')
+ and not file_path.startswith('third_party/node/node_modules/ms/')
+ and not file_path.startswith('third_party/node/node_modules/path-is-inside/')
+ and not file_path.startswith('third_party/node/node_modules/polymer-analyzer/')
+ and not file_path.startswith('third_party/node/node_modules/polymer-css-build/')
+ and not file_path.startswith('third_party/node/node_modules/resolve/')
+ and not file_path.startswith('third_party/node/node_modules/rollup/')
+ and not file_path.startswith('third_party/node/node_modules/shady-css-parser/')
+ and not file_path.startswith('third_party/node/node_modules/source-map/')
+ and not file_path.startswith('third_party/node/node_modules/stable/')
+ and not file_path.startswith('third_party/node/node_modules/supports-color/')
+ and not file_path.startswith('third_party/node/node_modules/terser/')
+ and not file_path.startswith('third_party/node/node_modules/to-fast-properties/')
+ and not file_path.startswith('third_party/node/node_modules/tr46/')
+ and not file_path.startswith('third_party/node/node_modules/typescript/')
+ and not file_path.startswith('third_party/node/node_modules/vscode-uri/')
+ and not file_path.startswith('third_party/node/node_modules/webidl-conversions/')
+ and not file_path.startswith('third_party/node/node_modules/whatwg-url/'))
or file_path.startswith('third_party/fuschsia-sdk/')
or file_path.startswith('third_party/glslang/src/Test/')
or file_path.startswith('third_party/google_')
or file_path.startswith('third_party/grpc/')
or file_path.startswith('third_party/hunspell_dictionaries')
- or file_path.startswith('third_party/icu/android')
or file_path.startswith('third_party/icu/cast')
or file_path.startswith('third_party/icu/chromeos')
or file_path.startswith('third_party/instrumented_libraries')
@@ -184,6 +224,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/libFuzzer')
or file_path.startswith('third_party/liblouis')
or file_path.startswith('third_party/libphonenumber')
+ or file_path.startswith('third_party/libunwindstack')
or file_path.startswith('third_party/logilab')
or file_path.startswith('third_party/markdown')
or file_path.startswith('third_party/openh264/src/res')
@@ -196,10 +237,11 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/sfntly/src/java')
or file_path.startswith('third_party/skia/docs/')
or file_path.startswith('third_party/skia/infra')
- or file_path.startswith('third_party/skia/site/dev/tools/calendar.mskp')
+ or file_path.startswith('third_party/skia/site/docs/dev/tools/calendar.mskp')
or file_path.startswith('third_party/sqlite/sqlite-src-')
or file_path.startswith('third_party/spirv-cross/spirv-cross/reference/')
or file_path.startswith('third_party/swiftshader/third_party/')
+ or file_path.startswith('third_party/tflite/')
or file_path.startswith('third_party/unrar')
or file_path.startswith('third_party/wayland')
or file_path.startswith('third_party/webgl')
@@ -236,6 +278,7 @@ def isInChromiumBlacklist(file_path):
or ('/test/' in file_path
and not '/webrtc/' in file_path
and not file_path.startswith('net/test/')
+ and not file_path.startswith('chrome/test/chromedriver/')
and not file_path.endswith('test_hook.h')
and not file_path.endswith('perftimer.h')
and not file_path.endswith('test-torque.tq')
@@ -262,7 +305,7 @@ def printProgress(current, total):
sys.stdout.write("\r{} of {}".format(current, total))
sys.stdout.flush()
-def copyFile(src, dst):
+def copyFile(src, dst, use_link = True, force_remove = False):
src = os.path.abspath(src)
dst = os.path.abspath(dst)
dst_dir = os.path.dirname(dst)
@@ -270,16 +313,19 @@ def copyFile(src, dst):
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir)
- if os.path.exists(dst):
+ if force_remove or os.path.exists(dst):
os.remove(dst)
try:
- os.link(src, dst)
+ if use_link:
+ os.link(src, dst)
+ else:
+ shutil.copy(src,dst)
# Qt uses LF-only but Chromium isn't.
subprocess.call(['dos2unix', '--keep-bom', '--quiet', dst])
except OSError as exception:
if exception.errno == errno.ENOENT:
- print 'file does not exist:' + src
+ print('file does not exist: ' + src)
else:
raise
@@ -289,10 +335,10 @@ third_party = os.path.join(qtwebengine_root, 'src/3rdparty')
def clearDirectory(directory):
currentDir = os.getcwd()
os.chdir(directory)
- print 'clearing the directory:' + directory
+ print('clearing the directory:' + directory)
for direntry in os.listdir(directory):
if not direntry == '.git' and os.path.isdir(direntry):
- print 'clearing:' + direntry
+ print('clearing:' + direntry)
shutil.rmtree(direntry)
os.chdir(currentDir)
@@ -306,17 +352,27 @@ def listFilesInCurrentRepository(use_deps=False):
files.append(os.path.join(submodule.pathRelativeToTopMostSupermodule(), submodule_file))
return files
+def listPackageFilesInCurrentRepositoryForPackage(packageName):
+ cipd = CIPDPackage.CIPDEntity(os.getcwd())
+ cipd_entities = cipd.readEntities()
+ files = []
+ for e in cipd_entities:
+ pkg = e.findPackage(CIPDPackage.androidx_package_name)
+ if pkg:
+ files.extend(pkg.listFiles())
+ return files
+
def exportGn():
third_party_upstream_gn = os.path.join(third_party_upstream, 'gn')
third_party_gn = os.path.join(third_party, 'gn')
os.makedirs(third_party_gn);
- print 'exporting contents of:' + third_party_upstream_gn
+ print('exporting contents of:' + third_party_upstream_gn)
os.chdir(third_party_upstream_gn)
files = listFilesInCurrentRepository()
- print 'copying files to ' + third_party_gn
- for i in xrange(len(files)):
+ print('copying files to ' + third_party_gn)
+ for i in range(len(files)):
printProgress(i+1, len(files))
- f = files[i]
+ f = files[i].decode()
if not isInGitBlacklist(f):
copyFile(f, os.path.join(third_party_gn, f))
print("")
@@ -325,13 +381,13 @@ def exportNinja():
third_party_upstream_ninja = os.path.join(third_party_upstream, 'ninja')
third_party_ninja = os.path.join(third_party, 'ninja')
os.makedirs(third_party_ninja);
- print 'exporting contents of:' + third_party_upstream_ninja
+ print('exporting contents of:' + third_party_upstream_ninja)
os.chdir(third_party_upstream_ninja)
files = listFilesInCurrentRepository()
- print 'copying files to ' + third_party_ninja
- for i in xrange(len(files)):
+ print('copying files to ' + third_party_ninja)
+ for i in range(len(files)):
printProgress(i+1, len(files))
- f = files[i]
+ f = files[i].decode()
if not isInGitBlacklist(f):
copyFile(f, os.path.join(third_party_ninja, f))
print("")
@@ -340,36 +396,60 @@ def exportChromium():
third_party_upstream_chromium = os.path.join(third_party_upstream, 'chromium')
third_party_chromium = os.path.join(third_party, 'chromium')
os.makedirs(third_party_chromium);
- print 'exporting contents of:' + third_party_upstream_chromium
+ print('exporting contents of:' + third_party_upstream_chromium)
os.chdir(third_party_upstream_chromium)
files = listFilesInCurrentRepository(True)
# Add LASTCHANGE files which are not tracked by git.
- files.append('build/util/LASTCHANGE')
- files.append('build/util/LASTCHANGE.committime')
- files.append('skia/ext/skia_commit_hash.h')
- files.append('gpu/config/gpu_lists_version.h')
- print 'copying files to ' + third_party_chromium
- for i in xrange(len(files)):
+ files.append(b'build/util/LASTCHANGE')
+ files.append(b'build/util/LASTCHANGE.committime')
+ files.append(b'skia/ext/skia_commit_hash.h')
+ files.append(b'gpu/config/gpu_lists_version.h')
+
+ files.extend(listPackageFilesInCurrentRepositoryForPackage(CIPDPackage.androidx_package_name))
+
+ for root, directories, local_files in os.walk(third_party_upstream_chromium + '/third_party/node/node_modules'):
+ for name in local_files:
+ f = os.path.relpath(os.path.join(root, name))
+ files.append(f)
+
+ symlinks = []
+ print('copying files to ' + third_party_chromium)
+ for i in range(len(files)):
printProgress(i+1, len(files))
- f = files[i]
+ if isinstance(files[i], bytes):
+ f = files[i].decode()
+ else:
+ f = files[i]
if not isInChromiumBlacklist(f) and not isInGitBlacklist(f):
- copyFile(f, os.path.join(third_party_chromium, f))
+ d = os.path.join(third_party_chromium, f)
+ copyFile(f,d)
+ # make sure we did not make a hardlink of symlink which is broken afterwards
+ if os.path.islink(f):
+ symlinks.append((f,d))
+ # this is mostly used for files coming from cipd packages
+ for s in symlinks:
+ if not os.path.exists(s[1]):
+ print('fixing ivalid link ' + s[1])
+ copyFile(s[0],s[1], use_link = False, force_remove = True)
+
+ # We need to gzip transport_security_state_static.json since it is otherwise too big for our git configuration:
+ subprocess.call(['gzip', '-n', third_party_chromium + '/net/http/transport_security_state_static.json'])
print("")
commandNotFound = subprocess.call(['which', 'dos2unix'])
if not commandNotFound:
- dos2unixVersion , err = subprocess.Popen(['dos2unix', '-V', '| true'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+ 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])
+ dos2unixVersion = StrictVersion(dos2unixVersion.splitlines()[0].split()[1].decode())
if commandNotFound or dos2unixVersion < StrictVersion('6.0.6'):
raise Exception("You need dos2unix version 6.0.6 minimum.")
os.chdir(third_party)
ignore_case_setting = subprocess.Popen(['git', 'config', '--get', 'core.ignorecase'], stdout=subprocess.PIPE).communicate()[0]
-if 'true' in ignore_case_setting:
+if b'true' in ignore_case_setting:
raise Exception("Your 3rdparty repository is configured to ignore case. "
"A snapshot created with these settings would cause problems on case sensitive file systems.")
@@ -379,5 +459,5 @@ exportGn()
exportNinja()
exportChromium()
-print 'done.'
+print('done.')
diff --git a/tools/scripts/update_change_ids.py b/tools/scripts/update_change_ids.py
index 481d8424d..64149d2b6 100755
--- a/tools/scripts/update_change_ids.py
+++ b/tools/scripts/update_change_ids.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import subprocess
diff --git a/tools/scripts/version_resolver.py b/tools/scripts/version_resolver.py
index d339b72dd..a29ee34e8 100644
--- a/tools/scripts/version_resolver.py
+++ b/tools/scripts/version_resolver.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
@@ -35,11 +9,42 @@ import shutil
import subprocess
import sys
import json
-import urllib2
+import urllib3
import git_submodule as GitSubmodule
-
-chromium_version = '90.0.4430.228'
-chromium_branch = '4430'
+from abc import ABC, abstractmethod
+
+class DEPSParser(ABC):
+ def __init__(self):
+ self.global_scope = {
+ 'Var': lambda var_name: '{%s}' % var_name,
+ 'Str': str,
+ 'deps_os': {},
+ }
+ self.local_scope = {}
+ self.topmost_supermodule_path_prefix = ''
+
+ def subdir(self, dep):
+ if dep.startswith('src/'):
+ return dep[4:]
+ # Don't skip submodules that have a supermodule path prefix set (at the moment these
+ # are 2nd level deep submodules).
+ elif not self.topmost_supermodule_path_prefix:
+ # Ignore the information about chromium itself since we get that from git,
+ # also ignore anything outside src/ (e.g. depot_tools)
+ return None
+ else:
+ return dep
+
+ @abstractmethod
+ def parse(self):
+ pass
+
+ def get_recursedeps(self):
+ return self.local_scope["recursedeps"]
+
+
+chromium_version = '118.0.5993.220'
+chromium_branch = '5993'
ninja_version = 'v1.8.2'
json_url = 'http://omahaproxy.appspot.com/all.json'
@@ -49,20 +54,18 @@ snapshot_src_dir = os.path.abspath(os.path.join(qtwebengine_root, 'src/3rdparty'
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'
- , 'chrome/tools/test/reference_build/chrome_mac'
- , 'chrome/tools/test/reference_build/chrome_linux'
- , 'chrome/tools/test/reference_build/chrome_win'
- # buildtools duplicates:
- , 'buildtools/clang_format/script'
- , 'buildtools/linux64'
- , 'buildtools/mac'
- , 'buildtools/win'
- , 'buildtools/third_party/libc++/trunk'
- , 'buildtools/third_party/libc++abi/trunk'
- , 'buildtools/third_party/libunwind/trunk'
- ]
+ 'buildtools/clang_format/script',
+ 'buildtools/third_party/libc++/trunk',
+ 'buildtools/third_party/libc++abi/trunk',
+ 'buildtools/third_party/libunwind/trunk',
+ 'chrome/browser/resources/chromeos/quickoffice',
+ 'remoting/host/installer/linux/internal',
+ 'third_party/widevine/cdm/chromeos',
+ 'third_party/widevine/cdm/linux',
+ 'third_party/widevine/test/license_server',
+ 'ui/file_manager/internal'
+]
+submodule_whitelist = [ 'src/third_party/android_ndk' , 'src/third_party/libunwindstack' ]
sys.path.append(os.path.join(qtwebengine_root, 'tools', 'scripts'))
@@ -85,11 +88,11 @@ def readReleaseChannels():
channels[os].append({ 'channel': ver['channel'], 'version': ver['version'], 'branch': ver['true_branch'] })
return channels
-def readSubmodules():
+def read(parserCls):
git_deps = subprocess.check_output(['git', 'show', chromium_version +':DEPS'])
- parser = GitSubmodule.DEPSParser()
- git_submodules = parser.parse(git_deps)
+ parser = parserCls()
+ git_submodules = parser.parse(git_deps, submodule_whitelist)
submodule_dict = {}
@@ -106,7 +109,7 @@ def readSubmodules():
with open(extra_deps_file_path, 'r') as extra_deps_file:
extra_deps = extra_deps_file.read()
if extra_deps:
- extradeps_parser = GitSubmodule.DEPSParser()
+ extradeps_parser = parserCls()
extradeps_parser.topmost_supermodule_path_prefix = extradeps_dir
extradeps_submodules = extradeps_parser.parse(extra_deps)
for sub in extradeps_submodules:
@@ -171,7 +174,7 @@ def resetUpstream():
chromium = GitSubmodule.Submodule()
chromium.path = "."
- submodules = chromium.readSubmodules()
+ submodules = chromium.readSubmodules(True)
submodules.append(chromium)
print('-- resetting upstream submodules in ' + os.path.relpath(target_dir) + ' to baseline --')
diff --git a/tools/scripts/windeploy-examples.py b/tools/scripts/windeploy-examples.py
index 3b2b42318..ef0e195aa 100755
--- a/tools/scripts/windeploy-examples.py
+++ b/tools/scripts/windeploy-examples.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2015 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtWebEngine module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## 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 https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2015 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import argparse
import os