summaryrefslogtreecommitdiffstats
path: root/examples/webengine/recipebrowser/resources
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2016-08-10 13:31:04 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2016-08-31 15:29:40 +0000
commitf5e690bff349d48d8493695088bf90025898bf39 (patch)
treeace30868050cac48eeaab5a3659896d30f931db4 /examples/webengine/recipebrowser/resources
parentf3a8486ffb9551818c7823b9e2d3ad09dab53b56 (diff)
Add recipebrowser example
The example uses WebEngineView and Qt Quick Controls 2 items to demonstrate how to write a small hybrid QtQuick / HTML application, and also shows the usage of the new focusOnNavigationEnabled setting. Task-number: QTBUG-52999 Change-Id: I1813a658a2f46e90f9ca4e8229a8c8fbb6590248 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'examples/webengine/recipebrowser/resources')
-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.qml153
-rw-r--r--examples/webengine/recipebrowser/resources/resources.qrc28
23 files changed, 1165 insertions, 0 deletions
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..84067e8f5
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/qml/main.qml
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** 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
+ 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>