Merge lp:~justinmcp/webbrowser-app/add-to-homescreen into lp:webbrowser-app

Proposed by David Barth
Status: Work in progress
Proposed branch: lp:~justinmcp/webbrowser-app/add-to-homescreen
Merge into: lp:webbrowser-app
Diff against target: 1467 lines (+1139/-85)
13 files modified
src/app/webbrowser/AddressBar.qml (+28/-7)
src/app/webbrowser/BookmarkOptions.qml (+222/-70)
src/app/webbrowser/Browser.qml (+54/-5)
src/app/webbrowser/CMakeLists.txt (+1/-0)
src/app/webbrowser/Chrome.qml (+7/-0)
src/app/webbrowser/FavoriteOptionTabs.qml (+389/-0)
src/app/webbrowser/NavigationBar.qml (+11/-0)
src/app/webbrowser/page-metadata-gathering.js (+100/-0)
src/app/webbrowser/webapps-extension.cpp (+234/-0)
src/app/webbrowser/webapps-extension.h (+52/-0)
src/app/webbrowser/webbrowser-app.cpp (+10/-0)
src/app/webcontainer/WebApp.qml (+28/-0)
tests/unittests/CMakeLists.txt (+3/-3)
To merge this branch: bzr merge lp:~justinmcp/webbrowser-app/add-to-homescreen
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Ubuntu Phablet Team Pending
Review via email: mp+271914@code.launchpad.net

Commit message

Communicate with the unity-chromium-extension to verify the availability of a webapp for the URL being navigated.

Description of the change

Communicate with the unity-chromium-extension to verify the availability of a webapp for the URL being navigated.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1162. By Justin McPherson

WIP

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1163. By Justin McPherson

WIP

1164. By Justin McPherson

WIP

1165. By Justin McPherson

Merge from trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1166. By Justin McPherson

WIP

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1167. By Justin McPherson

WIP

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

1167. By Justin McPherson

WIP

1166. By Justin McPherson

WIP

1165. By Justin McPherson

Merge from trunk.

1164. By Justin McPherson

WIP

1163. By Justin McPherson

WIP

1162. By Justin McPherson

WIP

1161. By Justin McPherson

WIP

1160. By Justin McPherson

WIP

1159. By Justin McPherson

WIP

1158. By Justin McPherson

