2
* Copyright 2013-2014 Canonical Ltd.
4
* This file is part of webbrowser-app.
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.
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.
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/>.
21
import QtWebKit.experimental 1.0
22
import Ubuntu.Components 1.1
23
import Ubuntu.Components.Extras.Browser 0.1
24
import Ubuntu.Components.Popups 1.0
28
\inqmlmodule Ubuntu.Components.Extras.Browser 0.1
30
\brief Custom Ubuntu WebView extending QtWebKit’s WebView
32
This version of UbuntuWebView is deprecated and shouldn’t be used in new
33
code. Use version 0.2 or higher instead.
38
signal newTabRequested(url url)
41
property real devicePixelRatio: QtWebKitDPR
42
onDevicePixelRatioChanged: {
43
// Do not make this patch to QtWebKit a hard requirement.
44
if (_webview.experimental.hasOwnProperty('devicePixelRatio')) {
45
_webview.experimental.devicePixelRatio = devicePixelRatio
50
interactive: !selection.visible
51
maximumFlickVelocity: height * 5
54
* Client overridable function called before the default treatment of a
55
* valid navigation request. This function can stop the navigation request
56
* if it sets the 'action' field of the request to IgnoreRequest.
59
function navigationRequestedDelegate(request) { }
66
* This function can be overridden by client applications that embed an
67
* UbuntuWebView to provide a static overridden UA string.
68
* If not overridden, the default UA string and the default override
69
* mechanism will be used.
71
function getUAString() {
72
// Note that this function used to accept a 'url' parameter to allow
73
// embedders to implement a custom override mechanism. It was removed
74
// after observing that no application was using it, and to simplify
75
// the API. Embedders willing to provide a custom override mechanism
76
// can always override (at their own risk) the onNavigationRequested
80
experimental.userAgent: (_webview.getUAString() === undefined) ? userAgent.defaultUA : _webview.getUAString()
81
onNavigationRequested: {
82
request.action = WebView.AcceptRequest;
84
navigationRequestedDelegate (request);
85
if (request.action === WebView.IgnoreRequest)
88
var staticUA = _webview.getUAString()
89
if (staticUA === undefined) {
90
_webview.experimental.userAgent = userAgent.getUAString(request.url)
92
_webview.experimental.userAgent = staticUA
96
experimental.preferences.navigatorQtObjectEnabled: true
97
experimental.userScripts: [Qt.resolvedUrl("hyperlinks.js"),
98
Qt.resolvedUrl("selection01.js")]
99
experimental.onMessageReceived: {
102
data = JSON.parse(message.data)
104
console.debug('DEBUG:', message.data)
107
if ('event' in data) {
108
if (data.event === 'longpress') {
109
if (('img' in data) || ('href' in data)) {
110
contextualData.clear()
112
contextualData.img = data.img
114
if ('href' in data) {
115
contextualData.href = data.href
116
contextualData.title = data.title
118
if (contextualActions != null) {
119
for (var i = 0; i < contextualActions.actions.length; ++i) {
120
if (contextualActions.actions[i].enabled) {
121
contextualRectangle.position(data)
122
PopupUtils.open(contextualPopover, contextualRectangle)
129
if ((data.event === 'longpress') || (data.event === 'selectionadjusted')) {
130
selection.clearData()
131
selection.createData()
132
if ('html' in data) {
133
selection.mimedata.html = data.html
135
// FIXME: push the text and image data in the order
136
// they appear in the selected block.
137
if ('text' in data) {
138
selection.mimedata.text = data.text
140
if ('images' in data) {
141
// TODO: download and cache the images locally
142
// (grab them from the webview’s cache, if possible),
143
// and forward local URLs.
144
selection.mimedata.urls = data.images
146
selection.show(data.left, data.top, data.width, data.height)
147
} else if (data.event === 'newtab') {
148
newTabRequested(data.url)
153
experimental.itemSelector: ItemSelector01 {}
155
property alias selection: selection
156
property ActionList selectionActions
163
property Item __popover: null
164
property var mimedata: null
168
ActionSelectionPopover {
169
grabDismissAreaEvents: false
170
actions: selectionActions
174
function createData() {
175
if (mimedata === null) {
176
mimedata = Clipboard.newData()
180
function clearData() {
181
if (mimedata !== null) {
187
function actionTriggered() {
188
selection.visible = false
191
function __showPopover() {
192
__popover = PopupUtils.open(selectionPopover, selection.rect)
193
var actions = __popover.actions.actions
194
for (var i in actions) {
195
actions[i].onTriggered.connect(actionTriggered)
199
function show(x, y, width, height) {
200
var scale = _webview.experimental.test.contentsScale * _webview.experimental.test.devicePixelRatio
201
rect.x = x * scale + _webview.contentX
202
rect.y = y * scale + _webview.contentY
203
rect.width = width * scale
204
rect.height = height * scale
210
if (!visible && (__popover != null)) {
211
PopupUtils.close(__popover)
217
var message = new Object
218
message.query = 'adjustselection'
219
var rect = selection.rect
220
var scale = _webview.experimental.test.contentsScale * _webview.experimental.test.devicePixelRatio
221
message.left = (rect.x - _webview.contentX) / scale
222
message.right = (rect.x + rect.width - _webview.contentX) / scale
223
message.top = (rect.y - _webview.contentY) / scale
224
message.bottom = (rect.y + rect.height - _webview.contentY) / scale
225
_webview.experimental.postMessage(JSON.stringify(message))
229
Clipboard.push(mimedata)
235
id: contextualRectangle
239
function position(data) {
240
var scale = _webview.experimental.test.contentsScale * _webview.experimental.test.devicePixelRatio
241
x = data.left * scale
243
width = data.width * scale
244
height = data.height * scale
247
property QtObject contextualData: QtObject {
249
property string title
259
property ActionList contextualActions
261
id: contextualPopover
262
ActionSelectionPopover {
263
actions: contextualActions
268
parent: _webview.parent
269
flickableItem: _webview
270
align: Qt.AlignTrailing
274
parent: _webview.parent
275
flickableItem: _webview
276
align: Qt.AlignBottom