~phablet-team/webbrowser-app/trunk

« back to all changes in this revision

Viewing changes to src/app/webcontainer/WebViewImplOxide.qml

  • Committer: CI bot
  • Author(s): Alexandre Abreu
  • Date: 2014-04-09 13:34:35 UTC
  • mfrom: (484.1.3 latest)
  • Revision ID: ps-jenkins@lists.canonical.com-20140409133435-hy3ur1zw4a915yg5
Add support for Oxide's onNavigationRequested in the container Fixes: 1302769, 1304380

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2014 Canonical Ltd.
 
3
 *
 
4
 * This file is part of webbrowser-app.
 
5
 *
 
6
 * webbrowser-app is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; version 3.
 
9
 *
 
10
 * webbrowser-app is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
import QtQuick 2.0
 
20
import QtQuick.Window 2.0
 
21
import com.canonical.Oxide 1.0
 
22
import Ubuntu.Components 0.1
 
23
import Ubuntu.Components.Extras.Browser 0.2
 
24
import Ubuntu.UnityWebApps 0.1 as UnityWebApps
 
25
import Ubuntu.Components.Popups 0.1
 
26
import "../actions" as Actions
 
27
import ".."
 
28
 
 
29
WebViewImpl {
 
30
    id: webview
 
31
 
 
32
    property bool developerExtrasEnabled: false
 
33
    property var toolbar: null
 
34
    property string webappName: ""
 
35
    property var webappUrlPatterns: null
 
36
 
 
37
    currentWebview: webview
 
38
 
 
39
    contextualActions: ActionList {
 
40
        Actions.CopyLink {
 
41
            enabled: webview.contextualData.href.toString()
 
42
            onTriggered: Clipboard.push([webview.contextualData.href])
 
43
        }
 
44
        Actions.CopyImage {
 
45
            enabled: webview.contextualData.img.toString()
 
46
            onTriggered: Clipboard.push([webview.contextualData.img])
 
47
        }
 
48
    }
 
49
 
 
50
    function isRunningAsANamedWebapp() {
 
51
        return webview.webappName && typeof(webview.webappName) === 'string' && webview.webappName.length != 0
 
52
    }
 
53
 
 
54
    function haveValidUrlPatterns() {
 
55
        return webappUrlPatterns && webappUrlPatterns.length !== 0
 
56
    }
 
57
 
 
58
    function shouldAllowNavigationTo(url) {
 
59
        // The list of url patterns defined by the webapp takes precedence over command line
 
60
        if (isRunningAsANamedWebapp()) {
 
61
            if (unityWebapps.model.exists(unityWebapps.name) &&
 
62
                unityWebapps.model.doesUrlMatchesWebapp(unityWebapps.name, url)) {
 
63
                return true;
 
64
            }
 
65
        }
 
66
 
 
67
        // We still take the possible additional patterns specified in the command line
 
68
        // (the in the case of finer grained ones specifically for the container and not
 
69
        // as an 'install source' for the webapp).
 
70
        if (webappUrlPatterns && webappUrlPatterns.length !== 0) {
 
71
            for (var i = 0; i < webappUrlPatterns.length; ++i) {
 
72
                var pattern = webappUrlPatterns[i]
 
73
                if (url.match(pattern)) {
 
74
                    return true;
 
75
                }
 
76
            }
 
77
        }
 
78
 
 
79
        return false;
 
80
    }
 
81
 
 
82
    function navigationRequestedDelegate(request) {
 
83
        // Pass-through if we are not running as a named webapp (--webapp='Gmail')
 
84
        // or if we dont have a list of url patterns specified to filter the
 
85
        // browsing actions
 
86
        if ( ! webview.haveValidUrlPatterns() && ! webview.isRunningAsANamedWebapp()) {
 
87
            request.action = NavigationRequest.ActionAccept
 
88
            return
 
89
        }
 
90
 
 
91
        var url = request.url.toString()
 
92
 
 
93
        // Covers some edge cases corresponding to current Oxide potential issues (to be
 
94
        // confirmed) that for e.g GooglePlus when a window.open() happens (or equivalent)
 
95
        // the url that we are given (for the corresponding window.open() is 'about:blank')
 
96
        if (url == 'about:blank') {
 
97
            console.log('Ignoring the request to navigate to "about:blank"')
 
98
            request.action = NavigationRequest.ActionReject
 
99
            return;
 
100
        }
 
101
 
 
102
        request.action = NavigationRequest.ActionReject
 
103
        if (webview.shouldAllowNavigationTo(url))
 
104
            request.action = NavigationRequest.ActionAccept
 
105
 
 
106
        if ( ! webview.isRunningAsANamedWebapp() && request.disposition === NavigationRequest.DispositionNewPopup) {
 
107
            console.debug('Opening: popup window ' + url + ' in the browser window.')
 
108
            Qt.openUrlExternally(url);
 
109
            return;
 
110
        }
 
111
 
 
112
        if (request.action === NavigationRequest.ActionReject) {
 
113
            console.debug('Opening: ' + url + ' in the browser window.')
 
114
            Qt.openUrlExternally(url)
 
115
        }
 
116
    }
 
117
 
 
118
    function createPopupWindow(request) {
 
119
        popupWebViewFactory.createObject(webview, { request: request, width: 500, height: 800 });
 
120
    }
 
121
 
 
122
    Component {
 
123
        id: popupWebViewFactory
 
124
        Window {
 
125
            id: popup
 
126
            property alias request: popupBrowser.request
 
127
            UbuntuWebView {
 
128
                id: popupBrowser
 
129
                anchors.fill: parent
 
130
 
 
131
                function navigationRequestedDelegate(request) {
 
132
                    var url = request.url.toString()
 
133
 
 
134
                    // If we are to browse in the popup to a place where we are not allows
 
135
                    if (request.disposition !== NavigationRequest.DispositionNewPopup &&
 
136
                            ! webview.shouldAllowNavigationTo(url)) {
 
137
                        Qt.openUrlExternally(url);
 
138
                        popup.close()
 
139
                        return;
 
140
                    }
 
141
 
 
142
                    // Fallback to regulat checks (there is a bit of overlap)
 
143
                    webview.navigationRequestedDelegate(request)
 
144
                }
 
145
 
 
146
                onNewTabRequested: {
 
147
                    webview.createPopupWindow(request)
 
148
                }
 
149
            }
 
150
            Component.onCompleted: popup.show()
 
151
        }
 
152
    }
 
153
 
 
154
    onNewTabRequested: {
 
155
        createPopupWindow(request)
 
156
    }
 
157
 
 
158
    preferences.localStorageEnabled: true
 
159
 
 
160
    // Small shim needed when running as a webapp to wire-up connections
 
161
    // with the webview (message received, etc…).
 
162
    // This is being called (and expected) internally by the webapps
 
163
    // component as a way to bind to a webview lookalike without
 
164
    // reaching out directly to its internals (see it as an interface).
 
165
    function getUnityWebappsProxies() {
 
166
        var eventHandlers = {
 
167
            onAppRaised: function () {
 
168
                if (webbrowserWindow) {
 
169
                    try {
 
170
                        webbrowserWindow.raise();
 
171
                    } catch (e) {
 
172
                        console.debug('Error while raising: ' + e);
 
173
                    }
 
174
                }
 
175
            }
 
176
        };
 
177
        return UnityWebAppsUtils.makeProxiesForWebViewBindee(webview, eventHandlers)
 
178
    }
 
179
}