WIP

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app/webbrowser/AddressBar.qml'
2--- src/app/webbrowser/AddressBar.qml 2015-09-01 17:25:21 +0000
3+++ src/app/webbrowser/AddressBar.qml 2015-09-30 04:21:34 +0000
4@@ -30,13 +30,9 @@
5 property bool incognito: false
6 property alias text: textField.text
7 property bool bookmarked: false
8- signal toggleBookmark()
9 property url requestedUrl
10 property url actualUrl
11- signal validated()
12 property bool loading
13- signal requestReload()
14- signal requestStop()
15 property string searchUrl
16 property bool canSimplifyText: true
17 property bool editing: false
18@@ -44,6 +40,8 @@
19 property bool findInPageMode: false
20 property var findController: null
21
22+ property var webappCapableWebsite: null
23+
24 property var securityStatus: null
25
26 readonly property Item bookmarkTogglePlaceHolder: bookmarkTogglePlaceHolderItem
27@@ -54,12 +52,27 @@
28 readonly property Item __actionButton: action
29 readonly property Item __bookmarkToggle: bookmarkToggle
30
31+ signal validated()
32+ signal requestReload()
33+ signal requestStop()
34+ signal webappLaunchRequest(var webApplication)
35+ signal toggleBookmark()
36+
37 height: textField.height
38
39 function selectAll() {
40 textField.selectAll()
41 }
42
43+ function getBookmarkToggleColor(webappCapable) {
44+ if (webappCapable) {
45+ return UbuntuColors.lightAubergine
46+ }
47+
48+ return addressbar.bookmarked ?
49+ UbuntuColors.orange : bookmarkToggleIcon.keyColor
50+ }
51+
52 Binding {
53 target: findController
54 property: "text"
55@@ -216,15 +229,23 @@
56 visible: !findInPageMode && internal.idle && addressbar.actualUrl.toString()
57
58 Icon {
59+ id: bookmarkToggleIcon
60+
61 height: parent.height - units.gu(2)
62 width: height
63 anchors.centerIn: parent
64
65- name: addressbar.bookmarked ? "starred" : "non-starred"
66- color: addressbar.bookmarked ? UbuntuColors.orange : UbuntuColors.darkGrey
67+ name: addressbar.bookmarked || webappCapableWebsite ? "starred" : "non-starred"
68+ color: getBookmarkToggleColor(webappCapableWebsite)
69 }
70
71- onClicked: addressbar.toggleBookmark()
72+ onClicked: {
73+ if (webappCapableWebsite != null) {
74+ webappLaunchRequest(webappCapableWebsite);
75+ } else {
76+ toggleBookmark();
77+ }
78+ }
79
80 Item {
81 id: bookmarkTogglePlaceHolderItem
82
83=== modified file 'src/app/webbrowser/BookmarkOptions.qml'
84--- src/app/webbrowser/BookmarkOptions.qml 2015-08-10 15:22:00 +0000
85+++ src/app/webbrowser/BookmarkOptions.qml 2015-09-30 04:21:34 +0000
86@@ -23,84 +23,236 @@
87 Popover {
88 id: bookmarkOptions
89
90+ property var webApplication: null
91 property url bookmarkUrl
92 property alias bookmarkTitle: titleTextField.text
93 property alias folderModel: folderOptionSelector.model
94
95 readonly property string bookmarkFolder: folderModel.get(folderOptionSelector.selectedIndex).folder
96
97- contentHeight: bookmarkOptionsColumn.childrenRect.height + units.gu(2)
98-
99- Column {
100- id: bookmarkOptionsColumn
101-
102- anchors {
103- top: parent.top
104- left: parent.left
105- right: parent.right
106- margins: units.gu(1)
107- }
108-
109- spacing: units.gu(1)
110-
111- Label {
112- font.bold: true
113- text: i18n.tr("Bookmark Added")
114- }
115-
116- Label {
117- // TRANSLATORS: Field where the title of bookmarked URL can be changed
118- text: i18n.tr("Name")
119- fontSize: "small"
120- }
121-
122- TextField {
123- id: titleTextField
124- objectName: "titleTextField"
125-
126- anchors {
127- left: parent.left
128- right: parent.right
129- }
130-
131- inputMethodHints: Qt.ImhNoPredictiveText
132- }
133-
134- Label {
135- // TRANSLATORS: Field to choose the folder where bookmarked URL will be saved in
136- text: i18n.tr("Save in")
137- fontSize: "small"
138- }
139-
140- OptionSelector {
141- id: folderOptionSelector
142-
143- delegate: OptionSelectorDelegate { text: folder === "" ? i18n.tr("All Bookmarks") : folder }
144- containerHeight: itemHeight * 3
145- }
146-
147- Item {
148- anchors {
149- left: parent.left
150- right: parent.right
151- }
152-
153- height: newFolderButton.height
154-
155- Button {
156- id: newFolderButton
157- objectName: "bookmarkOptions.newButton"
158- text: i18n.tr("New Folder")
159- onClicked: PopupUtils.open(newFolderDialog)
160- }
161-
162- Button {
163- id: okButton
164+ signal launchWebApplication();
165+
166+ contentHeight: bookmarkOptionsColumn.childrenRect.height + units.gu(8)
167+
168+ Rectangle {
169+ id: header
170+ anchors.centerIn: parent
171+
172+ width: parent.width
173+ height: units.gu(6)
174+
175+ Rectangle {
176+ id: launchTabHeader
177+
178+ property bool selected: webApplication != null
179+
180+ visible: webApplication != null
181+
182+ color: "white"
183+
184+ height: units.gu(6)
185+ width: parent.width / 2
186+
187+ anchors {
188+ right: parent.right
189+ top: parent.top
190+ }
191+
192+ border.color: "black"
193+ border.width: selected ? 0 : 2
194+
195+ Label {
196+ anchors.centerIn: launchTabHeader
197+ text: i18n.tr("Launch App")
198+ font.bold: true
199+ }
200+
201+ MouseArea {
202+ anchors.fill: parent
203+ onClicked: {
204+ if (!launchTabHeader.selected) {
205+ launchTabHeader.selected = true
206+ }
207+ }
208+ }
209+ }
210+
211+ Rectangle {
212+ id: bookmarkTabHeader
213+
214+ property bool selected: !launchTabHeader.selected
215+
216+ color: "white"
217+
218+ height: units.gu(6)
219+ width: parent.width/2
220+
221+ anchors {
222+ right: launchTabHeader.left
223+ top: parent.top
224+ }
225+
226+ border.color: "black"
227+ border.width: selected ? 0 : 2
228+
229+ Label {
230+ anchors.centerIn: bookmarkTabHeader
231+ text: i18n.tr("Add bookmark")
232+ font.bold: true
233+ }
234+
235+ MouseArea {
236+ anchors.fill: parent
237+ onClicked: {
238+ if (!bookmarkTabHeader.selected) {
239+ launchTabHeader.selected = false
240+ }
241+ }
242+ }
243+ }
244+ }
245+
246+ Rectangle {
247+ id: bookmarkTabContent
248+ visible: bookmarkTabHeader.selected
249+
250+ anchors {
251+ top: header.bottom
252+ left: parent.left
253+ right: parent.right
254+ bottom: parent.bottom
255+ }
256+
257+ Column {
258+ id: bookmarkOptionsColumn
259+
260+ anchors {
261+ top: parent.top
262+ left: parent.left
263+ right: parent.right
264+ margins: units.gu(1)
265+ }
266+
267+ spacing: units.gu(1)
268+
269+ Label {
270+ // TRANSLATORS: Field where the title of bookmarked URL can be changed
271+ text: i18n.tr("Name")
272+ fontSize: "small"
273+ }
274+
275+ TextField {
276+ id: titleTextField
277+ objectName: "titleTextField"
278+
279+ anchors {
280+ left: parent.left
281+ right: parent.right
282+ }
283+
284+ inputMethodHints: Qt.ImhNoPredictiveText
285+ }
286+
287+ Label {
288+ // TRANSLATORS: Field to choose the folder where bookmarked URL will be saved in
289+ text: i18n.tr("Save in")
290+ fontSize: "small"
291+ }
292+
293+ OptionSelector {
294+ id: folderOptionSelector
295+
296+ delegate: OptionSelectorDelegate { text: folder === "" ? i18n.tr("All Bookmarks") : folder }
297+ containerHeight: itemHeight * 3
298+ }
299+
300+ Item {
301+ anchors {
302+ left: parent.left
303+ right: parent.right
304+ }
305+
306+ height: newFolderButton.height
307+
308+ Button {
309+ id: newFolderButton
310+ objectName: "bookmarkOptions.newButton"
311+ text: i18n.tr("New Folder")
312+ onClicked: PopupUtils.open(newFolderDialog)
313+ }
314+
315+ Button {
316+ id: okButton
317+ objectName: "bookmarkOptions.okButton"
318+ anchors.right: parent.right
319+ text: i18n.tr("OK")
320+ color: UbuntuColors.green
321+ onClicked: hide()
322+ }
323+ }
324+ }
325+ }
326+
327+ Rectangle {
328+ id: launchTabContent
329+ visible: launchTabHeader.selected
330+
331+ anchors {
332+ top: header.bottom
333+ left: parent.left
334+ right: parent.right
335+ bottom: parent.bottom
336+ }
337+
338+ Column {
339+ anchors {
340+ top: parent.top
341+ left: parent.left
342+ right: parent.right
343+ margins: units.gu(1)
344+ }
345+
346+ spacing: units.gu(2)
347+
348+ Label {
349+ anchors {
350+ horizontalCenter: parent.horizontalCenter
351+ }
352+ width: parent.width - units.gu(1)
353+ horizontalAlignment: Text.AlignHCenter
354+ wrapMode: Text.WordWrap
355+ text: "We found a web application for this site"
356+ }
357+
358+ Label {
359+ anchors {
360+ horizontalCenter: parent.horizontalCenter
361+ }
362+ width: parent.width - units.gu(1)
363+ font.bold: true
364+ horizontalAlignment: Text.AlignHCenter
365+ text: webApplication == null ? "" : webApplication.appName
366+ }
367+
368+ Label {
369+ anchors {
370+ horizontalCenter: parent.horizontalCenter
371+ }
372+ width: parent.width - units.gu(1)
373+ horizontalAlignment: Text.AlignHCenter
374+ wrapMode: Text.WordWrap
375+ text: "Press the launch button to start the application"
376+ }
377+
378+ Button {
379 objectName: "bookmarkOptions.okButton"
380- anchors.right: parent.right
381- text: i18n.tr("OK")
382+ anchors {
383+ horizontalCenter: parent.horizontalCenter
384+ topMargin: units.gu(2)
385+ }
386+ text: i18n.tr("Launch")
387 color: UbuntuColors.green
388- onClicked: hide()
389+ onClicked: { launchWebApplication(); hide() }
390 }
391 }
392 }
393
394=== modified file 'src/app/webbrowser/Browser.qml'
395--- src/app/webbrowser/Browser.qml 2015-09-28 08:15:10 +0000
396+++ src/app/webbrowser/Browser.qml 2015-09-30 04:21:34 +0000
397@@ -339,14 +339,48 @@
398 }
399 bookmarked: isCurrentUrlBookmarked()
400 onToggleBookmark: {
401- if (isCurrentUrlBookmarked()) browser.bookmarksModel.remove(webview.url)
402- else internal.addBookmark(webview.url, webview.title, webview.icon)
403- }
404+ if (isCurrentUrlBookmarked()) {
405+ browser.bookmarksModel.remove(webview.url);
406+ } else {
407+ internal.addBookmark(webview.url, webview.title, webview.icon);
408+ }
409+ }
410+ onWebappLaunchRequest: {
411+ PopupUtils.open(bookmarkOptionsComponent,
412+ chrome.bookmarkTogglePlaceHolder,
413+ { "bookmarkUrl": webview.url,
414+ "bookmarkTitle": webview.title,
415+ "webApplication": webApplication });
416+ }
417+ onLaunchWebApplication: {
418+ WebappsExtension.launchWebApp(webview.url);
419+ }
420+
421 onWebviewChanged: bookmarked = isCurrentUrlBookmarked()
422 Connections {
423 target: chrome.webview
424- onUrlChanged: chrome.bookmarked = chrome.isCurrentUrlBookmarked()
425- }
426+ onUrlChanged: {
427+ chrome.bookmarked = chrome.isCurrentUrlBookmarked();
428+ chrome.launched = false
429+ // TODO: Dont check multiple times per session
430+ WebappsExtension.supportedUrl(chrome.webview.url);
431+ }
432+ }
433+ Connections {
434+ target: WebappsExtension
435+ onWebappSupported: {
436+ // Confirm URL because of nav?
437+ if (webApplication && webApplication.available) {
438+ chrome.webappCapableWebsite = webApplication;
439+ }
440+ }
441+ onWebappLaunched: {
442+ if (success) {
443+ chrome.launched = true
444+ }
445+ }
446+ }
447+
448 Connections {
449 target: browser.bookmarksModel
450 onAdded: if (!chrome.bookmarked && (url === chrome.webview.url)) chrome.bookmarked = true
451@@ -453,6 +487,18 @@
452 }
453 }
454
455+ Connections {
456+ target: browser.currentWebview
457+ onLoadingChanged: {
458+ if (browser.currentWebview.loading) {
459+ chrome.webappCapableWebsite = null
460+ chrome.state = "shown"
461+ } else if (browser.currentWebview.fullscreen) {
462+ chrome.state = "hidden"
463+ }
464+ }
465+ }
466+
467 ChromeController {
468 id: chromeController
469 webview: browser.currentWebview
470@@ -582,6 +628,8 @@
471 }
472 }
473 }
474+
475+ onLaunchWebApplication: chrome.launchWebApplication()
476 }
477 }
478 }
479@@ -947,6 +995,7 @@
480 preferences.appCacheEnabled: true
481
482 property QtObject contextModel: null
483+
484 contextualActions: ActionList {
485 Actions.OpenLinkInNewTab {
486 objectName: "OpenLinkInNewTabContextualAction"
487
488=== modified file 'src/app/webbrowser/CMakeLists.txt'
489--- src/app/webbrowser/CMakeLists.txt 2015-09-22 01:27:19 +0000
490+++ src/app/webbrowser/CMakeLists.txt 2015-09-30 04:21:34 +0000
491@@ -37,6 +37,7 @@
492 set(WEBBROWSER_APP_SRC
493 cache-deleter.cpp
494 file-operations.cpp
495+ webapps-extension.cpp
496 searchengine.cpp
497 webbrowser-app.cpp
498 )
499
500=== modified file 'src/app/webbrowser/Chrome.qml'
501--- src/app/webbrowser/Chrome.qml 2015-09-23 18:43:10 +0000
502+++ src/app/webbrowser/Chrome.qml 2015-09-30 04:21:34 +0000
503@@ -28,6 +28,7 @@
504 property alias text: navigationBar.text
505 property alias bookmarked: navigationBar.bookmarked
506 signal toggleBookmark()
507+ property alias launched: navigationBar.launched
508 property alias drawerActions: navigationBar.drawerActions
509 property alias drawerOpen: navigationBar.drawerOpen
510 property alias requestedUrl: navigationBar.requestedUrl
511@@ -49,6 +50,11 @@
512 navigationBar.selectAll()
513 }
514
515+ property alias webappCapableWebsite: navigationBar.webappCapableWebsite
516+
517+ signal launchWebApplication();
518+ signal webappLaunchRequest(var webApplication)
519+
520 FocusScope {
521 id: content
522 anchors.fill: parent
523@@ -95,6 +101,7 @@
524 height: units.gu(6)
525
526 onToggleBookmark: chrome.toggleBookmark()
527+ onWebappLaunchRequest: chrome.webappLaunchRequest(webApplication)
528 }
529 }
530 }
531
532=== added file 'src/app/webbrowser/FavoriteOptionTabs.qml'
533--- src/app/webbrowser/FavoriteOptionTabs.qml 1970-01-01 00:00:00 +0000
534+++ src/app/webbrowser/FavoriteOptionTabs.qml 2015-09-30 04:21:34 +0000
535@@ -0,0 +1,389 @@
536+/*
537+ * Copyright 2015 Canonical Ltd.
538+ *
539+ * This file is part of webbrowser-app.
540+ *
541+ * webbrowser-app is free software; you can redistribute it and/or modify
542+ * it under the terms of the GNU General Public License as published by
543+ * the Free Software Foundation; version 3.
544+ *
545+ * webbrowser-app is distributed in the hope that it will be useful,
546+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
547+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
548+ * GNU General Public License for more details.
549+ *
550+ * You should have received a copy of the GNU General Public License
551+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
552+ */
553+
554+import QtQuick 2.0
555+import Ubuntu.Components 1.1
556+
557+
558+Rectangle {
559+ id: dialog
560+
561+ property bool isWebappLaunchable: false
562+ property bool launchRequested: false
563+
564+ property string bookmarkTitle: ""
565+
566+ property var webappCapableWebsite
567+
568+ property bool launchingWebapp: false
569+
570+ border.color: "black"
571+ border.width: 2
572+
573+ function webappLaunchingComplete() {
574+ launchActivityIndicator.running = false
575+ }
576+
577+ onWebappCapableWebsiteChanged: {
578+ isWebappLaunchable = webappCapableWebsite != null;
579+ launchRequested = false
580+ }
581+
582+ onLaunchingWebappChanged: {
583+ launchActivityIndicator.running = false
584+ launchActivityIndicator.visible = false
585+ }
586+
587+ onVisibleChanged: {
588+ if (visible) {
589+ if (isWebappLaunchable)
590+ setLaunchTabAsSelected();
591+ else
592+ setBookmarkTabAsSelected()
593+ }
594+ }
595+
596+ signal bookmarked()
597+ signal launchWebApplication(var metainfos)
598+
599+ function setBookmarkTabAsSelected() {
600+ launchTabHeader.selected = false
601+ launchTabHeader.border.width = 2
602+
603+ bookmarkTabHeader.selected = true
604+ bookmarkTabHeader.border.width = 0
605+
606+ launchTabContent.visible = false
607+ bookmarkTabContent.visible = true
608+ }
609+
610+ function setLaunchTabAsSelected() {
611+ bookmarkTabHeader.selected = false
612+ bookmarkTabHeader.border.width = 2
613+
614+ launchTabHeader.selected = true
615+ launchTabHeader.border.width = 0
616+
617+ launchTabContent.visible = true
618+ bookmarkTabContent.visible = false
619+ }
620+
621+ color: "white"
622+
623+ Rectangle {
624+
625+ anchors.centerIn: parent
626+
627+ height: parent.height - 2
628+ width: parent.width - 2
629+
630+ border.color: "black"
631+ border.width: 2
632+
633+ radius: units.gu(1)
634+
635+ Item {
636+ id: content
637+ anchors.fill: parent
638+
639+ Rectangle {
640+ id: launchTabHeader
641+
642+ property bool selected: true
643+
644+ opacity: 1
645+
646+ color: "white"
647+
648+ height: units.gu(6)
649+ width: parent.width/2
650+
651+ anchors.right: parent.right
652+ anchors.top: parent.top
653+
654+ border.color: "black"
655+ border.width: 2
656+
657+ Label {
658+ anchors.centerIn: launchTabHeader
659+ text: i18n.tr("Launch App")
660+ font.bold: true
661+ }
662+ }
663+ MouseArea {
664+ anchors.fill: launchTabHeader
665+ onClicked: {
666+ if (! launchTabHeader.selected) {
667+ setLaunchTabAsSelected()
668+ }
669+ }
670+ }
671+
672+ Rectangle {
673+ id: bookmarkTabHeader
674+
675+ property bool selected: false
676+
677+ opacity: 1
678+
679+ color: "white"
680+
681+ height: units.gu(6)
682+ width: parent.width/2
683+
684+ anchors.right: launchTabHeader.left
685+ anchors.top: parent.top
686+
687+ border.color: "black"
688+ border.width: 2
689+
690+ Label {
691+ anchors.centerIn: bookmarkTabHeader
692+ text: i18n.tr("Add bookmark")
693+ font.bold: true
694+ }
695+ }
696+ MouseArea {
697+ anchors.fill: bookmarkTabHeader
698+ onClicked: {
699+ if (! bookmarkTabHeader.selected) {
700+ setBookmarkTabAsSelected()
701+ }
702+ }
703+ }
704+
705+ Rectangle {
706+ id: bookmarkTabContent
707+
708+ visible: false
709+
710+ color: "white"
711+
712+ height: parent.height - units.gu(6)
713+
714+ anchors.right: parent.right
715+ anchors.left: parent.left
716+
717+ anchors.top: bookmarkTabHeader.bottom
718+ anchors.topMargin: units.gu(2)
719+
720+ Column {
721+ id: bookmarkDetailsArea
722+
723+ spacing: units.gu(2)
724+ anchors.leftMargin: units.gu(2)
725+
726+ anchors.fill: parent
727+
728+ Label {
729+ id: bookmarkNameLabel
730+
731+ text: i18n.tr("bookmark name")
732+ }
733+ TextField {
734+ id: bookmarkNameText
735+ text: bookmarkTitle
736+ width: parent.width - units.gu(2)
737+ }
738+
739+ Label {
740+ id: bookmarkSaveInLabel
741+
742+ text: i18n.tr("save in")
743+ }
744+ Rectangle {
745+ id: bookmarkSeparator
746+ color: "black"
747+ height: 2
748+ smooth: true
749+ width: parent.width - units.gu(2)
750+ opacity: 0.5
751+ }
752+ Label {
753+ id: bookmarkExistingNameLabel
754+
755+ text: i18n.tr("All Bookmarks")
756+ fontSize: "large"
757+
758+ MouseArea {
759+ anchors.fill: parent
760+ onClicked: bookmarked()
761+ }
762+ }
763+ }
764+ }
765+
766+ Rectangle {
767+ id: launchTabContent
768+
769+ visible: false
770+
771+ color: "white"
772+
773+ height: parent.height - units.gu(6)
774+
775+ anchors.right: parent.right
776+ anchors.left: parent.left
777+ anchors.top: launchTabHeader.bottom
778+
779+ Rectangle {
780+ id: launchGridImageArea
781+
782+ border.width: 1
783+ border.color: "black"
784+
785+ width: parent.width/2 - units.gu(3)
786+ height: parent.width/2 - units.gu(3)
787+
788+ anchors.left: parent.left
789+ anchors.top: parent.top
790+ anchors.bottom: parent.bottom
791+
792+ anchors.leftMargin: units.gu(3)/2
793+ anchors.rightMargin: units.gu(3)/2
794+ anchors.topMargin: units.gu(3)/2
795+ anchors.bottomMargin: units.gu(3)/2
796+
797+ Item {
798+ anchors.fill: parent
799+ clip: true
800+
801+ anchors.leftMargin: units.gu(3)/2
802+ anchors.rightMargin: units.gu(3)/2
803+ anchors.topMargin: units.gu(3)/2
804+ anchors.bottomMargin: units.gu(3)/2
805+
806+ Column {
807+ x: parent.x - units.gu(4)
808+ y: parent.y - units.gu(4)
809+
810+ Row {
811+ UbuntuShape {
812+ radius: "medium"
813+ color: "#E6E4E2"
814+ width: launchGridImageArea.width/3
815+ height: launchGridImageArea.height/3
816+ }
817+ UbuntuShape {
818+ radius: "medium"
819+ color: "#E6E4E2"
820+ width: launchGridImageArea.width/3
821+ height: launchGridImageArea.height/3
822+ }
823+ UbuntuShape {
824+ radius: "medium"
825+ color: "#E6E4E2"
826+ width: launchGridImageArea.width/3
827+ height: launchGridImageArea.height/3
828+ }
829+ }
830+ Row {
831+ UbuntuShape {
832+ radius: "medium"
833+ color: "#E6E4E2"
834+ width: launchGridImageArea.width/3
835+ height: launchGridImageArea.height/3
836+ }
837+ UbuntuShape {
838+ radius: "medium"
839+ color: "#E6E4E2"
840+ width: launchGridImageArea.width/3
841+ height: launchGridImageArea.height/3
842+ }
843+ UbuntuShape {
844+ radius: "medium"
845+ color: "#E6E4E2"
846+ width: launchGridImageArea.width/3
847+ height: launchGridImageArea.height/3
848+ }
849+ }
850+ Row {
851+ UbuntuShape {
852+ radius: "medium"
853+ color: "#E6E4E2"
854+ width: launchGridImageArea.width/3
855+ height: launchGridImageArea.height/3
856+ }
857+ UbuntuShape {
858+ radius: "medium"
859+ color: "#E6E4E2"
860+ width: launchGridImageArea.width/3
861+ height: launchGridImageArea.height/3
862+ }
863+ UbuntuShape {
864+ radius: "medium"
865+ color: "#E6E4E2"
866+ width: launchGridImageArea.width/3
867+ height: launchGridImageArea.height/3
868+ }
869+ }
870+ }
871+ }
872+ }
873+
874+ Item {
875+ id: launchButtonArea
876+
877+ anchors.left: launchGridImageArea.right
878+ anchors.leftMargin: units.gu(4)
879+
880+ anchors.right: parent.right
881+ anchors.top: parent.top
882+ anchors.topMargin: units.gu(10)
883+
884+ anchors.bottom: parent.bottom
885+
886+ Column {
887+ spacing: units.gu(4)
888+ anchors.horizontalCenter: parent.horizontalCenter
889+
890+ Label {
891+ id: launchLabel
892+ text: "Launch " + (webappCapableWebsite ? webappCapableWebsite.appName : "");
893+ anchors.horizontalCenter: parent.horizontalCenter
894+ }
895+
896+ Button {
897+ id: launchButton
898+ text: i18n.tr("Launch")
899+
900+ enabled: !launchingWebapp
901+
902+ anchors.topMargin: units.gu(1)
903+ anchors.horizontalCenter: parent.horizontalCenter
904+
905+ onClicked: {
906+ launchingWebapp = true
907+ launchActivityIndicator.running = true
908+
909+ launchWebApplication(webappCapableWebsite)
910+ }
911+
912+ ActivityIndicator {
913+ id: launchActivityIndicator
914+ running: launchingWebapp
915+ visible: running
916+ anchors.fill: parent
917+ }
918+ }
919+ }
920+ }
921+ }
922+ }
923+ }
924+}
925
926=== modified file 'src/app/webbrowser/NavigationBar.qml'
927--- src/app/webbrowser/NavigationBar.qml 2015-08-13 11:11:59 +0000
928+++ src/app/webbrowser/NavigationBar.qml 2015-09-30 04:21:34 +0000
929@@ -42,6 +42,12 @@
930 onFindInPageModeChanged: if (findInPageMode) addressbar.text = ""
931 onIncognitoChanged: findInPageMode = false
932
933+ property bool launched: false
934+ property alias webappCapableWebsite: addressbar.webappCapableWebsite
935+
936+ signal launchWebApplication(var webAppplicationInformation)
937+ signal webappLaunchRequest(var webApplication)
938+
939 function selectAll() {
940 addressbar.selectAll()
941 }
942@@ -128,6 +134,7 @@
943 }
944 onRequestStop: webview.stop()
945 onToggleBookmark: root.toggleBookmark()
946+ onWebappLaunchRequest: root.webappLaunchRequest(webApplication)
947
948 Connections {
949 target: webview
950@@ -223,6 +230,10 @@
951 }
952 }
953
954+ onLaunchedChanged: {
955+ favoriteView.launchingWebapp = false
956+ }
957+
958 Component {
959 id: drawerComponent
960
961
962=== added file 'src/app/webbrowser/page-metadata-gathering.js'
963--- src/app/webbrowser/page-metadata-gathering.js 1970-01-01 00:00:00 +0000
964+++ src/app/webbrowser/page-metadata-gathering.js 2015-09-30 04:21:34 +0000
965@@ -0,0 +1,100 @@
966+/*
967+ * Copyright 2015 Canonical Ltd.
968+ *
969+ * This file is part of webbrowser-app.
970+ *
971+ * webbrowser-app is free software; you can redistribute it and/or modify
972+ * it under the terms of the GNU General Public License as published by
973+ * the Free Software Foundation; version 3.
974+ *
975+ * webbrowser-app is distributed in the hope that it will be useful,
976+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
977+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
978+ * GNU General Public License for more details.
979+ *
980+ * You should have received a copy of the GNU General Public License
981+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
982+ */
983+
984+// Runs at document-end by default
985+(function() {
986+ function detectWebappManifest() {
987+ var webapp_capable_meta =
988+ document.head.querySelector('meta[name="mobile-web-app-capable"]');
989+ var manifest = document.head.querySelector('link[rel="manifest"]');
990+ var theme_color_meta = document.head.querySelector('meta[name="theme-color"]');
991+
992+ if (webapp_capable_meta &&
993+ manifest &&
994+ webapp_capable_meta.getAttribute('content') === 'yes' &&
995+ manifest.getAttribute('href')) {
996+
997+ oxide.sendMessage(
998+ 'webapp-capable-website-detected', {
999+ type: 'manifest',
1000+ manifest: manifest.href,
1001+ baseurl: document.location.href,
1002+ theme_color: theme_color_meta.getAttribute('content')
1003+ });
1004+ return true;
1005+ }
1006+ return false;
1007+ }
1008+
1009+ function detectAppleMetaWebappInfo() {
1010+ var webapp_capable_meta =
1011+ document.head.querySelector('meta[name="apple-mobile-web-app-capable"]');
1012+ var webapp_title_meta =
1013+ document.head.querySelector('meta[name="apple-mobile-web-app-title"]');
1014+ var webapp_color_meta =
1015+ document.head.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
1016+
1017+ function getAppleIcons() {
1018+ // by order of pref
1019+ var apple_icon = document.head.querySelector('link[rel="apple-touch-icon"]');
1020+ var apple_icon_pre = document.head.querySelector('link[rel="apple-touch-icon-precomposed"]');
1021+ var fallback_icon = document.head.querySelector('link[rel="icon"]');
1022+
1023+ if (apple_icon &&
1024+ apple_icon.getAttribute('href')) {
1025+ return [apple_icon.getAttribute('href')];
1026+ }
1027+ if (apple_icon_pre &&
1028+ apple_icon_pre.getAttribute('href')) {
1029+ return [apple_icon_pre.getAttribute('href')];
1030+ }
1031+
1032+ // TODO watch out for multiple defs (sizes)
1033+ if (fallback_icon &&
1034+ fallback_icon.getAttribute('href')) {
1035+ return [fallback_icon.getAttribute('href')];
1036+ }
1037+ }
1038+
1039+ if (webapp_capable_meta &&
1040+ webapp_title_meta &&
1041+ webapp_capable_meta.getAttribute('content') === 'yes' &&
1042+ webapp_title_meta.getAttribute('content')) {
1043+ oxide.sendMessage(
1044+ 'webapp-capable-website-detected', {
1045+ type: 'apple',
1046+ manifest: document.head.innerHTML,
1047+ baseurl: document.location.href,
1048+ title: webapp_title_meta.getAttribute('content'),
1049+ icons: getAppleIcons(),
1050+ theme_color: webapp_color_meta ?
1051+ webapp_color_meta.getAttribute('content') : ''
1052+ });
1053+ return true;
1054+ }
1055+ return false;
1056+ }
1057+
1058+ var detectors = [detectAppleMetaWebappInfo, detectWebappManifest];
1059+ for (var i in detectors) {
1060+ if (detectors[i]()) {
1061+ console.log('Webapp capable website detected by ' + detectors[i].name);
1062+ break;
1063+ }
1064+ }
1065+})();
1066
1067=== added file 'src/app/webbrowser/webapps-extension.cpp'
1068--- src/app/webbrowser/webapps-extension.cpp 1970-01-01 00:00:00 +0000
1069+++ src/app/webbrowser/webapps-extension.cpp 2015-09-30 04:21:34 +0000
1070@@ -0,0 +1,234 @@
1071+/*
1072+ * Copyright 2015 Canonical Ltd.
1073+ *
1074+ * This file is part of webbrowser-app.
1075+ *
1076+ * webbrowser-app is free software; you can redistribute it and/or modify
1077+ * it under the terms of the GNU General Public License as published by
1078+ * the Free Software Foundation; version 3.
1079+ *
1080+ * webbrowser-app is distributed in the hope that it will be useful,
1081+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1082+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1083+ * GNU General Public License for more details.
1084+ *
1085+ * You should have received a copy of the GNU General Public License
1086+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1087+ *
1088+ * Author: Justin McPherson <justin.mcpherson@canonical.com>
1089+ *
1090+ */
1091+
1092+#include "webapps-extension.h"
1093+
1094+#include <QQueue>
1095+#include <QProcess>
1096+#include <QElapsedTimer>
1097+#include <QVariant>
1098+#include <QJsonDocument>
1099+#include <QState>
1100+#include <QFinalState>
1101+#include <QStateMachine>
1102+
1103+#include <QDebug>
1104+
1105+namespace {
1106+const char* webapps_extension_path = "/usr/share/unity-webapps/bin/webapps-extension";
1107+const char* method_key = "method";
1108+const char* available_key = "available";
1109+const char* url_key = "url";
1110+const char* launched_key = "launched";
1111+const char* url_loaded_method = "click_available";
1112+const char* launch_method = "launch_click";
1113+const char* method_return_error = "Invalid method name";
1114+}
1115+
1116+
1117+class WebappsExtensionPrivate : public QObject
1118+{
1119+ Q_OBJECT
1120+ Q_DECLARE_PUBLIC(WebappsExtension)
1121+
1122+public:
1123+ WebappsExtensionPrivate(WebappsExtension* q);
1124+ ~WebappsExtensionPrivate();
1125+
1126+ void writeMessage(const QVariantMap& message);
1127+
1128+Q_SIGNALS:
1129+ void processStarted();
1130+ void readFinished();
1131+ void writeFinished();
1132+
1133+private Q_SLOTS:
1134+ void start();
1135+ void write();
1136+ void finalize();
1137+
1138+ void readyRead();
1139+ void bytesWritten(qint64 numBytes);
1140+
1141+private:
1142+ QProcess* m_extensionProcess;
1143+ QStateMachine* m_stateMachine;
1144+ WebappsExtension* q_ptr;
1145+
1146+ QQueue<QVariantMap> writeQueue;
1147+ qint64 totalOutput;
1148+ QByteArray outputBuffer;
1149+ QByteArray inputBuffer;
1150+};
1151+
1152+WebappsExtensionPrivate::WebappsExtensionPrivate(WebappsExtension *q)
1153+ : QObject(nullptr)
1154+ , m_extensionProcess(new QProcess(this))
1155+ , m_stateMachine(new QStateMachine(this))
1156+ , q_ptr(q)
1157+{
1158+ m_extensionProcess->setProgram(webapps_extension_path);
1159+ connect(m_extensionProcess, SIGNAL(started()), SIGNAL(processStarted()));
1160+ connect(m_extensionProcess, SIGNAL(readyRead()), SLOT(readyRead()));
1161+ connect(m_extensionProcess, SIGNAL(bytesWritten(qint64)), SLOT(bytesWritten(qint64)));
1162+
1163+ QState *initialState = new QState;
1164+ QState *writingState = new QState;
1165+ QState *readingState = new QState;
1166+ QFinalState* finalizeState = new QFinalState;
1167+
1168+ initialState->addTransition(this, SIGNAL(processStarted()), writingState);
1169+ writingState->addTransition(this, SIGNAL(writeFinished()), readingState);
1170+ readingState->addTransition(this, SIGNAL(readFinished()), finalizeState);
1171+
1172+ connect(writingState, SIGNAL(entered()), SLOT(write()));
1173+
1174+ m_stateMachine->addState(initialState);
1175+ m_stateMachine->addState(writingState);
1176+ m_stateMachine->addState(readingState);
1177+ m_stateMachine->addState(finalizeState);
1178+ m_stateMachine->setInitialState(initialState);
1179+
1180+ connect(m_stateMachine, SIGNAL(started()), SLOT(start()));
1181+ connect(m_stateMachine, SIGNAL(finished()), SLOT(finalize()));
1182+}
1183+
1184+WebappsExtensionPrivate::~WebappsExtensionPrivate()
1185+{
1186+}
1187+
1188+void WebappsExtensionPrivate::writeMessage(const QVariantMap& message)
1189+{
1190+ writeQueue.enqueue(message);
1191+
1192+ if (!m_stateMachine->isRunning())
1193+ m_stateMachine->start();
1194+}
1195+
1196+void WebappsExtensionPrivate::start()
1197+{
1198+ inputBuffer.clear();
1199+ outputBuffer.clear();
1200+ totalOutput = 0;
1201+
1202+ if (m_extensionProcess->state() != QProcess::Running) {
1203+ m_extensionProcess->start();
1204+ } else {
1205+ Q_EMIT processStarted();
1206+ }
1207+}
1208+
1209+void WebappsExtensionPrivate::write()
1210+{
1211+ QVariantMap message = writeQueue.dequeue();
1212+ QJsonDocument doc = QJsonDocument::fromVariant(message);
1213+ outputBuffer = doc.toJson();
1214+ quint32 length = outputBuffer.length();
1215+ m_extensionProcess->write((char *)&length, sizeof(length));
1216+ m_extensionProcess->write(outputBuffer);
1217+}
1218+
1219+void WebappsExtensionPrivate::finalize()
1220+{
1221+ Q_Q(WebappsExtension);
1222+
1223+ QVariantMap message;
1224+ QJsonDocument doc = QJsonDocument::fromJson(inputBuffer);
1225+ message = doc.toVariant().toMap();
1226+
1227+ if (!message.contains(method_key)) {
1228+ Q_EMIT q->extensionError(QLatin1String(method_return_error));
1229+ } else {
1230+ QString method = message[method_key].toString();
1231+ if (method == QLatin1String(url_loaded_method)) {
1232+ Q_EMIT q->webappSupported(message);
1233+ } else if (method == QLatin1String(launch_method)) {
1234+ bool success = message.contains(launched_key) && message[launched_key].toBool();
1235+ QUrl url(message[url_key].toString());
1236+ Q_EMIT q->webappLaunched(success, message[url_key].toString());
1237+ }
1238+ }
1239+
1240+ if (!writeQueue.empty()) {
1241+ m_stateMachine->start();
1242+ }
1243+}
1244+
1245+void WebappsExtensionPrivate::readyRead()
1246+{
1247+ if (inputBuffer.capacity() == 0) {
1248+ quint32 length = 0;
1249+ if (m_extensionProcess->bytesAvailable() < sizeof(length)) {
1250+ return;
1251+ }
1252+ m_extensionProcess->read((char *)&length, sizeof(length));
1253+ inputBuffer.reserve(length);
1254+ }
1255+
1256+ if (m_extensionProcess->bytesAvailable() < inputBuffer.capacity()) {
1257+ return;
1258+ }
1259+
1260+ inputBuffer += m_extensionProcess->read(inputBuffer.capacity());
1261+
1262+ Q_EMIT readFinished();
1263+}
1264+
1265+void WebappsExtensionPrivate::bytesWritten(qint64 numBytes)
1266+{
1267+ totalOutput += numBytes;
1268+ if (totalOutput == outputBuffer.length() + sizeof(quint32)) {
1269+ Q_EMIT writeFinished();
1270+ }
1271+}
1272+
1273+
1274+WebappsExtension::WebappsExtension()
1275+ : QObject(nullptr)
1276+ , d_ptr(new WebappsExtensionPrivate(this))
1277+{
1278+}
1279+
1280+WebappsExtension::~WebappsExtension()
1281+{
1282+}
1283+
1284+void WebappsExtension::supportedUrl(const QUrl& url)
1285+{
1286+ Q_D(WebappsExtension);
1287+
1288+ QVariantMap message;
1289+ message.insert(method_key, url_loaded_method);
1290+ message.insert(url_key, url.toString());
1291+ d->writeMessage(message);
1292+}
1293+
1294+void WebappsExtension::launchWebApp(const QUrl& url)
1295+{
1296+ Q_D(WebappsExtension);
1297+
1298+ QVariantMap message;
1299+ message.insert(method_key, launch_method);
1300+ message.insert(url_key, url.toString());
1301+ d->writeMessage(message);
1302+}
1303+
1304+#include "webapps-extension.moc"
1305
1306=== added file 'src/app/webbrowser/webapps-extension.h'
1307--- src/app/webbrowser/webapps-extension.h 1970-01-01 00:00:00 +0000
1308+++ src/app/webbrowser/webapps-extension.h 2015-09-30 04:21:34 +0000
1309@@ -0,0 +1,52 @@
1310+/*
1311+ * Copyright 2015 Canonical Ltd.
1312+ *
1313+ * This file is part of webbrowser-app.
1314+ *
1315+ * webbrowser-app is free software; you can redistribute it and/or modify
1316+ * it under the terms of the GNU General Public License as published by
1317+ * the Free Software Foundation; version 3.
1318+ *
1319+ * webbrowser-app is distributed in the hope that it will be useful,
1320+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1321+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1322+ * GNU General Public License for more details.
1323+ *
1324+ * You should have received a copy of the GNU General Public License
1325+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1326+ *
1327+ * Author: Justin McPherson <justin.mcpherson@canonical.com>
1328+ *
1329+ */
1330+
1331+#ifndef _WEBAPPS_EXTENSION_H_
1332+#define _WEBAPPS_EXTENSION_H_
1333+
1334+#include <QObject>
1335+#include <QUrl>
1336+#include <QScopedPointer>
1337+
1338+
1339+class WebappsExtensionPrivate;
1340+class WebappsExtension : public QObject
1341+{
1342+ Q_OBJECT
1343+ Q_DECLARE_PRIVATE(WebappsExtension)
1344+
1345+public:
1346+ WebappsExtension();
1347+ ~WebappsExtension();
1348+
1349+ Q_INVOKABLE void supportedUrl(const QUrl& url);
1350+ Q_INVOKABLE void launchWebApp(const QUrl& url);
1351+
1352+Q_SIGNALS:
1353+ void webappSupported(const QVariantMap& webApplication);
1354+ void webappLaunched(bool success, const QUrl& url);
1355+ void extensionError(const QString& errorString);
1356+
1357+private:
1358+ QScopedPointer<WebappsExtensionPrivate> d_ptr;
1359+};
1360+
1361+#endif // _WEBAPPS_EXTENSION_H_
1362
1363=== modified file 'src/app/webbrowser/webbrowser-app.cpp'
1364--- src/app/webbrowser/webbrowser-app.cpp 2015-08-19 13:16:06 +0000
1365+++ src/app/webbrowser/webbrowser-app.cpp 2015-09-30 04:21:34 +0000
1366@@ -27,6 +27,7 @@
1367 #include "history-lastvisitdate-model.h"
1368 #include "history-model.h"
1369 #include "history-timeframe-model.h"
1370+#include "webapps-extension.h"
1371 #include "limit-proxy-model.h"
1372 #include "searchengine.h"
1373 #include "text-search-filter-model.h"
1374@@ -50,6 +51,14 @@
1375 {
1376 }
1377
1378+
1379+static QObject* WebappsExtension_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)
1380+{
1381+ Q_UNUSED(engine);
1382+ Q_UNUSED(scriptEngine);
1383+ return new WebappsExtension();
1384+}
1385+
1386 static QObject* FileOperations_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine)
1387 {
1388 Q_UNUSED(engine);
1389@@ -78,6 +87,7 @@
1390 qmlRegisterType<TabsModel>(uri, 0, 1, "TabsModel");
1391 qmlRegisterType<BookmarksModel>(uri, 0, 1, "BookmarksModel");
1392 qmlRegisterType<BookmarksFolderListModel>(uri, 0, 1, "BookmarksFolderListModel");
1393+ qmlRegisterSingletonType<WebappsExtension>(uri, 0, 1, "WebappsExtension", WebappsExtension_singleton_factory);
1394 qmlRegisterSingletonType<FileOperations>(uri, 0, 1, "FileOperations", FileOperations_singleton_factory);
1395 qmlRegisterType<SearchEngine>(uri, 0, 1, "SearchEngine");
1396 qmlRegisterSingletonType<CacheDeleter>(uri, 0, 1, "CacheDeleter", CacheDeleter_singleton_factory);
1397
1398=== modified file 'src/app/webcontainer/WebApp.qml'
1399--- src/app/webcontainer/WebApp.qml 2015-08-18 14:18:37 +0000
1400+++ src/app/webcontainer/WebApp.qml 2015-09-30 04:21:34 +0000
1401@@ -116,6 +116,29 @@
1402 return result
1403 }
1404
1405+ Component {
1406+ id: webappCapableInstallComponent
1407+ Rectangle {
1408+ id: dialogue
1409+ title: "Install"
1410+ text: "Are you sure that you want to save this file?"
1411+ Button {
1412+ text: "cancel"
1413+ onClicked: PopupUtils.close(dialogue)
1414+ }
1415+ Button {
1416+ text: "overwrite previous version"
1417+ color: UbuntuColors.orange
1418+ onClicked: PopupUtils.close(dialogue)
1419+ }
1420+ Button {
1421+ text: "save a copy"
1422+ color: UbuntuColors.orange
1423+ onClicked: PopupUtils.close(dialogue)
1424+ }
1425+ }
1426+ }
1427+
1428 Item {
1429 id: webviewContainer
1430 anchors.fill: parent
1431@@ -132,9 +155,14 @@
1432 height: parent.height - osk.height
1433 developerExtrasEnabled: webapp.developerExtrasEnabled
1434
1435+ webappManifestDetected: {
1436+ PopupUtils.open(dialog)
1437+ }
1438+
1439 onSamlRequestUrlPatternReceived: {
1440 addGeneratedUrlPattern(urlPattern)
1441 }
1442+
1443 webappUrlPatterns: mergeUrlPatternSets(urlPatternSettings.generatedUrlPatterns,
1444 webapp.webappUrlPatterns)
1445
1446
1447=== modified file 'tests/unittests/CMakeLists.txt'
1448--- tests/unittests/CMakeLists.txt 2015-08-19 13:16:06 +0000
1449+++ tests/unittests/CMakeLists.txt 2015-09-30 04:21:34 +0000
1450@@ -1,5 +1,5 @@
1451 add_subdirectory(sanity)
1452-add_subdirectory(qml)
1453+#add_subdirectory(qml)
1454 add_subdirectory(domain-utils)
1455 add_subdirectory(history-model)
1456 add_subdirectory(history-timeframe-model)
1457@@ -19,8 +19,8 @@
1458 add_subdirectory(cookie-store)
1459 add_subdirectory(oxide-cookie-helper)
1460 add_subdirectory(session-storage)
1461-add_subdirectory(favicon-fetcher)
1462-add_subdirectory(webapp-container-hook)
1463+#add_subdirectory(favicon-fetcher)
1464+#add_subdirectory(webapp-container-hook)
1465 add_subdirectory(intent-filter)
1466 add_subdirectory(search-engine)
1467 add_subdirectory(text-search-filter-model)

Subscribers

People subscribed via source and target branches

to status/vote changes: