summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/examples.pro12
-rw-r--r--examples/webengine/customdialogs/MessageRectangle.qml55
-rw-r--r--examples/webengine/customdialogs/SwitchButton.qml60
-rw-r--r--examples/webengine/customdialogs/WebView.qml125
-rw-r--r--examples/webengine/customdialogs/customdialogs.pro18
-rw-r--r--examples/webengine/customdialogs/customdialogs.qrc24
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-auth1.pngbin0 -> 6453 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-auth2.pngbin0 -> 7983 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-color1.pngbin0 -> 20401 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-color2.pngbin0 -> 6609 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-file1.pngbin0 -> 15736 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-file2.pngbin0 -> 9036 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-menu.pngbin0 -> 5484 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-prompt1.pngbin0 -> 5509 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-prompt2.pngbin0 -> 7839 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-validation1.pngbin0 -> 12523 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs-validation2.pngbin0 -> 12171 bytes
-rw-r--r--examples/webengine/customdialogs/doc/images/customdialogs.pngbin0 -> 11764 bytes
-rw-r--r--examples/webengine/customdialogs/doc/src/customdialogs.qdoc337
-rw-r--r--examples/webengine/customdialogs/forms/Authentication.qml68
-rw-r--r--examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml161
-rw-r--r--examples/webengine/customdialogs/forms/Button.qml98
-rw-r--r--examples/webengine/customdialogs/forms/ColorCell.qml53
-rw-r--r--examples/webengine/customdialogs/forms/ColorPicker.qml68
-rw-r--r--examples/webengine/customdialogs/forms/ColorPickerForm.ui.qml225
-rw-r--r--examples/webengine/customdialogs/forms/FilePicker.qml81
-rw-r--r--examples/webengine/customdialogs/forms/FilePickerForm.ui.qml167
-rw-r--r--examples/webengine/customdialogs/forms/FileRow.qml82
-rw-r--r--examples/webengine/customdialogs/forms/JavaScript.qml81
-rw-r--r--examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml149
-rw-r--r--examples/webengine/customdialogs/forms/Menu.qml59
-rw-r--r--examples/webengine/customdialogs/forms/MenuForm.ui.qml103
-rw-r--r--examples/webengine/customdialogs/icon.svg24
-rw-r--r--examples/webengine/customdialogs/index.html53
-rw-r--r--examples/webengine/customdialogs/main.cpp75
-rw-r--r--examples/webengine/customdialogs/main.qml90
-rw-r--r--examples/webengine/customdialogs/server.cpp75
-rw-r--r--examples/webengine/customdialogs/server.h65
-rw-r--r--examples/webengine/customdialogs/style.css37
-rw-r--r--examples/webengine/quicknanobrowser/quicknanobrowser.pro2
-rw-r--r--examples/webengine/recipebrowser/doc/images/recipebrowser-demo.jpgbin0 -> 33398 bytes
-rw-r--r--examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc216
-rw-r--r--examples/webengine/recipebrowser/main.cpp66
-rw-r--r--examples/webengine/recipebrowser/recipebrowser.pro14
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md23
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md12
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/markdown.css260
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/marked.min.js6
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/custom.css65
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/custom.js57
-rw-r--r--examples/webengine/recipebrowser/resources/pages/burger.html76
-rw-r--r--examples/webengine/recipebrowser/resources/pages/cupcakes.html54
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/burger.jpgbin0 -> 48882 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/cupcakes.jpgbin0 -> 38653 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/pasta.jpgbin0 -> 42411 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/pizza.jpgbin0 -> 49068 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/skewers.jpgbin0 -> 49246 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/soup.jpgbin0 -> 49028 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/images/steak.jpgbin0 -> 49202 bytes
-rw-r--r--examples/webengine/recipebrowser/resources/pages/pasta.html57
-rw-r--r--examples/webengine/recipebrowser/resources/pages/pizza.html48
-rw-r--r--examples/webengine/recipebrowser/resources/pages/skewers.html54
-rw-r--r--examples/webengine/recipebrowser/resources/pages/soup.html42
-rw-r--r--examples/webengine/recipebrowser/resources/pages/steak.html68
-rw-r--r--examples/webengine/recipebrowser/resources/qml/RecipeList.qml162
-rw-r--r--examples/webengine/recipebrowser/resources/qml/main.qml158
-rw-r--r--examples/webengine/recipebrowser/resources/resources.qrc28
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.cpp53
-rw-r--r--examples/webenginewidgets/demobrowser/browsermainwindow.h15
-rw-r--r--examples/webenginewidgets/demobrowser/webview.cpp6
-rw-r--r--examples/webenginewidgets/demobrowser/webview.h1
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc9
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp1
-rw-r--r--examples/webenginewidgets/spellchecker/data/icon.svg24
-rw-r--r--examples/webenginewidgets/spellchecker/data/index.html33
-rw-r--r--examples/webenginewidgets/spellchecker/data/spellchecker.qrc7
-rw-r--r--examples/webenginewidgets/spellchecker/data/style.css90
-rw-r--r--examples/webenginewidgets/spellchecker/dict/de/README.txt20
-rw-r--r--examples/webenginewidgets/spellchecker/dict/de/de-DE.aff5
-rw-r--r--examples/webenginewidgets/spellchecker/dict/de/de-DE.dic14
-rw-r--r--examples/webenginewidgets/spellchecker/dict/en/README.txt16
-rw-r--r--examples/webenginewidgets/spellchecker/dict/en/en-US.aff5
-rw-r--r--examples/webenginewidgets/spellchecker/dict/en/en-US.dic11
-rw-r--r--examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.pngbin0 -> 15978 bytes
-rw-r--r--examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc139
-rw-r--r--examples/webenginewidgets/spellchecker/main.cpp54
-rw-r--r--examples/webenginewidgets/spellchecker/spellchecker.pro63
-rw-r--r--examples/webenginewidgets/spellchecker/webview.cpp96
-rw-r--r--examples/webenginewidgets/spellchecker/webview.h60
89 files changed, 4598 insertions, 37 deletions
diff --git a/examples/examples.pro b/examples/examples.pro
index 0de2ec505..1a0f3a263 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -2,6 +2,7 @@ TEMPLATE=subdirs
qtHaveModule(webengine) {
SUBDIRS += \
+ webengine/customdialogs \
webengine/minimal \
webengine/quicknanobrowser
}
@@ -13,5 +14,14 @@ qtHaveModule(webenginewidgets) {
webenginewidgets/cookiebrowser \
webenginewidgets/demobrowser \
webenginewidgets/markdowneditor \
- webenginewidgets/simplebrowser \
+ webenginewidgets/simplebrowser
+
+ contains(WEBENGINE_CONFIG, use_spellchecker):!cross_compile {
+ !contains(WEBENGINE_CONFIG, use_native_spellchecker) {
+ SUBDIRS += webenginewidgets/spellchecker
+ } else {
+ message("Spellcheck example will not be built because it depends on usage of Hunspell dictionaries.")
+ }
+ }
+
}
diff --git a/examples/webengine/customdialogs/MessageRectangle.qml b/examples/webengine/customdialogs/MessageRectangle.qml
new file mode 100644
index 000000000..e0ace7ca5
--- /dev/null
+++ b/examples/webengine/customdialogs/MessageRectangle.qml
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+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/webengine/customdialogs/SwitchButton.qml b/examples/webengine/customdialogs/SwitchButton.qml
new file mode 100644
index 000000000..75a2c6452
--- /dev/null
+++ b/examples/webengine/customdialogs/SwitchButton.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Controls 1.4 as Controls
+import QtQuick.Layouts 1.3
+
+Item {
+ width: parent.width
+ height: 40
+ property alias checked: switcher.checked
+ RowLayout {
+ anchors.centerIn: parent
+ Text {
+ text: qsTr("Use default dialogs")
+ font.pointSize: 12
+ }
+ Controls.Switch {
+ id: switcher
+ checked: true
+ }
+ }
+}
diff --git a/examples/webengine/customdialogs/WebView.qml b/examples/webengine/customdialogs/WebView.qml
new file mode 100644
index 000000000..591789caa
--- /dev/null
+++ b/examples/webengine/customdialogs/WebView.qml
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtWebEngine 1.4
+
+WebEngineView {
+
+ url: "qrc:/index.html"
+ property bool useDefaultDialogs: true
+ signal openForm(var form)
+
+ onContextMenuRequested: function(request) {
+ // we only show menu for links with #openMenu
+ if (!request.linkUrl.toString().endsWith("#openMenu")) {
+ request.accepted = true;
+ return;
+ }
+ // return early to show default menu
+ if (useDefaultDialogs)
+ return;
+
+ request.accepted = true;
+ openForm({item: Qt.resolvedUrl("forms/Menu.qml"),
+ properties: {"request": request}});
+ }
+
+ onAuthenticationDialogRequested: function(request) {
+ if (useDefaultDialogs)
+ return;
+
+ request.accepted = true;
+ openForm({item: Qt.resolvedUrl("forms/Authentication.qml"),
+ properties: {"request": request}});
+ }
+
+ onJavaScriptDialogRequested: function(request) {
+ if (useDefaultDialogs)
+ return;
+
+ request.accepted = true;
+ openForm({item: Qt.resolvedUrl("forms/JavaScript.qml"),
+ properties: {"request": request}});
+ }
+
+ onColorDialogRequested: function(request) {
+ if (useDefaultDialogs)
+ return;
+
+ request.accepted = true;
+ openForm({item: Qt.resolvedUrl("forms/ColorPicker.qml"),
+ properties: {"request": request}});
+ }
+
+ onFileDialogRequested: function(request) {
+ if (useDefaultDialogs)
+ return;
+
+ request.accepted = true;
+ openForm({item: Qt.resolvedUrl("forms/FilePicker.qml"),
+ properties: {"request": request}});
+
+ }
+
+ onFormValidationMessageRequested: function(request) {
+ switch (request.type) {
+ case FormValidationMessageRequest.Show:
+ if (useDefaultDialogs)
+ return;
+
+ request.accepted = true;
+ validationMessage.text = request.text;
+ validationMessage.y = request.anchor.y + request.anchor.height + 10;
+ validationMessage.visible = true;
+ break;
+ case FormValidationMessageRequest.Move:
+ break;
+ case FormValidationMessageRequest.Hide:
+ validationMessage.visible = false;
+ break;
+ }
+ }
+
+ MessageRectangle {
+ id: validationMessage
+ z: 1
+ }
+}
diff --git a/examples/webengine/customdialogs/customdialogs.pro b/examples/webengine/customdialogs/customdialogs.pro
new file mode 100644
index 000000000..5861f3af7
--- /dev/null
+++ b/examples/webengine/customdialogs/customdialogs.pro
@@ -0,0 +1,18 @@
+QT += webengine
+
+HEADERS += \
+ server.h
+
+SOURCES += \
+ main.cpp \
+ server.cpp
+
+RESOURCES += \
+ customdialogs.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webengine/customdialogs
+INSTALLS += target
+
+qtHaveModule(widgets) {
+ QT += widgets # QApplication is required to get native styling with QtQuickControls
+}
diff --git a/examples/webengine/customdialogs/customdialogs.qrc b/examples/webengine/customdialogs/customdialogs.qrc
new file mode 100644
index 000000000..5ab5b11cd
--- /dev/null
+++ b/examples/webengine/customdialogs/customdialogs.qrc
@@ -0,0 +1,24 @@
+<RCC>
+ <qresource prefix="/">
+ <file>forms/AuthenticationForm.ui.qml</file>
+ <file>forms/Authentication.qml</file>
+ <file>forms/Button.qml</file>
+ <file>forms/ColorCell.qml</file>
+ <file>forms/ColorPickerForm.ui.qml</file>
+ <file>forms/ColorPicker.qml</file>
+ <file>forms/FilePickerForm.ui.qml</file>
+ <file>forms/FilePicker.qml</file>
+ <file>forms/FileRow.qml</file>
+ <file>forms/JavaScriptForm.ui.qml</file>
+ <file>forms/JavaScript.qml</file>
+ <file>forms/MenuForm.ui.qml</file>
+ <file>forms/Menu.qml</file>
+ <file>icon.svg</file>
+ <file>index.html</file>
+ <file>main.qml</file>
+ <file>MessageRectangle.qml</file>
+ <file>style.css</file>
+ <file>SwitchButton.qml</file>
+ <file>WebView.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-auth1.png b/examples/webengine/customdialogs/doc/images/customdialogs-auth1.png
new file mode 100644
index 000000000..2bde8bd8e
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-auth1.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-auth2.png b/examples/webengine/customdialogs/doc/images/customdialogs-auth2.png
new file mode 100644
index 000000000..ce358fca0
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-auth2.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-color1.png b/examples/webengine/customdialogs/doc/images/customdialogs-color1.png
new file mode 100644
index 000000000..a51d1bdd3
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-color1.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-color2.png b/examples/webengine/customdialogs/doc/images/customdialogs-color2.png
new file mode 100644
index 000000000..3b0b2e986
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-color2.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-file1.png b/examples/webengine/customdialogs/doc/images/customdialogs-file1.png
new file mode 100644
index 000000000..0ff39bf38
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-file1.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-file2.png b/examples/webengine/customdialogs/doc/images/customdialogs-file2.png
new file mode 100644
index 000000000..e56078c44
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-file2.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-menu.png b/examples/webengine/customdialogs/doc/images/customdialogs-menu.png
new file mode 100644
index 000000000..3409c951c
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-menu.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-prompt1.png b/examples/webengine/customdialogs/doc/images/customdialogs-prompt1.png
new file mode 100644
index 000000000..988b4deea
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-prompt1.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-prompt2.png b/examples/webengine/customdialogs/doc/images/customdialogs-prompt2.png
new file mode 100644
index 000000000..085339378
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-prompt2.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-validation1.png b/examples/webengine/customdialogs/doc/images/customdialogs-validation1.png
new file mode 100644
index 000000000..38fa86235
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-validation1.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs-validation2.png b/examples/webengine/customdialogs/doc/images/customdialogs-validation2.png
new file mode 100644
index 000000000..247d2711b
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs-validation2.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/images/customdialogs.png b/examples/webengine/customdialogs/doc/images/customdialogs.png
new file mode 100644
index 000000000..13322d2f6
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/images/customdialogs.png
Binary files differ
diff --git a/examples/webengine/customdialogs/doc/src/customdialogs.qdoc b/examples/webengine/customdialogs/doc/src/customdialogs.qdoc
new file mode 100644
index 000000000..f5a18b591
--- /dev/null
+++ b/examples/webengine/customdialogs/doc/src/customdialogs.qdoc
@@ -0,0 +1,337 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webengine/customdialogs
+ \title WebEngine Qt Quick Custom Dialogs Example
+ \ingroup webengine-examples
+ \brief Customizes UI elements of Qt WebEngine'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
+ \li Form Validation Message
+ \endlist
+
+ \section1 Triggering Dialogs
+
+ The technical details on how the dialogs are triggered are beyond the scope
+ of this example. The only thing worth mentioning is that we fire up the
+ localhost TCP server when the example starts up. The server is needed to
+ get proxy and HTTP authentication requests.
+
+ \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 webengine/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 webengine/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
+ \li FormValidationMessageRequest
+ \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 webengine/customdialogs/WebView.qml
+ \skipto WebEngineView
+ \printuntil {
+ \dots 4
+ \skipto onContextMenuRequested
+ \printuntil }
+ \printuntil }
+ \printuntil }
+ \dots 4
+ \skipuntil onFormValidationMessageRequested
+ \skipuntil }
+ \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 webengine/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 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 webengine/customdialogs/WebView.qml
+ \skipto WebEngineView
+ \printuntil {
+ \dots 4
+ \skipto onAuthenticationDialogRequested
+ \printuntil }
+ \printuntil }
+ \dots 4
+ \skipuntil onFormValidationMessageRequested
+ \skipuntil }
+ \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 webengine/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 webengine/customdialogs/WebView.qml
+ \skipto WebEngineView
+ \printuntil {
+ \dots 4
+ \skipto onJavaScriptDialogRequested
+ \printuntil }
+ \printuntil }
+ \dots 4
+ \skipuntil onFormValidationMessageRequested
+ \skipuntil }
+ \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 webengine/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 webengine/customdialogs/WebView.qml
+ \skipto WebEngineView
+ \printuntil {
+ \dots 4
+ \skipto onColorDialogRequested
+ \printuntil }
+ \printuntil }
+ \dots 4
+ \skipuntil onFormValidationMessageRequested
+ \skipuntil }
+ \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 webengine/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 webengine/customdialogs/WebView.qml
+ \skipto WebEngineView
+ \printuntil {
+ \dots 4
+ \skipto onFileDialogRequested
+ \printuntil }
+ \printuntil }
+ \dots 4
+ \skipuntil onFormValidationMessageRequested
+ \skipuntil }
+ \skipuntil }
+ \skipuntil }
+ \skipto }
+ \printline }
+
+ We use the \c onFileDialogRequested 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 FilePickerForm:
+
+ \image customdialogs-file2.png
+
+ \quotefromfile webengine/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.
+
+ \section2 Form Validation Message Requests
+
+ \image customdialogs-validation1.png
+
+ \l [QML]{FormValidationMessageRequest} is a request object that is passed as a
+ parameter of the WebEngineView::formValidationMessageRequested signal:
+
+ \quotefromfile webengine/customdialogs/WebView.qml
+ \skipto WebEngineView
+ \printuntil url
+ \dots 4
+ \skipto onFormValidationMessageRequested
+ \printuntil }
+ \printuntil }
+ \printuntil }
+ \skipto }
+ \printline }
+
+ We use the \c onFormValidationMessageRequested signal handler to check
+ whether we should use the default message bubble. If not, we accept the
+ request and customize \c validationMessage. Depending on the type of the
+ request, we show, move, or hide the message.
+
+ \image customdialogs-validation2.png
+*/
diff --git a/examples/webengine/customdialogs/forms/Authentication.qml b/examples/webengine/customdialogs/forms/Authentication.qml
new file mode 100644
index 000000000..8ee0a416f
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/Authentication.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtWebEngine 1.4
+
+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/webengine/customdialogs/forms/AuthenticationForm.ui.qml b/examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml
new file mode 100644
index 000000000..0ba27acdb
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/AuthenticationForm.ui.qml
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 1.0 as Controls
+
+Item {
+ id: item1
+ property alias cancelButton: cancelButton
+ property alias loginButton: loginButton
+ property alias userName: userName
+ property alias password: password
+
+ 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
+ anchors.rightMargin: 0
+ anchors.leftMargin: 0
+ anchors.right: parent.right
+ anchors.left: parent.left
+ gradient: Gradient {
+ GradientStop {
+ position: 0
+ color: "#25a6e2"
+ }
+ GradientStop {
+ color: "#188bd0"
+ }
+ }
+
+ Text {
+ id: textArea
+ x: 54
+ y: 5
+ color: "#ffffff"
+ text: qsTr("Restricted Area")
+ font.pointSize: 12
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Item {
+ width: 40
+ height: 40
+ }
+
+ Text {
+ id: userNameText
+ text: qsTr("Username:")
+ font.pointSize: 12
+ }
+
+ Controls.TextField {
+ id: userName
+ width: 300
+ height: 22
+ Layout.fillWidth: true
+ font.pointSize: 12
+ }
+
+ Text {
+ id: passwordText
+ text: qsTr("Password:")
+ font.pointSize: 12
+ }
+
+ Controls.TextField {
+ id: password
+ width: 300
+ height: 26
+ Layout.fillWidth: true
+ font.pointSize: 12
+ }
+
+ Item {
+ Layout.fillHeight: true
+ }
+
+ RowLayout {
+ id: rowLayout
+ width: 100
+ height: 100
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Button {
+ id: cancelButton
+ width: 90
+ height: 30
+ btnText: qsTr("Cancel")
+ btnBlue: false
+ }
+
+ Button {
+ id: loginButton
+ width: 90
+ height: 30
+ btnText: qsTr("Login")
+ btnBlue: false
+ }
+ }
+ }
+}
diff --git a/examples/webengine/customdialogs/forms/Button.qml b/examples/webengine/customdialogs/forms/Button.qml
new file mode 100644
index 000000000..8ae0865d1
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/Button.qml
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+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/webengine/customdialogs/forms/ColorCell.qml b/examples/webengine/customdialogs/forms/ColorCell.qml
new file mode 100644
index 000000000..197cca3d3
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/ColorCell.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+Rectangle {
+ id: rectangle
+ width: 50
+ height: 50
+ signal clicked()
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: rectangle.clicked(color)
+ }
+}
diff --git a/examples/webengine/customdialogs/forms/ColorPicker.qml b/examples/webengine/customdialogs/forms/ColorPicker.qml
new file mode 100644
index 000000000..d4ab1abae
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/ColorPicker.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.[B"
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+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/webengine/customdialogs/forms/ColorPickerForm.ui.qml b/examples/webengine/customdialogs/forms/ColorPickerForm.ui.qml
new file mode 100644
index 000000000..d50f727f1
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/ColorPickerForm.ui.qml
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.3
+
+Item {
+ property alias cancelButton: cancelButton
+ property alias okButton: okButton
+ property string message: "Message"
+ property string title: "Title"
+ property alias blue1: blue1
+ property alias grid: grid
+ property alias colorPicker: colorPicker
+
+ 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 {
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ source: "qrc:/icon.svg"
+ }
+
+ Rectangle {
+ height: 30
+ anchors.rightMargin: 0
+ anchors.leftMargin: 0
+ anchors.right: parent.right
+ anchors.left: parent.left
+ gradient: Gradient {
+ GradientStop {
+ position: 0
+ color: "#25a6e2"
+ }
+
+ GradientStop {
+ color: "#188bd0"
+ }
+ }
+
+ Text {
+ id: title
+ x: 54
+ y: 5
+ color: "#ffffff"
+ text: qsTr("Select Color")
+ font.pointSize: 12
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Item {
+ width: 40
+ height: 40
+ }
+
+ GridLayout {
+ id: grid
+ columns: 5
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ ColorCell {
+ id: blue1
+ color: "#26d5f8"
+ }
+ ColorCell {
+ id: green1
+ color: "#25f93d"
+ }
+ ColorCell {
+ id: red1
+ color: "#f71111"
+ }
+ ColorCell {
+ id: yellow1
+ color: "#faf23c"
+ }
+ ColorCell {
+ id: orange1
+ color: "#ec8505"
+ }
+ ColorCell {
+ id: blue2
+ color: "#037eaa"
+ }
+ ColorCell {
+ id: green2
+ color: "#389a13"
+ }
+ ColorCell {
+ id: red2
+ color: "#b2001b"
+ }
+ ColorCell {
+ id: yellow2
+ color: "#caca03"
+ }
+ ColorCell {
+ id: orange2
+ color: "#bb4900"
+ }
+ ColorCell {
+ id: blue3
+ color: "#01506c"
+ }
+ ColorCell {
+ id: green3
+ color: "#37592b"
+ }
+ ColorCell {
+ id: red3
+ color: "#700113"
+ }
+ ColorCell {
+ id: yellow3
+ color: "#848404"
+ }
+
+ ColorCell {
+ id: orange3
+ color: "#563100"
+ }
+ }
+
+ Item {
+ width: 10
+ height: 10
+ }
+
+ Rectangle {
+ width: 90
+ height: 90
+ color: "#000000"
+ radius: 4
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ Rectangle {
+ id: colorPicker
+ height: 80
+ color: "#ffffff"
+ anchors.rightMargin: 5
+ anchors.leftMargin: 5
+ anchors.bottomMargin: 5
+ anchors.topMargin: 5
+ anchors.fill: parent
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ }
+
+ RowLayout {
+ id: rowLayout
+ width: 100
+ height: 100
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Button {
+ id: cancelButton
+ width: 90
+ height: 30
+ btnText: qsTr("Cancel")
+ btnBlue: false
+ }
+
+ Button {
+ id: okButton
+ width: 90
+ height: 30
+ btnText: qsTr("OK")
+ btnBlue: false
+ }
+ }
+ }
+}
diff --git a/examples/webengine/customdialogs/forms/FilePicker.qml b/examples/webengine/customdialogs/forms/FilePicker.qml
new file mode 100644
index 000000000..e459a5ceb
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/FilePicker.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+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/webengine/customdialogs/forms/FilePickerForm.ui.qml b/examples/webengine/customdialogs/forms/FilePickerForm.ui.qml
new file mode 100644
index 000000000..67c9821b2
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/FilePickerForm.ui.qml
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.3
+
+Item {
+ property alias cancelButton: cancelButton
+ property alias okButton: okButton
+ property string message: "Message"
+ property string title: "Title"
+ property alias files: files
+
+ 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
+ anchors.rightMargin: 0
+ anchors.leftMargin: 0
+ anchors.right: parent.right
+ anchors.left: parent.left
+ gradient: Gradient {
+ GradientStop {
+ position: 0
+ color: "#25a6e2"
+ }
+
+ GradientStop {
+ color: "#188bd0"
+ }
+ }
+
+ Text {
+ id: title
+ x: 54
+ y: 5
+ color: "#ffffff"
+ text: qsTr("Select File")
+ font.pointSize: 12
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Item {
+ width: 40
+ height: 40
+ }
+
+ ColumnLayout {
+ id: files
+
+ FileRow {
+ id: filename1
+ text: "example.qdoc"
+ }
+
+ FileRow {
+ id: filename2
+ text: "factory.cpp"
+ }
+
+ FileRow {
+ id: filename3
+ text: "index.html"
+ }
+
+ FileRow {
+ id: filename4
+ text: "main.qml"
+ }
+
+ FileRow {
+ id: filename5
+ text: "qt-logo.png"
+ }
+
+ FileRow {
+ id: filename6
+ text: "window.h"
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ }
+
+ RowLayout {
+ id: rowLayout
+ width: 20
+ height: 100
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Button {
+ id: cancelButton
+ width: 90
+ height: 30
+ btnText: qsTr("Cancel")
+ btnBlue: false
+ }
+
+ Button {
+ id: okButton
+ width: 90
+ height: 30
+ btnText: qsTr("OK")
+ btnBlue: false
+ }
+ }
+ }
+}
diff --git a/examples/webengine/customdialogs/forms/FileRow.qml b/examples/webengine/customdialogs/forms/FileRow.qml
new file mode 100644
index 000000000..be0611323
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/FileRow.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 1.0 as Controls
+
+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/webengine/customdialogs/forms/JavaScript.qml b/examples/webengine/customdialogs/forms/JavaScript.qml
new file mode 100644
index 000000000..a97d8e0d4
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/JavaScript.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtWebEngine 1.4
+
+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/webengine/customdialogs/forms/JavaScriptForm.ui.qml b/examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml
new file mode 100644
index 000000000..cc0c1908e
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/JavaScriptForm.ui.qml
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 1.0 as Controls
+
+Item {
+ id: item
+ 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
+ anchors.rightMargin: 0
+ anchors.leftMargin: 0
+ anchors.right: parent.right
+ anchors.left: parent.left
+ 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
+ }
+
+ Controls.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
+ }
+
+ Button {
+ id: cancelButton
+ width: 90
+ height: 30
+ btnText: qsTr("Cancel")
+ btnBlue: false
+ }
+
+ Button {
+ id: okButton
+ width: 90
+ height: 30
+ btnText: qsTr("OK")
+ btnBlue: false
+ }
+ }
+ }
+}
diff --git a/examples/webengine/customdialogs/forms/Menu.qml b/examples/webengine/customdialogs/forms/Menu.qml
new file mode 100644
index 000000000..1ba6a84b4
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/Menu.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+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/webengine/customdialogs/forms/MenuForm.ui.qml b/examples/webengine/customdialogs/forms/MenuForm.ui.qml
new file mode 100644
index 000000000..696511cc7
--- /dev/null
+++ b/examples/webengine/customdialogs/forms/MenuForm.ui.qml
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.3
+
+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"
+ }
+
+ Button {
+ id: followLink
+ btnText: qsTr("Follow")
+ }
+
+ Button {
+ id: back
+ btnText: qsTr("Back")
+ }
+
+ Button {
+ id: forward
+ btnText: qsTr("Forward")
+ }
+
+ Button {
+ id: reload
+ btnText: qsTr("Reload")
+ }
+
+ Button {
+ id: copyLinkUrl
+ btnText: qsTr("Copy Link URL")
+ }
+
+ Button {
+ id: saveLink
+ btnText: qsTr("Save Link")
+ }
+
+ Button {
+ id: close
+ btnBlue: false
+ btnText: qsTr("Close")
+ }
+
+ }
+}
diff --git a/examples/webengine/customdialogs/icon.svg b/examples/webengine/customdialogs/icon.svg
new file mode 100644
index 000000000..48271180b
--- /dev/null
+++ b/examples/webengine/customdialogs/icon.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="94px" height="94px" viewBox="0 0 94 94" enable-background="new 0 0 94 94" xml:space="preserve">
+<g>
+ <circle fill="none" cx="47" cy="47" r="47"/>
+ <g>
+ <path fill="#46A2DA" d="M47,92.979c-11.779,0-23.559-4.484-32.526-13.451C-3.461,61.591-3.461,32.409,14.472,14.474
+ C32.41-3.463,61.592-3.461,79.526,14.473c17.935,17.936,17.935,47.119,0.002,65.054l-0.002,0.001
+ C70.559,88.495,58.779,92.979,47,92.979z"/>
+ </g>
+ <path fill="#80C342" d="M93,47C93,21.595,72.405,1,47,1C34.297,1,22.797,6.149,14.473,14.473l65.054,65.054
+ C87.851,71.203,93,59.703,93,47z"/>
+ <g>
+ <path fill="#46A2DA" d="M47,65c-4.808,0-9.328-1.873-12.728-5.272c-7.018-7.019-7.018-18.438,0-25.456
+ C37.672,30.873,42.192,29,47,29s9.328,1.873,12.728,5.272c7.018,7.019,7.018,18.438,0,25.456C56.328,63.127,51.808,65,47,65z"/>
+ <path fill="#FFFFFF" d="M62.248,59.919c6.671-7.858,6.312-19.644-1.105-27.061C57.237,28.953,52.118,27,47,27
+ c-5.118,0-10.237,1.953-14.142,5.858c-7.81,7.81-7.81,20.474,0,28.284C36.763,65.047,41.882,67,47,67
+ c4.379,0,8.752-1.441,12.372-4.3L77.88,81.209c0.989-0.895,1.935-1.837,2.843-2.814L62.248,59.919z M35.686,58.314
+ c-6.238-6.238-6.238-16.389,0-22.627C38.708,32.664,42.726,31,47,31c4.274,0,8.292,1.664,11.314,4.686
+ c6.238,6.238,6.238,16.389,0,22.627C55.292,61.336,51.274,63,47,63C42.726,63,38.708,61.336,35.686,58.314z"/>
+ </g>
+</g>
+</svg>
diff --git a/examples/webengine/customdialogs/index.html b/examples/webengine/customdialogs/index.html
new file mode 100644
index 000000000..43a2dbb67
--- /dev/null
+++ b/examples/webengine/customdialogs/index.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Custom UI</title>
+ <link rel="stylesheet" type="text/css" href="style.css">
+ </head>
+ <body>
+ <table align="center">
+ <tr>
+ <td><div class="div"><a href="#openMenu" class="link">Right click on text to see link context menu</a></div></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="window.location = 'http://localhost.:5555/OPEN_AUTH'">
+ Open Authentication Dialog</button></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="window.location = 'http://localhost.:5555/OPEN_PROXY'">
+ Open Proxy Dialog</button></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="alert('This is the Alert Dialog !')">
+ Open Alert Dialog</button></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="confirm('This is the Confirm Dialog.')">
+ Open Confirm Dialog</button></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="prompt('Is this the Prompt Dialog ?', 'Yes')">
+ Open Prompt Dialog</button></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="document.getElementById('colorpicker').click()">
+ Open Color Dialog</button></td>
+ </tr>
+ <tr>
+ <td><button class="button" onclick="document.getElementById('filepicker').click()">
+ Open File Dialog</button></td>
+ </tr>
+ <tr>
+ <td>
+ <form><table>
+ <tr><td><button class="button" type="submit">Open Message Bubble</button></td></tr>
+ <tr><td><input class="input" placeholder="For this field we open message bubble..." required/></td></tr>
+ </table></form>
+ </td>
+ </tr>
+ </table>
+ <input type="color" id="colorpicker" value="#ff0000" style="visibility:hidden"/>
+ <input type="file" id="filepicker" accept=".cpp, .html, .h, .png, .qdoc, .qml" style="visibility:hidden"/>
+ </body>
+</html>
diff --git a/examples/webengine/customdialogs/main.cpp b/examples/webengine/customdialogs/main.cpp
new file mode 100644
index 000000000..2f79a1e48
--- /dev/null
+++ b/examples/webengine/customdialogs/main.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "server.h"
+#include <qtwebengineglobal.h>
+#include <QNetworkProxy>
+#include <QQmlApplicationEngine>
+#include <QTimer>
+
+#ifndef QT_NO_WIDGETS
+#include <QtWidgets/QApplication>
+// QApplication is required to get native styling with QtQuickControls
+typedef QApplication Application;
+#else
+#include <QtGui/QGuiApplication>
+typedef QGuiApplication Application;
+#endif
+
+int main(int argc, char *argv[])
+{
+ Application app(argc, argv);
+ QtWebEngine::initialize();
+
+ 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/webengine/customdialogs/main.qml b/examples/webengine/customdialogs/main.qml
new file mode 100644
index 000000000..4288137fc
--- /dev/null
+++ b/examples/webengine/customdialogs/main.qml
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Controls 1.4 as Controls
+import QtQuick.Layouts 1.3
+import QtQuick.Window 2.0
+
+Window {
+ width: 350
+ height: 550
+ visible: true
+
+ Controls.StackView {
+ id: stackView
+ anchors.fill: parent
+ focus: true
+ initialItem: Item {
+ id: main
+ width: parent.width
+ height: parent.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);
+ }
+
+ function openForm(form)
+ {
+ push(form);
+ currentItem.closeForm.connect(closeForm);
+ }
+
+ }
+
+ Component.onCompleted: {
+ webView.openForm.connect(stackView.openForm);
+ }
+}
diff --git a/examples/webengine/customdialogs/server.cpp b/examples/webengine/customdialogs/server.cpp
new file mode 100644
index 000000000..21a8ffe5a
--- /dev/null
+++ b/examples/webengine/customdialogs/server.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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);
+ QByteArray msg = socket->readAll();
+ if (msg.contains(QByteArrayLiteral("OPEN_AUTH")))
+ socket->write("HTTP/1.1 401 Unauthorized\nWWW-Authenticate: "
+ "Basic realm=\"Very Restricted Area\"\r\n\r\n");
+ if (msg.contains(QByteArrayLiteral("OPEN_PROXY")))
+ socket->write("HTTP/1.1 407 Proxy Auth Required\nProxy-Authenticate: "
+ "Basic realm=\"Proxy requires authentication\"\r\n\r\n");
+}
diff --git a/examples/webengine/customdialogs/server.h b/examples/webengine/customdialogs/server.h
new file mode 100644
index 000000000..dc96acb70
--- /dev/null
+++ b/examples/webengine/customdialogs/server.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef 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;
+};
+
+#endif // SERVER_H
diff --git a/examples/webengine/customdialogs/style.css b/examples/webengine/customdialogs/style.css
new file mode 100644
index 000000000..e4c25e7eb
--- /dev/null
+++ b/examples/webengine/customdialogs/style.css
@@ -0,0 +1,37 @@
+.div {
+ padding:8px 4px;
+ border: 5px solid #188BD0;
+ width: 280px;
+ font-family: sans-serif;
+ font-size:10pt;
+}
+.link {
+ text-decoration: none;
+ color: #888888;
+}
+.button {
+ background: -webkit-linear-gradient(top,#25A6E2 0%,#188BD0 100%);
+ padding:8px 13px;
+ color:#fff;
+ font-family: sans-serif;
+ font-size:17px;
+ -webkit-border-radius:5px;
+ border:1px solid #1A87FF;
+ width: 300px;
+}
+.button:focus {
+ outline: none;
+}
+.button:active {
+ background: -webkit-linear-gradient(top,#25A6E2 0%,#188BD0 70%);
+}
+.input {
+ padding:8px 4px;
+ border: 5px solid #188BD0;
+ width: 280px;
+ font-family: sans-serif;
+ font-size:10pt;
+}
+.input:focus {
+ outline: none;
+}
diff --git a/examples/webengine/quicknanobrowser/quicknanobrowser.pro b/examples/webengine/quicknanobrowser/quicknanobrowser.pro
index 6cf556984..5a27f5fd4 100644
--- a/examples/webengine/quicknanobrowser/quicknanobrowser.pro
+++ b/examples/webengine/quicknanobrowser/quicknanobrowser.pro
@@ -1,4 +1,4 @@
-requires(contains(QT_CONFIG, accessibility))
+requires(qtConfig(accessibility))
TEMPLATE = app
TARGET = quicknanobrowser
diff --git a/examples/webengine/recipebrowser/doc/images/recipebrowser-demo.jpg b/examples/webengine/recipebrowser/doc/images/recipebrowser-demo.jpg
new file mode 100644
index 000000000..761ad3576
--- /dev/null
+++ b/examples/webengine/recipebrowser/doc/images/recipebrowser-demo.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc
new file mode 100644
index 000000000..d33f6bf10
--- /dev/null
+++ b/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** 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 webengine/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{QtWebEngine::initialize} so we can use
+ \l{WebEngineView} in our QML code. We enable high DPI screen support by setting the
+ \l{Qt::AA_EnableHighDpiScaling} attribute. 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 webengine/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 webengine/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 onRecipeSelected
+ \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 webengine/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 KeyNavigation.priority
+
+ 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
+ \printto firstLoadComplete
+
+ 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. 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.
+
+ \printuntil busy.running = true
+ \printline }
+ \printline }
+ \printline }
+
+ 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 webengine/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{http://kevinburke.bitbucket.org/markdowncss/}{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 webengine/recipebrowser/resources/pages/soup.html
+ \printuntil </html>
+
+*/
diff --git a/examples/webengine/recipebrowser/main.cpp b/examples/webengine/recipebrowser/main.cpp
new file mode 100644
index 000000000..a4251c3ea
--- /dev/null
+++ b/examples/webengine/recipebrowser/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QQuickStyle>
+#include <qtwebengineglobal.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+ QtWebEngine::initialize();
+
+ 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/webengine/recipebrowser/recipebrowser.pro b/examples/webengine/recipebrowser/recipebrowser.pro
new file mode 100644
index 000000000..ea6db13fb
--- /dev/null
+++ b/examples/webengine/recipebrowser/recipebrowser.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+
+QT += quick qml quickcontrols2 webengine
+
+cross_compile {
+ posix|qnx|linux: DEFINES += QTWEBENGINE_RECIPE_BROWSER_EMBEDDED
+}
+
+SOURCES += main.cpp
+
+RESOURCES += resources/resources.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webengine/recipebrowser
+INSTALLS += target
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md
new file mode 100644
index 000000000..9e91ab302
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md
@@ -0,0 +1,23 @@
+## markd license
+
+```
+Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+```
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md
new file mode 100644
index 000000000..8f9c807aa
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md
@@ -0,0 +1,12 @@
+## 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](http://kevinburke.bitbucket.org/markdowncss/markdown.css)
+was created by _Kevin Burke_.
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/markdown.css b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/markdown.css
new file mode 100644
index 000000000..24fc2ffe2
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/markdown.css
@@ -0,0 +1,260 @@
+body{
+ margin: 0 auto;
+ font-family: Georgia, Palatino, serif;
+ color: #444444;
+ line-height: 1;
+ max-width: 960px;
+ padding: 30px;
+}
+h1, h2, h3, h4 {
+ color: #111111;
+ font-weight: 400;
+}
+h1, h2, h3, h4, h5, p {
+ margin-bottom: 24px;
+ padding: 0;
+}
+h1 {
+ font-size: 48px;
+}
+h2 {
+ font-size: 36px;
+ /* The bottom margin is small. It's designed to be used with gray meta text
+ * below a post title. */
+ margin: 24px 0 6px;
+}
+h3 {
+ font-size: 24px;
+}
+h4 {
+ font-size: 21px;
+}
+h5 {
+ font-size: 18px;
+}
+a {
+ color: #0099ff;
+ margin: 0;
+ padding: 0;
+ vertical-align: baseline;
+}
+a:hover {
+ text-decoration: none;
+ color: #ff6600;
+}
+a:visited {
+ color: purple;
+}
+ul, ol {
+ padding: 0;
+ margin: 0;
+}
+li {
+ line-height: 24px;
+}
+li ul, li ul {
+ margin-left: 24px;
+}
+p, ul, ol {
+ font-size: 16px;
+ line-height: 24px;
+ max-width: 540px;
+}
+pre {
+ padding: 0px 24px;
+ max-width: 800px;
+ white-space: pre-wrap;
+}
+code {
+ font-family: Consolas, Monaco, Andale Mono, monospace;
+ line-height: 1.5;
+ font-size: 13px;
+}
+aside {
+ display: block;
+ float: right;
+ width: 390px;
+}
+blockquote {
+ border-left:.5em solid #eee;
+ padding: 0 2em;
+ margin-left:0;
+ max-width: 476px;
+}
+blockquote cite {
+ font-size:14px;
+ line-height:20px;
+ color:#bfbfbf;
+}
+blockquote cite:before {
+ content: '\2014 \00A0';
+}
+
+blockquote p {
+ color: #666;
+ max-width: 460px;
+}
+hr {
+ width: 540px;
+ text-align: left;
+ margin: 0 auto 0 0;
+ color: #999;
+}
+
+/* Code below this line is copyright Twitter Inc. */
+
+button,
+input,
+select,
+textarea {
+ font-size: 100%;
+ margin: 0;
+ vertical-align: baseline;
+ *vertical-align: middle;
+}
+button, input {
+ line-height: normal;
+ *overflow: visible;
+}
+button::-moz-focus-inner, input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ -webkit-appearance: button;
+}
+input[type=checkbox], input[type=radio] {
+ cursor: pointer;
+}
+/* override default chrome & firefox settings */
+input:not([type="image"]), textarea {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+label,
+input,
+select,
+textarea {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: normal;
+ margin-bottom: 18px;
+}
+input[type=checkbox], input[type=radio] {
+ cursor: pointer;
+ margin-bottom: 0;
+}
+input[type=text],
+input[type=password],
+textarea,
+select {
+ display: inline-block;
+ width: 210px;
+ padding: 4px;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 18px;
+ height: 18px;
+ color: #808080;
+ border: 1px solid #ccc;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+select, input[type=file] {
+ height: 27px;
+ line-height: 27px;
+}
+textarea {
+ height: auto;
+}
+
+/* grey out placeholders */
+:-moz-placeholder {
+ color: #bfbfbf;
+}
+::-webkit-input-placeholder {
+ color: #bfbfbf;
+}
+
+input[type=text],
+input[type=password],
+select,
+textarea {
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+input[type=text]:focus, input[type=password]:focus, textarea:focus {
+ outline: none;
+ border-color: rgba(82, 168, 236, 0.8);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+/* buttons */
+button {
+ display: inline-block;
+ padding: 4px 14px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ background-color: #0064cd;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));
+ background-image: -moz-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -ms-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));
+ background-image: -webkit-linear-gradient(top, #049cdb, #0064cd);
+ background-image: -o-linear-gradient(top, #049cdb, #0064cd);
+ background-image: linear-gradient(top, #049cdb, #0064cd);
+ color: #fff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border: 1px solid #004b9a;
+ border-bottom-color: #003f81;
+ -webkit-transition: 0.1s linear all;
+ -moz-transition: 0.1s linear all;
+ transition: 0.1s linear all;
+ border-color: #0064cd #0064cd #003f81;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+}
+button:hover {
+ color: #fff;
+ background-position: 0 -15px;
+ text-decoration: none;
+}
+button:active {
+ -webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+button::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/marked.min.js b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/marked.min.js
new file mode 100644
index 000000000..f679a4776
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/marked.min.js
@@ -0,0 +1,6 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",/<!--[\s\S]*?-->/)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].split(/ *\| */)}this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */)}this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1].charAt(cap[1].length-1)==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",text:cap[0]});continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^<a /i.test(cap[0])){this.inLink=true}else if(this.inLink&&/^<\/a>/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>.5){ch="x"+ch.toString(16)}out+="&#"+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return"<pre><code>"+(escaped?code:escape(code,true))+"\n</code></pre>"}return'<pre><code class="'+this.options.langPrefix+escape(lang,true)+'">'+(escaped?code:escape(code,true))+"\n</code></pre>\n"};Renderer.prototype.blockquote=function(quote){return"<blockquote>\n"+quote+"</blockquote>\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"<h"+level+' id="'+this.options.headerPrefix+raw.toLowerCase().replace(/[^\w]+/g,"-")+'">'+text+"</h"+level+">\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+"</"+type+">\n"};Renderer.prototype.listitem=function(text){return"<li>"+text+"</li>\n"};Renderer.prototype.paragraph=function(text){return"<p>"+text+"</p>\n"};Renderer.prototype.table=function(header,body){return"<table>\n"+"<thead>\n"+header+"</thead>\n"+"<tbody>\n"+body+"</tbody>\n"+"</table>\n"};Renderer.prototype.tablerow=function(content){return"<tr>\n"+content+"</tr>\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+"</"+type+">\n"};Renderer.prototype.strong=function(text){return"<strong>"+text+"</strong>"};Renderer.prototype.em=function(text){return"<em>"+text+"</em>"};Renderer.prototype.codespan=function(text){return"<code>"+text+"</code>"};Renderer.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"};Renderer.prototype.del=function(text){return"<del>"+text+"</del>"};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='<a href="'+href+'"';if(title){out+=' title="'+title+'"'}out+=">"+text+"</a>";return out};Renderer.prototype.image=function(href,title,text){var out='<img src="'+href+'" alt="'+text+'"';if(title){out+=' title="'+title+'"'}out+=this.options.xhtml?"/>":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i<this.token.header.length;i++){flags={header:true,align:this.token.align[i]};cell+=this.renderer.tablecell(this.inline.output(this.token.header[i]),{header:true,align:this.token.align[i]})}header+=this.renderer.tablerow(cell);for(i=0;i<this.token.cells.length;i++){row=this.token.cells[i];cell="";for(j=0;j<row.length;j++){cell+=this.renderer.tablecell(this.inline.output(row[j]),{header:false,align:this.token.align[j]})}body+=this.renderer.tablerow(cell)}return this.renderer.table(header,body)}case"blockquote_start":{var body="";while(this.next().type!=="blockquote_end"){body+=this.tok()}return this.renderer.blockquote(body)}case"list_start":{var body="",ordered=this.token.ordered;while(this.next().type!=="list_end"){body+=this.tok()}return this.renderer.list(body,ordered)}case"list_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.token.type==="text"?this.parseText():this.tok()}return this.renderer.listitem(body)}case"loose_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.tok()}return this.renderer.listitem(body)}case"html":{var html=!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;return this.renderer.html(html)}case"paragraph":{return this.renderer.paragraph(this.inline.output(this.token.text))}case"text":{return this.renderer.paragraph(this.parseText())}}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target){if(Object.prototype.hasOwnProperty.call(target,key)){obj[key]=target[key]}}}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}opt=merge({},marked.defaults,opt||{});var highlight=opt.highlight,tokens,pending,i=0;try{tokens=Lexer.lex(src,opt)}catch(e){return callback(e)}pending=tokens.length;var done=function(err){if(err){opt.highlight=highlight;return callback(err)}var out;try{out=Parser.parse(tokens,opt)}catch(e){err=e}opt.highlight=highlight;return err?callback(err):callback(null,out)};if(!highlight||highlight.length<3){return done()}delete opt.highlight;if(!pending)return done();for(;i<tokens.length;i++){(function(token){if(token.type!=="code"){return--pending||done()}return highlight(token.text,token.lang,function(err,code){if(err)return done(err);if(code==null||code===token.text){return--pending||done()}token.text=code;token.escaped=true;--pending||done()})})(tokens[i])}return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";if((opt||marked.defaults).silent){return"<p>An error occurred:</p><pre>"+escape(e.message+"",true)+"</pre>"}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/custom.css b/examples/webengine/recipebrowser/resources/pages/assets/custom.css
new file mode 100644
index 000000000..9ddc19466
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/custom.css
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+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/webengine/recipebrowser/resources/pages/assets/custom.js b/examples/webengine/recipebrowser/resources/pages/assets/custom.js
new file mode 100644
index 000000000..aaa22a290
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/custom.js
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+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/webengine/recipebrowser/resources/pages/burger.html b/examples/webengine/recipebrowser/resources/pages/burger.html
new file mode 100644
index 000000000..315c0a866
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/burger.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/burger.jpg" alt="Insanity Burger" title="Insanity Burger" />
+Insanity burger
+===============
+
+### Ingredients
+
+* 800 g minced chuck steak
+* olive oil
+* 1 large red onion
+* 1 splash of white wine vinegar
+* 2 large gherkins
+* 4 sesame-topped brioche burger buns
+* 4-8 rashers of smoked streaky bacon
+* 4 teaspoons American mustard
+* Tabasco Chipotle sauce
+* 4 thin slices of Red Leicester cheese
+* 4 teaspoons tomato ketchup
+
+#### For the burger sauce
+* ¼ of an iceberg lettuce
+* 2 heaped tablespoons mayonnaise
+* 1 heaped tablespoon tomato ketchup
+* 1 teaspoon Tabasco Chipotle sauce
+* 1 teaspoon Worcestershire sauce
+* 1 teaspoon brandy, or bourbon (optional)
+
+### Instructions
+For the best burger, go to your butcher’s and ask them to mince 800g of chuck steak for you.
+This cut has a really good balance of fat and flavoursome meat. Divide it into 4 and, with wet
+hands, roll each piece into a ball, then press into flat patties roughly 12cm wide and about 2cm
+wider than your buns. Place on an oiled plate and chill in the fridge. Next, finely slice the red
+onion, then dress in a bowl with the vinegar and a pinch of sea salt. Slice the gherkins and halve
+the buns. Finely chop the lettuce and mix with the rest of the burger sauce ingredients in a bowl,
+then season to taste.
+
+I like to only cook 2 burgers at a time to achieve perfection, so get two pans on the go – a large
+non-stick pan on a high heat for your burgers and another on a medium heat for the bacon. Pat your
+burgers with oil and season them with salt and pepper. Put 2 burgers into the first pan, pressing
+down on them with a fish slice, then put half the bacon into the other pan. After 1 minute, flip
+the burgers and brush each cooked side with ½ a teaspoon of mustard and a dash of Tabasco. After
+another minute, flip onto the mustard side and brush again with another ½ teaspoon of mustard and
+a second dash of Tabasco on the other side. Cook for one more minute, by which point you can place
+some crispy bacon on top of each burger with a slice of cheese. Add a tiny splash of water to the
+pan and place a heatproof bowl over the burgers to melt the cheese – 30 seconds should do it. At the
+same time, toast 2 split buns in the bacon fat in the other pan until lightly golden. Repeat with
+the remaining two burgers.
+
+To build each burger, add a quarter of the burger sauce to the bun base, then top with a cheesy
+bacon burger, a quarter of the onions and gherkins. Rub the bun top with a teaspoon of ketchup,
+then gently press together. As the burger rests, juices will soak into the bun, so serve right
+away, which is great, or for an extra filthy experience, wrap each one in greaseproof paper, then
+give it a minute to go gorgeous and sloppy.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/pages/cupcakes.html b/examples/webengine/recipebrowser/resources/pages/cupcakes.html
new file mode 100644
index 000000000..c169196f2
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/cupcakes.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/cupcakes.jpg" alt="Cupcakes" title="Cupcakes" />
+Cupcakes
+=============
+
+### Ingredients
+
+* 300 g caster sugar
+* 150 ml sunflower oil
+* 1 teaspoon vanilla extract
+* 500 g dairy-free soya yoghurt
+* 2 teaspoons cider vinegar
+* 350 g plain flour
+* 1 teaspoon bicarbonate of soda
+* 1½ teaspoons baking powder
+
+#### For the vegan vanilla icing
+* 200 g dairy-free soya spread , chilled
+* 660 g icing sugar
+* ½ teaspoon vanilla extract
+
+### Instructions
+1. Preheat the oven to 170°C fan/375°F/gas 5.
+2. Place the sugar, oil and vanilla extract in a large bowl, then beat with an electric mixer for 1 to 2 minutes, until well combined.
+3. Mix the yoghurt and vinegar together in a bowl, then add to the mixture and beat for 1 to 2 minutes.
+4. Add the remaining cupcake ingredients and 1 teaspoon of fine sea salt, then whisk until smooth and just combined.
+5. Fill the paper cases two-thirds full with mixture, but don’t bother to smooth it out.
+6. Bake for 20 minutes, or until they spring back when touched. Leave to cool, transferring to a wire cooling rack after 5 minutes.
+7. Meanwhile, make the icing. Beat the soya spread with an electric mixer for 1 to 2 minutes, or until smooth.
+8. Sift the icing sugar into a large bowl, then add to the soya spread in two stages, beating well between each.
+9. Add the vanilla extract and a small splash of water, then whisk for a further few minutes, or until silky smooth – if it’s too stiff, add a splash more water to loosen.
+10. Once the cupcakes are cool, decorate them with the icing and add a few sprinkles too if you like – whatever takes your fancy – then enjoy.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/pages/images/burger.jpg b/examples/webengine/recipebrowser/resources/pages/images/burger.jpg
new file mode 100644
index 000000000..edc0c65de
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/burger.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/images/cupcakes.jpg b/examples/webengine/recipebrowser/resources/pages/images/cupcakes.jpg
new file mode 100644
index 000000000..cce52ba23
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/cupcakes.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/images/pasta.jpg b/examples/webengine/recipebrowser/resources/pages/images/pasta.jpg
new file mode 100644
index 000000000..7ac924b79
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/pasta.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/images/pizza.jpg b/examples/webengine/recipebrowser/resources/pages/images/pizza.jpg
new file mode 100644
index 000000000..8d8f756af
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/pizza.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/images/skewers.jpg b/examples/webengine/recipebrowser/resources/pages/images/skewers.jpg
new file mode 100644
index 000000000..6bb2f1172
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/skewers.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/images/soup.jpg b/examples/webengine/recipebrowser/resources/pages/images/soup.jpg
new file mode 100644
index 000000000..fc9dff906
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/soup.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/images/steak.jpg b/examples/webengine/recipebrowser/resources/pages/images/steak.jpg
new file mode 100644
index 000000000..240b72eb4
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/images/steak.jpg
Binary files differ
diff --git a/examples/webengine/recipebrowser/resources/pages/pasta.html b/examples/webengine/recipebrowser/resources/pages/pasta.html
new file mode 100644
index 000000000..c94b0df0a
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/pasta.html
@@ -0,0 +1,57 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/pasta.jpg" alt="Pasta" title="Pasta" />
+Pasta
+=============
+
+### Ingredients
+
+* 2 red peppers , deseeded and sliced
+* 2 yellow peppers , deseeded and sliced
+* extra virgin olive oil
+* sea salt
+* freshly ground black pepper
+* 2 red onions , peeled and finely sliced
+* 2 cloves garlic , peeled and grated
+* 2 handfuls fresh flat-leaf parsley , leaves finely chopped, stalks reserved
+* 2 tablespoons red wine vinegar or balsamic vinegar
+* 2 handfuls Parmesan cheese , grated
+* 2 heaped tablespoons mascarpone cheese or crème fraîche , optional
+* 455 g rigatoni, penne or spaghetti
+
+
+### Instructions
+1. Put all the peppers in a large frying pan over a medium heat with a little olive oil and a pinch of salt and pepper.
+2. Place a lid on, and cook slowly for 15 minutes until softened. Don't rush this too much, as cooking the peppers slowly like this really helps to bring out the flavour.
+3. Add the onion and cook for a further 20 minutes.
+4. Then add the garlic and parsley stalks and toss around, keeping everything moving in the pan.
+5. Cook for about 3 minutes most. Have a little taste, and season with a bit more salt and pepper.
+5. Add the vinegar - it will sizzle away, so give everything a good toss.
+6. Then add one handful of the grated Parmesan and the mascarpone or crème fraîche if you are using it and turn the heat down to minimum while you cook the pasta.
+7. Meanwhile put a large pot of salted water on to boil.
+8. Add the pasta to the boiling water and cook according to the packet instructions.
+9. When cooked, drain in a colander, reserving some of the cooking water.
+10. Put the peppers, pasta and parsley leaves into a large warmed bowl.
+11. Give them a good toss together, then add a little of the pasta cooking water and a few good lugs of extra virgin olive oil to coat the pasta nicely.
+12. Serve straight away sprinkled with the rest of the Parmesan.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/pages/pizza.html b/examples/webengine/recipebrowser/resources/pages/pizza.html
new file mode 100644
index 000000000..a1ebfa18e
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/pizza.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/pizza.jpg" alt="Pizza Diavola" title="Pizza Diavola" />
+Pizza Diavola
+=============
+
+### Ingredients
+
+* 2 pizza dough balls
+* 100g Mozzarella
+* 400g Passata
+* 200 g Spicy Salami
+* 2 fresh chillies
+* Extra virgin olive oil
+* Salt
+
+### Instructions
+1. Preheat oven to 210 oc.
+2. Get your pizza dough balls ( depending on how many you are making) and roll them out to about 12 inches diameter using your hands in a circular stretching technique or using a rolling pin.
+3. With the dough prepared now get our sauce ready by mixing the passata with three tbsp of the olive oil and a good pinch of salt.
+4. Now slice up your salami into thin-ish slices and also finely chop the fresh chillies.
+5. Next, slice or dice your mozzarella and we are ready to dress the pizza.
+6. Add half the tomato sauce to each base and spread evenly leaving a half inch perimeter.
+7. Add the mozzarella, salami and finish with the chillies.
+8. Finally drizzle with some more olive oil and your are ready to cook your pizza diavola.
+9. Place in the oven for ten minutes or until golden.
+10. Remove from the oven, slice, and enjoy your pizza diavola.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/pages/skewers.html b/examples/webengine/recipebrowser/resources/pages/skewers.html
new file mode 100644
index 000000000..63d85f7e1
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/skewers.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/skewers.jpg" alt="Grilled skewers" title="Grilled skewers" />
+Grilled skewers
+======================
+
+### Ingredients
+
+* 3 cloves of garlic
+* 200g kefalotyri cheese
+* 2 medium aubergine
+* 1 iceberg lettuce
+* 1 tablespoon coriander seeds
+* 2 teaspoons dried oregano
+* 2 lemons
+* 4 tablespoons olive oil
+* 600g lamb neck fillet , in 2cm chunks
+* 12 fresh bay leaves
+
+### Instructions
+1. Peel and crush the garlic.
+2. Chop the cheese into bite-sized pieces, trim and chop the aubergines into 2cm chunks, and trim and finely slice the lettuce.
+3. Finely crush the coriander seeds in a pestle and mortar and add to a large bowl with the oregano and garlic. Finely grate in the lemon zest (reserve the zested lemons) and stir in the oil.
+4. Season, then add the cheese, lamb, aubergines and bay leaves. Leave to marinate for at least an hour, or overnight if you can.
+5. Meanwhile, pickle your cabbage. Trim, core and finely slice the cabbage, then place in a colander in the sink or over a bowl and toss with 2 teaspoons of sea salt. Cover and set aside for at least 2 hours, then rinse.
+6. Peel and finely slice the onions, then transfer to a bowl along with the cabbage.
+7. Put the remaining ingredients in a pan and bring to a boil. Simmer for 10 minutes, then pour over the cabbage and onions. Transfer to sterilised jars – this will keep for up to 1 month.
+8. For the flatbreads, put the flour, baking powder, buttermilk and half of the sesame seeds in a bowl and mix until everything is combined.
+9. Tip onto a lightly floured surface and knead briefly. Divide into six, using a rolling pin to roll them into 1 to 2mm rounds.
+10. Scatter with the remaining sesame seeds and run the rolling pin over them. Pop the flatbreads onto the hot barbecue for 1 to 2 minutes on each side.
+11. Load 12 skewers with the cheese, lamb, aubergines and bay leaves, then place on the barbecue (not directly over the coals) for 20 to 25 minutes, turning often, until the lamb is medium-rare and the aubergines are cooked.
+12. Serve the lamb with the flatbreads, cabbage, lettuce and lemon wedges.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/pages/soup.html b/examples/webengine/recipebrowser/resources/pages/soup.html
new file mode 100644
index 000000000..c7537d94c
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/soup.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/soup.jpg" alt="Soup" title="Soup" />
+Soup
+=============
+
+### Ingredients
+
+* 2 potatoes
+* 2 onions
+* 2 cloves of garlic
+* olive oil
+* 400 ml organic stock
+* 3 bunches of watercress
+
+### Instructions
+* Peel and roughly chop the potatoes, onions and garlic.
+* In a large saucepan, heat a little olive oil, then sauté the potato, onion and garlic until the onions are translucent.
+* Add the stock and simmer until the potato is soft. Chop and add the watercress and simmer for a further 3 to 4 minutes.
+* Using a hand blender, liquidise the soup until smooth.
+* Serve with a swirl of crème fraîche and some Fortt’s Bath Oliver biscuits, if you like.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/pages/steak.html b/examples/webengine/recipebrowser/resources/pages/steak.html
new file mode 100644
index 000000000..1871f0fe8
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/steak.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<html lang="en">
+<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">
+</head>
+<body>
+ <div id="placeholder"></div>
+ <div id="content">
+
+<img src="images/steak.jpg" alt="Grilled steak and rice" title="Grilled steak and rice" />
+Grilled steak and rice
+======================
+
+### Ingredients
+
+#### For the ratatouille
+* courgette
+* 1 small aubergine
+* 2 mixed-color peppers
+* 1 red onion
+* 1 heaped teaspoon harissa
+* 2 anchovy fillets
+* 2-4 cloves of garlic
+* 700 g passata
+* 1 tablespoon balsamic vinegar
+* ½ bunch fresh basil
+* 2 tablespoons fat-free natural yoghurt
+
+#### For the rice
+* 1 mug (300g) 10-minute wholegrain or basmati rice
+* 1 good pinch saffron
+* ½ lemon
+
+#### For the steak
+* 2 x 250 g quality sirloin steaks, fat removed
+* 1 teaspoon sweet paprika olive oil
+* ½ bunch fresh flat-leaf parsley
+* 1 heaped teaspoon Dijon mustard
+* 1 tablespoon extra virgin olive oil
+* ½ lemon
+
+### Instructions
+1. Halve the courgette lengthways, slice the aubergine 1cm thick and place both on the griddle pan, turning when charred.
+2. Put 1 mug of rice, 2 mugs of boiling water, the saffron, lemon half and a pinch of salt into the small pan, cover and cook until fluffy, stirring occasionally.
+3. Tear the seeds and stalks out of the peppers, then roughly chop with the peeled red onion and put into the casserole pan with the harissa, anchovies and 1 teaspoon of their oil.
+4. Squash in the unpeeled garlic through a garlic crusher and stir regularly.
+5. Remove the charred courgette and aubergine from the griddle pan, leaving it on the heat, and roughly chop them on a board.
+6. Add them to the casserole pan along with the passata and vinegar, and boil with the lid on.
+7. Rub the steaks with salt, the paprika and 1 teaspoon of olive oil and place on the hot griddle pan, turning every minute until cooked to your liking.
+8. On a board, finely slice the parsley stalks and roughly chop the leaves.
+9. Add the mustard and extra virgin olive oil, season with salt and pepper and squeeze over the lemon juice, then mix together and spread over the board.
+10. When the steaks are done, transfer them to the board, turn in the dressing, then slice.
+11. Tear the top leafy half of the basil into the ratatouille, season to taste, and serve with yoghurt and saffron rice.
+
+**Enjoy!**
+
+ </div><!--End of content-->
+
+ <script src="assets/3rdparty/marked.min.js"></script>
+ <script src="assets/custom.js"></script>
+</body>
+</html>
+
+
+
diff --git a/examples/webengine/recipebrowser/resources/qml/RecipeList.qml b/examples/webengine/recipebrowser/resources/qml/RecipeList.qml
new file mode 100644
index 000000000..c2432631e
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/qml/RecipeList.qml
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+import QtQuick.Controls.Material 2.0
+import QtQuick.Layouts 1.0
+
+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/webengine/recipebrowser/resources/qml/main.qml b/examples/webengine/recipebrowser/resources/qml/main.qml
new file mode 100644
index 000000000..b49cb6649
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/qml/main.qml
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.0
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+import QtQuick.Controls.Material 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Window 2.0
+import QtWebEngine 1.4
+
+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
+ KeyNavigation.tab: webView
+ onRecipeSelected: webView.showRecipe(url)
+ }
+
+ WebEngineView {
+ id: webView
+ Layout.preferredWidth: 2 * parent.width / 3
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ KeyNavigation.tab: recipeList
+ KeyNavigation.priority: KeyNavigation.BeforeItem
+ // 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: {
+ 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/webengine/recipebrowser/resources/resources.qrc b/examples/webengine/recipebrowser/resources/resources.qrc
new file mode 100644
index 000000000..ae5aa2ed3
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/resources.qrc
@@ -0,0 +1,28 @@
+<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.min.js</file>
+ <file>pages/assets/3rdparty/default.md</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/webenginewidgets/demobrowser/browsermainwindow.cpp b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
index f044219ca..926c4a5d7 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.cpp
@@ -109,6 +109,9 @@ BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags)
, m_historyForward(0)
, m_stop(0)
, m_reload(0)
+#ifndef QT_NO_PRINTER
+ , m_currentPrinter(nullptr)
+#endif
{
setToolButtonStyle(Qt::ToolButtonFollowStyle);
setAttribute(Qt::WA_DeleteOnClose, true);
@@ -312,6 +315,8 @@ void BrowserMainWindow::setupMenu()
fileMenu->addSeparator();
#if defined(QWEBENGINEPAGE_PRINT)
fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview()));
+#endif
+#ifndef QT_NO_PRINTER
fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print);
#endif
fileMenu->addAction(tr("&Print to PDF..."), this, SLOT(slotFilePrintToPDF()));
@@ -403,7 +408,10 @@ void BrowserMainWindow::setupMenu()
viewMenu->addAction(tr("Reset &Zoom"), this, SLOT(slotViewResetZoom()), QKeySequence(Qt::CTRL | Qt::Key_0));
viewMenu->addSeparator();
- viewMenu->addAction(tr("Page S&ource"), this, SLOT(slotViewPageSource()), tr("Ctrl+Alt+U"));
+ QAction *m_pageSource = viewMenu->addAction(tr("Page S&ource"));
+ m_pageSource->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_U));
+ m_tabWidget->addWebAction(m_pageSource, QWebEnginePage::ViewSource);
+
QAction *a = viewMenu->addAction(tr("&Full Screen"), this, SLOT(slotViewFullScreen(bool)), Qt::Key_F11);
a->setCheckable(true);
@@ -710,10 +718,10 @@ void BrowserMainWindow::slotFilePrintPreview()
void BrowserMainWindow::slotFilePrint()
{
-#if defined(QWEBENGINEPAGE_PRINT)
+#ifndef QT_NO_PRINTER
if (!currentTab())
return;
- printRequested(currentTab()->page()->mainFrame());
+ printRequested(currentTab()->page());
#endif
}
@@ -747,16 +755,29 @@ void BrowserMainWindow::slotFilePrintToPDF()
currentTab()->page()->printToPdf(invoke(this, &BrowserMainWindow::slotHandlePdfPrinted), dialog->pageLayout());
}
-#if defined(QWEBENGINEPAGE_PRINT)
-void BrowserMainWindow::printRequested(QWebEngineFrame *frame)
+#ifndef QT_NO_PRINTER
+void BrowserMainWindow::slotHandlePagePrinted(bool result)
+{
+ Q_UNUSED(result);
+
+ delete m_currentPrinter;
+ m_currentPrinter = nullptr;
+}
+
+
+void BrowserMainWindow::printRequested(QWebEnginePage *page)
{
#ifndef QT_NO_PRINTDIALOG
- QPrinter printer;
- QPrintDialog *dialog = new QPrintDialog(&printer, this);
+ if (m_currentPrinter)
+ return;
+ m_currentPrinter = new QPrinter();
+ QScopedPointer<QPrintDialog> dialog(new QPrintDialog(m_currentPrinter, this));
dialog->setWindowTitle(tr("Print Document"));
- if (dialog->exec() != QDialog::Accepted)
+ if (dialog->exec() != QDialog::Accepted) {
+ slotHandlePagePrinted(false);
return;
- frame->print(&printer);
+ }
+ page->print(m_currentPrinter, invoke(this, &BrowserMainWindow::slotHandlePagePrinted));
#endif
}
#endif
@@ -867,20 +888,6 @@ void BrowserMainWindow::slotViewFullScreen(bool makeFullScreen)
}
}
-void BrowserMainWindow::slotViewPageSource()
-{
- if (!currentTab())
- return;
-
- QPlainTextEdit *view = new QPlainTextEdit;
- view->setWindowTitle(tr("Page Source of %1").arg(currentTab()->title()));
- view->setMinimumWidth(640);
- view->setAttribute(Qt::WA_DeleteOnClose);
- view->show();
-
- currentTab()->page()->toHtml(invoke(view, &QPlainTextEdit::setPlainText));
-}
-
void BrowserMainWindow::slotHome()
{
QSettings settings;
diff --git a/examples/webenginewidgets/demobrowser/browsermainwindow.h b/examples/webenginewidgets/demobrowser/browsermainwindow.h
index 9fb6b0851..91e1c1d2f 100644
--- a/examples/webenginewidgets/demobrowser/browsermainwindow.h
+++ b/examples/webenginewidgets/demobrowser/browsermainwindow.h
@@ -56,7 +56,10 @@
#include <QtCore/QUrl>
QT_BEGIN_NAMESPACE
-class QWebEngineFrame;
+#ifndef QT_NO_PRINTER
+class QPrinter;
+#endif
+class QWebEnginePage;
QT_END_NAMESPACE
class AutoSaver;
@@ -123,7 +126,6 @@ private slots:
void slotViewToolbar();
void slotViewBookmarksBar();
void slotViewStatusbar();
- void slotViewPageSource();
void slotViewFullScreen(bool enable);
void slotWebSearch();
@@ -140,8 +142,9 @@ private slots:
void slotSwapFocus();
void slotHandlePdfPrinted(const QByteArray&);
-#if defined(QWEBENGINEPAGE_PRINT)
- void printRequested(QWebEngineFrame *frame);
+#ifndef QT_NO_PRINTER
+ void slotHandlePagePrinted(bool result);
+ void printRequested(QWebEnginePage *page);
#endif
void geometryChangeRequested(const QRect &geometry);
void updateToolbarActionText(bool visible);
@@ -177,6 +180,10 @@ private:
QAction *m_restoreLastSession;
QAction *m_addBookmark;
+#ifndef QT_NO_PRINTER
+ QPrinter *m_currentPrinter;
+#endif
+
QIcon m_reloadIcon;
QIcon m_stopIcon;
diff --git a/examples/webenginewidgets/demobrowser/webview.cpp b/examples/webenginewidgets/demobrowser/webview.cpp
index a785ae48b..ab2a4f3c6 100644
--- a/examples/webenginewidgets/demobrowser/webview.cpp
+++ b/examples/webenginewidgets/demobrowser/webview.cpp
@@ -365,6 +365,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
menu = new QMenu(this);
menu->addAction(page()->action(QWebEnginePage::OpenLinkInThisWindow));
menu->addAction(page()->action(QWebEnginePage::OpenLinkInNewWindow));
+ menu->addAction(page()->action(QWebEnginePage::OpenLinkInNewTab));
menu->addAction(page()->action(QWebEnginePage::OpenLinkInNewBackgroundTab));
menu->addSeparator();
menu->addAction(page()->action(QWebEnginePage::DownloadLinkToDisk));
@@ -392,11 +393,6 @@ void WebView::wheelEvent(QWheelEvent *event)
QWebEngineView::wheelEvent(event);
}
-void WebView::openLinkInNewTab()
-{
- pageAction(QWebEnginePage::OpenLinkInNewTab)->trigger();
-}
-
void WebView::onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
{
FeaturePermissionBar *permissionBar = new FeaturePermissionBar(this);
diff --git a/examples/webenginewidgets/demobrowser/webview.h b/examples/webenginewidgets/demobrowser/webview.h
index 8cb502fd1..7531254d6 100644
--- a/examples/webenginewidgets/demobrowser/webview.h
+++ b/examples/webenginewidgets/demobrowser/webview.h
@@ -115,7 +115,6 @@ private slots:
void setProgress(int progress);
void loadFinished(bool success);
void setStatusBarText(const QString &string);
- void openLinkInNewTab();
void onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature);
void onIconChanged(const QIcon &icon);
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
index 3a9908ea6..0239c1065 100644
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -113,11 +113,16 @@
\quotefromfile webenginewidgets/markdowneditor/mainwindow.cpp
\skipto MainWindow::MainWindow
- \printto connect
+ \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. It then makes sure our custom
+ 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
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
index 417858d8d..9981d177d 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.cpp
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
@@ -65,6 +65,7 @@ MainWindow::MainWindow(QWidget *parent) :
{
ui->setupUi(this);
ui->editor->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
+ ui->preview->setContextMenuPolicy(Qt::NoContextMenu);
PreviewPage *page = new PreviewPage(this);
ui->preview->setPage(page);
diff --git a/examples/webenginewidgets/spellchecker/data/icon.svg b/examples/webenginewidgets/spellchecker/data/icon.svg
new file mode 100644
index 000000000..b90ff26dd
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/data/icon.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="94px" height="94px" viewBox="0 0 94 94" enable-background="new 0 0 94 94" xml:space="preserve">
+<g>
+ <circle fill="none" cx="47" cy="47" r="47"/>
+ <g>
+ <path fill="#46A2DA" d="M47,92.979c-11.779,0-23.559-4.484-32.526-13.451C-3.461,61.591-3.461,32.409,14.472,14.474
+ C32.41-3.463,61.592-3.461,79.526,14.473c17.935,17.936,17.935,47.119,0.002,65.054l-0.002,0.001
+ C70.559,88.495,58.779,92.979,47,92.979z"/>
+ </g>
+ <path fill="#80C342" d="M93,47C93,21.595,72.405,1,47,1C34.297,1,22.797,6.149,14.473,14.473l65.054,65.054
+ C87.851,71.203,93,59.703,93,47z"/>
+ <g>
+ <path fill="#46A2DA" d="M47,65c-4.808,0-9.328-1.873-12.728-5.272c-7.018-7.019-7.018-18.438,0-25.456
+ C37.672,30.873,42.192,29,47,29s9.328,1.873,12.728,5.272c7.018,7.019,7.018,18.438,0,25.456C56.328,63.127,51.808,65,47,65z"/>
+ <path fill="#FFFFFF" d="M62.248,59.919c6.671-7.858,6.312-19.644-1.105-27.061C57.237,28.953,52.118,27,47,27
+ c-5.118,0-10.237,1.953-14.142,5.858c-7.81,7.81-7.81,20.474,0,28.284C36.763,65.047,41.882,67,47,67
+ c4.379,0,8.752-1.441,12.372-4.3L77.88,81.209c0.989-0.895,1.935-1.837,2.843-2.814L62.248,59.919z M35.686,58.314
+ c-6.238-6.238-6.238-16.389,0-22.627C38.708,32.664,42.726,31,47,31c4.274,0,8.292,1.664,11.314,4.686
+ c6.238,6.238,6.238,16.389,0,22.627C55.292,61.336,51.274,63,47,63C42.726,63,38.708,61.336,35.686,58.314z"/>
+ </g>
+</g>
+</svg>
diff --git a/examples/webenginewidgets/spellchecker/data/index.html b/examples/webenginewidgets/spellchecker/data/index.html
new file mode 100644
index 000000000..b6cec5fe0
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/data/index.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Contact us</title>
+ <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>
+ </body>
+</html>
diff --git a/examples/webenginewidgets/spellchecker/data/spellchecker.qrc b/examples/webenginewidgets/spellchecker/data/spellchecker.qrc
new file mode 100644
index 000000000..a9c76cc7e
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/data/spellchecker.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <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
new file mode 100644
index 000000000..7b6736f1f
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/data/style.css
@@ -0,0 +1,90 @@
+.logo {
+ width: 50px;
+ height: 50px;
+ float: left;
+ margin: 20px 20px 0px 20px;
+ -webkit-animation:spin 8s linear infinite;
+}
+@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
+
+.header {
+ display: inline
+}
+
+.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;
+}
+
+h1 {
+ padding-left:40px;
+ color: #46a2da;
+}
+
+h2 {
+ color: #80c342;
+ font-size: 13px;
+ margin-top: -20px;
+}
+
+span {
+ margin-left: 20px;
+}
+
+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);
+}
+
+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);
+}
+
+input:focus, textarea:focus {
+ outline:none;
+ border: 1px solid #46a2da;
+}
+
+input[type=submit] {
+ width: 100px;
+ left: 170px;
+ bottom: 10px;
+ background: #46a2da;
+ color: #fff;
+ height: 30px;
+ position: absolute;
+ border-radius: 14px;
+}
+
+input[type=submit]:hover {
+ background: #80c342;
+}
+
diff --git a/examples/webenginewidgets/spellchecker/dict/de/README.txt b/examples/webenginewidgets/spellchecker/dict/de/README.txt
new file mode 100644
index 000000000..f9c94e06d
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/dict/de/README.txt
@@ -0,0 +1,20 @@
+This is dummy german dictionary which knows only following words:
+
+* ich
+* du
+* er
+* sie
+* es
+* wir
+* ihr
+* sie
+* Sie
+* liebe
+* liebst
+* liebt
+* lieben
+* liebt
+* qt
+
+Also each of words above can start with 'q' for example
+* qich
diff --git a/examples/webenginewidgets/spellchecker/dict/de/de-DE.aff b/examples/webenginewidgets/spellchecker/dict/de/de-DE.aff
new file mode 100644
index 000000000..ff8185771
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/dict/de/de-DE.aff
@@ -0,0 +1,5 @@
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzqESIANRTOLCDUGMPHBYFVKWZQ
+
+PFX Q Y 1
+PFX Q 0 q .
diff --git a/examples/webenginewidgets/spellchecker/dict/de/de-DE.dic b/examples/webenginewidgets/spellchecker/dict/de/de-DE.dic
new file mode 100644
index 000000000..d10ae2600
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/dict/de/de-DE.dic
@@ -0,0 +1,14 @@
+15
+du/Q
+er/Q
+es/Q
+ich/Q
+ihr/Q
+liebe/Q
+lieben/Q
+liebst/Q
+liebt/Q
+qt/Q
+sie/Q
+Sie/Q
+wir/Q
diff --git a/examples/webenginewidgets/spellchecker/dict/en/README.txt b/examples/webenginewidgets/spellchecker/dict/en/README.txt
new file mode 100644
index 000000000..41b529292
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/dict/en/README.txt
@@ -0,0 +1,16 @@
+This is dummy english dictionary which knows only following words:
+
+* I
+* you
+* he
+* she
+* it
+* we
+* they
+* love
+* loves
+* qt
+
+Also each of words above can start with 'q' for example:
+
+* qI
diff --git a/examples/webenginewidgets/spellchecker/dict/en/en-US.aff b/examples/webenginewidgets/spellchecker/dict/en/en-US.aff
new file mode 100644
index 000000000..ff8185771
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/dict/en/en-US.aff
@@ -0,0 +1,5 @@
+SET UTF-8
+TRY esianrtolcdugmphbyfvkwzqESIANRTOLCDUGMPHBYFVKWZQ
+
+PFX Q Y 1
+PFX Q 0 q .
diff --git a/examples/webenginewidgets/spellchecker/dict/en/en-US.dic b/examples/webenginewidgets/spellchecker/dict/en/en-US.dic
new file mode 100644
index 000000000..3d4ecdfa4
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/dict/en/en-US.dic
@@ -0,0 +1,11 @@
+10
+he/Q
+I/Q
+it/Q
+love/Q
+loves/Q
+qt/Q
+she/Q
+they/Q
+we/Q
+you/Q
diff --git a/examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.png b/examples/webenginewidgets/spellchecker/doc/images/spellchecker-example.png
new file mode 100644
index 000000000..cc4e74946
--- /dev/null
+++ 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
new file mode 100644
index 000000000..b0240cd4d
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webenginewidgets/spellchecker
+ \title WebEngine Widgets Spellchecker Example
+ \ingroup webengine-widgetexamples
+ \brief Integrates a spellchecker into a simple HTML form.
+
+ \image spellchecker-example.png
+
+ \e {Spellchecker} demonstrates how to integrate spellchecking support into
+ an HTML form that enables users to submit spellchecked messages.
+
+ \include examples-run.qdocinc
+
+ \section1 Dictionaries
+
+ To be able to check the spelling, we need to provide the spellchecker with
+ dictionaries. The Qt WebEngine spellchecker supports dictionaries provided by the
+ \l {Hunspell project} on all platforms and native dictionaries provided by macOS.
+ In this example, we want to support the English and German languages.
+
+ For Hunspell dictionaries to be supported they have to be compiled into a special binary format.
+ A Hunspell dictionary consists of two files:
+
+ \list
+
+ \li A \c .dic file that is a dictionary containing words for the
+ language
+ \li An \c .aff file that defines the meaning of special flags in the
+ dictionary
+ \endlist
+
+ These two files can be converted into the \c bdic format by using the
+ \c qwebengine_convert_dict tool that is shipped together with Qt.
+
+ In this example, we are going to compile en_US and de_DE dictionaries.
+ However, the real full dictionaries would take too much space for the
+ purposes of this example. Therefore, we have created two dummy dictionaries
+ that contain the following words and can be used to demonstrate the
+ conversion process:
+
+ \list
+ \li English dictionary: I, you, he, she, it, we, they, love, loves, qt
+ \li German dictionary: ich, du, er, sie, es, wir, ihr, sie, Sie, liebe,
+ liebst, liebt, lieben, liebt, qt
+ \endlist
+
+ Each word in a dictionary can be prefixed with \c q. For more information
+ about how to create \c dic and \c aff files, see the Hunspell dictionary
+ file format specification in the \l{Hunspell Project}.
+
+ When a specific spellchecking language is requested, Qt WebEngine will try
+ to load the already compiled matching \c .bdic file first from
+ \e qtwebengine_dictionaries directories relative to the executable,
+ then it will look in \c QT_INSTALL_PREFIX/qtwebengine_dictionaries.
+
+ On macOS, because this example was configured to use Hunspell dictionaries, Qt WebEngine will
+ look in the \e qtwebengine_dictionaries directory located inside the application bundle
+ \c Resources directory, and also in the \c Resources directory located inside the
+ Qt framework bundle.
+
+ We specify the QMAKE_EXTRA_COMPILERS parameter in the project file to add a
+ conversion step to the build process:
+
+ \quotefromfile webenginewidgets/spellchecker/spellchecker.pro
+ \skipto CONVERT_TOOL
+ \printuntil QMAKE_EXTRA_COMPILERS
+
+ To set up a dictionary, we run \c qwebengine_convert_dict passing the
+ file path of the dictionary \c dic and \c bdic files. The \c aff file and
+ optional \c delta file are also picked up by the \c convert process.
+ The output \c bdic file is placed into the \e qtwebengine_dictionaries local
+ directory (or Resources directory), which the application binary will run from.
+
+ \section1 Setting the Spellchecker
+
+ The constructor of our class is trivial.
+
+ \quotefromfile webenginewidgets/spellchecker/webview.cpp
+ \skipto WebView::WebView
+ \printuntil }
+ We define simple mapping between our dictionary filenames and
+ the actual language display name. We will use that mapping to display names
+ of dictionaries in the context menu. Spellchecking is disabled by default.
+ Therefore we also enable spellchecker and set the \e English dictionary.
+ When Qt WebEngine's spellcheck service initializes, it will try to load the
+ \c bdict dictionaries and to check them for consistency.
+ Any errors are logged by using the qWarning() function.
+
+ \section1 Switching the Spellchecking Language
+
+ The current language used for spellchecking is defined per profile, and can
+ get set using the QWebEngineProfile::setSpellCheckLanguage method. When the
+ user clicks on an underlined misspelled word, the default context menu
+ displays up to four suggestions. Selecting one will replace the misspelled
+ word. We could reimplement a number of suggestions, by overriding
+ QWebEngineView::contextMenuEvent and using
+ QWebEngineContextMenuData::spellCheckerSuggestions, but we will demonstrate
+ how to add langague options in the context menu instead:
+
+ \quotefromfile webenginewidgets/spellchecker/webview.cpp
+ \skipto void WebView::contextMenuEvent
+ \printuntil menu->popup
+ \printline }
+
+ Above, we get the QWebEngineContextMenuData instance using the
+ QWebEnginePage::contextMenuData method. We use it to be notified when the
+ user clicks on an editable field and show the \uicontrol {Check Spelling}
+ item in the context menu. Moreover, if spellchecking is enabled, we also
+ add the \uicontrol {Select Language} submenu with the supported languages.
+ When an action is triggered, we set the language with the
+ QWebEngineProfile::setSpellCheckLanguage call.
+*/
diff --git a/examples/webenginewidgets/spellchecker/main.cpp b/examples/webenginewidgets/spellchecker/main.cpp
new file mode 100644
index 000000000..0d411f665
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "webview.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ WebView view;
+ view.setUrl(QUrl(QStringLiteral("qrc:/index.html")));
+ view.resize(500, 640);
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/spellchecker/spellchecker.pro b/examples/webenginewidgets/spellchecker/spellchecker.pro
new file mode 100644
index 000000000..c6031a36d
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/spellchecker.pro
@@ -0,0 +1,63 @@
+TEMPLATE = app
+TARGET = spellchecker
+QT += webenginewidgets
+CONFIG += c++11
+
+contains(WEBENGINE_CONFIG, use_native_spellchecker) {
+ error("Spellcheck example can not be built when using native OS dictionaries.")
+}
+
+HEADERS += \
+ webview.h
+
+SOURCES += \
+ main.cpp \
+ webview.cpp
+
+RESOURCES += \
+ data/spellchecker.qrc
+
+DISTFILES += \
+ dict/en/README.txt \
+ dict/en/en-US.dic \
+ dict/en/en-US.aff \
+ dict/de/README.txt \
+ dict/de/de-DE.dic \
+ dict/de/de-DE.aff
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/spellchecker
+INSTALLS += target
+
+qtPrepareTool(CONVERT_TOOL, qwebengine_convert_dict)
+
+debug_and_release {
+ CONFIG(debug, debug|release): DICTIONARIES_DIR = debug/qtwebengine_dictionaries
+ else: DICTIONARIES_DIR = release/qtwebengine_dictionaries
+} else {
+ DICTIONARIES_DIR = qtwebengine_dictionaries
+}
+
+dict_base_paths = en/en-US de/de-DE
+for (base_path, dict_base_paths) {
+ dict.files += $$PWD/dict/$${base_path}.dic
+}
+
+dictoolbuild.input = dict.files
+dictoolbuild.output = $${DICTIONARIES_DIR}/${QMAKE_FILE_BASE}.bdic
+dictoolbuild.depends = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.aff
+dictoolbuild.commands = $${CONVERT_TOOL} ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+dictoolbuild.name = Build ${QMAKE_FILE_IN_BASE}
+dictoolbuild.CONFIG = no_link target_predeps
+QMAKE_EXTRA_COMPILERS += dictoolbuild
+
+# When the example is compiled as a bundle, WebEngine expects to find the dictionaries in
+# bundle.app/Contents/Resources/qtwebengine_dictionaries
+macos:app_bundle {
+ for (base_path, dict_base_paths) {
+ base_path_splitted = $$split(base_path, /)
+ base_name = $$last(base_path_splitted)
+ binary_dict_files.files += $${DICTIONARIES_DIR}/$${base_name}.bdic
+ }
+ binary_dict_files.path = Contents/Resources/$$DICTIONARIES_DIR
+ QMAKE_BUNDLE_DATA += binary_dict_files
+}
diff --git a/examples/webenginewidgets/spellchecker/webview.cpp b/examples/webenginewidgets/spellchecker/webview.cpp
new file mode 100644
index 000000000..86e21ab13
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/webview.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "webview.h"
+#include <QContextMenuEvent>
+#include <QMenu>
+#include <QWebEngineProfile>
+#include <QWebEngineContextMenuData>
+
+WebView::WebView(QWidget *parent)
+ : QWebEngineView(parent)
+{
+ m_spellCheckLanguages["English"] = "en-US";
+ m_spellCheckLanguages["German"] = "de-DE";
+ QWebEngineProfile *profile = page()->profile();
+ profile->setSpellCheckEnabled(true);
+ profile->setSpellCheckLanguages({"en-US"});
+}
+
+void WebView::contextMenuEvent(QContextMenuEvent *event)
+{
+ const QWebEngineContextMenuData &data = page()->contextMenuData();
+ Q_ASSERT(data.isValid());
+
+ if (!data.isContentEditable()) {
+ QWebEngineView::contextMenuEvent(event);
+ return;
+ }
+
+ QWebEngineProfile *profile = page()->profile();
+ const QString &language = profile->spellCheckLanguages().first();
+ QMenu *menu = page()->createStandardContextMenu();
+ menu->addSeparator();
+
+ QAction *spellcheckAction = new QAction(tr("Check Spelling"));
+ spellcheckAction->setCheckable(true);
+ spellcheckAction->setChecked(profile->isSpellCheckEnabled());
+ connect(spellcheckAction, &QAction::toggled, this, [profile](bool toogled) {
+ profile->setSpellCheckEnabled(toogled);
+ });
+ menu->addAction(spellcheckAction);
+
+ if (profile->isSpellCheckEnabled()) {
+ QMenu *subMenu = menu->addMenu(tr("Select Language"));
+ foreach (const QString &str, m_spellCheckLanguages.keys()) {
+ QAction *action = subMenu->addAction(str);
+ action->setCheckable(true);
+ QString lang = m_spellCheckLanguages[str];
+ action->setChecked(language == lang);
+ connect(action, &QAction::triggered, this, [profile, lang](){
+ profile->setSpellCheckLanguages(QStringList()<<lang);
+ });
+ }
+ }
+ connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
+ menu->popup(event->globalPos());
+}
+
+
diff --git a/examples/webenginewidgets/spellchecker/webview.h b/examples/webenginewidgets/spellchecker/webview.h
new file mode 100644
index 000000000..787d06a1a
--- /dev/null
+++ b/examples/webenginewidgets/spellchecker/webview.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEBVIEW_H
+#define WEBVIEW_H
+
+#include <QWebEngineView>
+
+class WebView : public QWebEngineView
+{
+ Q_OBJECT
+
+public:
+ WebView(QWidget *parent = nullptr);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event) override;
+
+private:
+ QMap<QString,QString> m_spellCheckLanguages;
+};
+
+#endif