[Merge] lp:~osomon/webbrowser-app/contextual-selection into lp:webbrowser-app
Didier Roche
didrocks at ubuntu.com
Thu Jun 26 13:40:58 UTC 2014
Review: Needs Fixing
See the inline comment, once that's fixed: +1
Diff comments:
> === modified file '.bzrignore'
> --- .bzrignore 2014-05-30 16:16:56 +0000
> +++ .bzrignore 2014-06-26 12:56:18 +0000
> @@ -30,8 +30,8 @@
> debian/files
> debian/tmp/
> debian/qtdeclarative5-ubuntu-ui-extras-browser-plugin/
> -debian/qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets/
> debian/qtdeclarative5-ubuntu-web-plugin/
> +debian/qtdeclarative5-ubuntu-web-plugin-assets/
> debian/webapp-container/
> debian/webapp-container-autopilot/
> debian/webbrowser-app/
>
> === modified file 'debian/control'
> --- debian/control 2014-06-16 08:34:26 +0000
> +++ debian/control 2014-06-26 12:56:18 +0000
> @@ -78,7 +78,6 @@
> ${shlibs:Depends},
> libqt5webkit5-qmlwebkitplugin,
> qtdeclarative5-qtquick2-plugin,
> - qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets (>= ${source:Version}),
> qtdeclarative5-ubuntu-ui-toolkit-plugin,
> qtdeclarative5-ubuntu-web-plugin (= ${binary:Version}),
> qtdeclarative5-window-plugin,
> @@ -89,16 +88,6 @@
> (versions 0.1 based on WebKit and 0.2 based on Oxide), in the
> Ubuntu.Components.Extras.Browser module.
>
> -Package: qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets
> -Architecture: all
> -Multi-Arch: foreign
> -Depends: ${misc:Depends},
> -Description: Ubuntu web QML plugin assets
> - A standalone QML plugin that contains the UbuntuWebView component
> - (versions 0.1 based on WebKit and 0.2 based on Oxide), in the
> - Ubuntu.Components.Extras.Browser module. This package contains the
> - PNGs used as UI elements by the plugin.
> -
> Package: qtdeclarative5-ubuntu-web-plugin
> Architecture: any
> Multi-Arch: same
> @@ -108,11 +97,22 @@
> liboxideqt-qmlplugin,
> qtdeclarative5-qtquick2-plugin,
> qtdeclarative5-ubuntu-ui-toolkit-plugin,
> + qtdeclarative5-ubuntu-web-plugin-assets (>= ${source:Version}),
> qtdeclarative5-window-plugin,
> Description: Ubuntu web QML plugin
> A standalone QML plugin that contains the WebView component,
> in the Ubuntu.Web module.
>
> +Package: qtdeclarative5-ubuntu-web-plugin-assets
> +Architecture: all
> +Multi-Arch: foreign
> +Depends: ${misc:Depends},
> +Replaces: qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets
There is no need for replaces: as you don't install any common filename with qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets from that package. You can just remove it.
> +Description: Ubuntu web QML plugin assets
> + A standalone QML plugin that contains the WebView component,
> + in the Ubuntu.Web module. This package contains the PNGs used
> + as UI elements by the plugin.
> +
> Package: webbrowser-app-autopilot
> Architecture: all
> Multi-Arch: foreign
>
> === renamed file 'debian/qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets.install' => 'debian/qtdeclarative5-ubuntu-web-plugin-assets.install'
> --- debian/qtdeclarative5-ubuntu-ui-extras-browser-plugin-assets.install 2013-07-18 14:15:53 +0000
> +++ debian/qtdeclarative5-ubuntu-web-plugin-assets.install 2014-06-26 12:56:18 +0000
> @@ -1,1 +1,1 @@
> -usr/share/qtdeclarative5-ubuntu-ui-extras-browser-plugin/
> +usr/share/qtdeclarative5-ubuntu-web-plugin/
>
> === modified file 'debian/rules'
> --- debian/rules 2014-03-04 09:32:47 +0000
> +++ debian/rules 2014-06-26 12:56:18 +0000
> @@ -11,7 +11,9 @@
> dh $@ --parallel --with translations
>
> override_dh_install:
> - ln -sf /usr/share/qtdeclarative5-ubuntu-ui-extras-browser-plugin/assets \
> + ln -sf /usr/share/qtdeclarative5-ubuntu-web-plugin/assets \
> + $(CURDIR)/debian/tmp/usr/lib/*/qt5/qml/Ubuntu/Web
> + ln -sf /usr/share/qtdeclarative5-ubuntu-web-plugin/assets \
> $(CURDIR)/debian/tmp/usr/lib/*/qt5/qml/Ubuntu/Components/Extras/Browser
> dh_install --fail-missing
>
>
> === modified file 'src/Ubuntu/Components/Extras/Browser/CMakeLists.txt'
> --- src/Ubuntu/Components/Extras/Browser/CMakeLists.txt 2014-05-29 17:03:44 +0000
> +++ src/Ubuntu/Components/Extras/Browser/CMakeLists.txt 2014-06-26 12:56:18 +0000
> @@ -13,19 +13,14 @@
> file(GLOB QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml qmldir *.js)
> install(TARGETS ${PLUGIN} DESTINATION ${WEBBROWSER_IMPORTS_DIR})
> install(FILES ${QML_FILES} DESTINATION ${WEBBROWSER_IMPORTS_DIR})
> -install(DIRECTORY assets
> - DESTINATION ${CMAKE_INSTALL_DATADIR}/qtdeclarative5-ubuntu-ui-extras-browser-plugin
> - FILES_MATCHING PATTERN *.png)
>
> if(NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
> # copy qml files and assets over to build dir to be able to import them uninstalled
> - file(GLOB ASSETS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} assets/*)
> - set(copied ${QML_FILES} ${ASSETS})
> - foreach(_file ${copied})
> + foreach(_file ${QML_FILES})
> add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}
> DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_file}
> COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${_file} ${CMAKE_CURRENT_BINARY_DIR}/${_file})
> endforeach(_file)
> - add_custom_target(copy_files_to_build_dir_legacy DEPENDS ${copied})
> + add_custom_target(copy_files_to_build_dir_legacy DEPENDS ${QML_FILES})
> add_dependencies(${PLUGIN} copy_files_to_build_dir_legacy)
> endif()
>
> === added symlink 'src/Ubuntu/Components/Extras/Browser/Selection.qml'
> === target is u'../../../Web/Selection.qml'
> === added symlink 'src/Ubuntu/Components/Extras/Browser/SelectionHandle.qml'
> === target is u'../../../Web/SelectionHandle.qml'
> === added symlink 'src/Ubuntu/Components/Extras/Browser/assets'
> === target is u'../../../Web/assets/'
> === modified file 'src/Ubuntu/Web/CMakeLists.txt'
> --- src/Ubuntu/Web/CMakeLists.txt 2014-05-29 17:03:44 +0000
> +++ src/Ubuntu/Web/CMakeLists.txt 2014-06-26 12:56:18 +0000
> @@ -13,6 +13,9 @@
> file(GLOB QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml qmldir *.js)
> install(TARGETS ${PLUGIN} DESTINATION ${UBUNTU_WEB_IMPORTS_DIR})
> install(FILES ${QML_FILES} DESTINATION ${UBUNTU_WEB_IMPORTS_DIR})
> +install(DIRECTORY assets
> + DESTINATION ${CMAKE_INSTALL_DATADIR}/qtdeclarative5-ubuntu-web-plugin
> + FILES_MATCHING PATTERN *.png)
>
> if(NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
> # copy qml files over to build dir to be able to import them uninstalled
>
> === renamed file 'src/Ubuntu/Components/Extras/Browser/Selection.qml' => 'src/Ubuntu/Web/Selection.qml'
> --- src/Ubuntu/Components/Extras/Browser/Selection.qml 2013-03-08 10:53:16 +0000
> +++ src/Ubuntu/Web/Selection.qml 2014-06-26 12:56:18 +0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright 2013 Canonical Ltd.
> + * Copyright 2013-2014 Canonical Ltd.
> *
> * This file is part of webbrowser-app.
> *
> @@ -27,16 +27,20 @@
> property real __minimumWidth: units.gu(5)
> property real __minimumHeight: units.gu(5)
>
> + readonly property bool resizing: __leftHandle.dragging || __topHandle.dragging || __rightHandle.dragging || __bottomHandle.dragging
> +
> signal resized()
> + signal dismissed()
>
> MouseArea {
> anchors.fill: parent
> // dismiss the selection when tapping anywhere except for the handles
> - onClicked: __container.visible = false
> + onClicked: __container.dismissed()
> }
>
> Item {
> id: __rect
> + objectName: "rectangle"
> }
>
> Rectangle {
> @@ -91,6 +95,7 @@
>
> SelectionHandle {
> id: __leftHandle
> + objectName: "leftHandle"
> axis: Drag.XAxis
> x: __rect.x - width / 2
> y: (__topHandle.y + __bottomHandle.y) / 2
> @@ -107,6 +112,7 @@
>
> SelectionHandle {
> id: __topHandle
> + objectName: "topHandle"
> axis: Drag.YAxis
> x: (__leftHandle.x + __rightHandle.x) / 2
> y: __rect.y - height / 2
> @@ -123,6 +129,7 @@
>
> SelectionHandle {
> id: __rightHandle
> + objectName: "rightHandle"
> axis: Drag.XAxis
> x: __rect.x + __rect.width - width / 2
> y: (__topHandle.y + __bottomHandle.y) / 2
> @@ -138,6 +145,7 @@
>
> SelectionHandle {
> id: __bottomHandle
> + objectName: "bottomHandle"
> axis: Drag.YAxis
> x: (__leftHandle.x + __rightHandle.x) / 2
> y: __rect.y + __rect.height - height / 2
>
> === renamed file 'src/Ubuntu/Components/Extras/Browser/SelectionHandle.qml' => 'src/Ubuntu/Web/SelectionHandle.qml'
> --- src/Ubuntu/Components/Extras/Browser/SelectionHandle.qml 2013-03-08 10:53:16 +0000
> +++ src/Ubuntu/Web/SelectionHandle.qml 2014-06-26 12:56:18 +0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright 2013 Canonical Ltd.
> + * Copyright 2013-2014 Canonical Ltd.
> *
> * This file is part of webbrowser-app.
> *
> @@ -23,8 +23,6 @@
> property int axis
> property real minimum
> property real maximum
> - // Known issue: when dragging outside the window, the drag is canceled,
> - // but dragging remains true. See QTBUG-29146.
> property bool dragging: __mousearea.drag.active
>
> width: units.gu(3)
>
> === modified file 'src/Ubuntu/Web/UbuntuWebView02.qml'
> --- src/Ubuntu/Web/UbuntuWebView02.qml 2014-06-11 09:31:38 +0000
> +++ src/Ubuntu/Web/UbuntuWebView02.qml 2014-06-26 12:56:18 +0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright 2013 Canonical Ltd.
> + * Copyright 2013-2014 Canonical Ltd.
> *
> * This file is part of webbrowser-app.
> *
> @@ -62,29 +62,36 @@
> msgId: "contextmenu"
> contexts: ["oxide://selection/"]
> callback: function(msg, frame) {
> - if (('img' in msg.args) || ('href' in msg.args)) {
> - if (internal.currentContextualMenu != null) {
> - PopupUtils.close(internal.currentContextualMenu)
> - }
> - contextualData.clear()
> - if ('img' in msg.args) {
> - contextualData.img = msg.args.img
> - }
> - if ('href' in msg.args) {
> - contextualData.href = msg.args.href
> - contextualData.title = msg.args.title
> - }
> - if (contextualActions != null) {
> - for (var i = 0; i < contextualActions.actions.length; ++i) {
> - if (contextualActions.actions[i].enabled) {
> - contextualRectangle.position(msg.args)
> - internal.currentContextualMenu = PopupUtils.open(contextualPopover, contextualRectangle)
> - break
> - }
> - }
> - }
> - } else if (internal.currentContextualMenu != null) {
> - PopupUtils.close(internal.currentContextualMenu)
> + internal.dismissCurrentContextualMenu()
> + internal.dismissCurrentSelection()
> + internal.fillContextualData(msg.args)
> + if (contextualActions != null) {
> + for (var i = 0; i < contextualActions.actions.length; ++i) {
> + if (contextualActions.actions[i].enabled) {
> + contextualRectangle.position(msg.args)
> + internal.currentContextualMenu = PopupUtils.open(contextualPopover, contextualRectangle)
> + break
> + }
> + }
> + }
> + }
> + },
> + Oxide.ScriptMessageHandler {
> + msgId: "selection"
> + contexts: ["oxide://selection/"]
> + callback: function(msg, frame) {
> + internal.dismissCurrentSelection()
> + internal.dismissCurrentContextualMenu()
> + if (selectionActions != null) {
> + for (var i = 0; i < selectionActions.actions.length; ++i) {
> + if (selectionActions.actions[i].enabled) {
> + var mimedata = internal.buildMimedata(msg.args)
> + var bounds = internal.computeBounds(msg.args)
> + internal.currentSelection = selection.createObject(_webview, {mimedata: mimedata, bounds: bounds})
> + internal.currentSelection.showActions()
> + break
> + }
> + }
> }
> }
> },
> @@ -92,9 +99,8 @@
> msgId: "scroll"
> contexts: ["oxide://selection/"]
> callback: function(msg, frame) {
> - if (internal.currentContextualMenu != null) {
> - PopupUtils.close(internal.currentContextualMenu)
> - }
> + internal.dismissCurrentContextualMenu()
> + internal.dismissCurrentSelection()
> }
> }
> ]
> @@ -140,10 +146,127 @@
> }
> }
>
> + property ActionList selectionActions
> + onSelectionActionsChanged: {
> + for (var i in selectionActions.actions) {
> + selectionActions.actions[i].onTriggered.connect(function () {
> + internal.dismissCurrentSelection()
> + })
> + }
> + }
> + Component {
> + id: selection
> + Selection {
> + anchors.fill: parent
> + property var mimedata: null
> + property rect bounds
> + onBoundsChanged: {
> + rect.x = bounds.x
> + rect.y = bounds.y
> + rect.width = bounds.width
> + rect.height = bounds.height
> + }
> + property Item actions: null
> + Component {
> + id: selectionPopover
> + ActionSelectionPopover {
> + objectName: "selectionActions"
> + autoClose: false
> + actions: selectionActions
> + }
> + }
> + function showActions() {
> + if (actions != null) {
> + actions.destroy()
> + }
> + actions = PopupUtils.open(selectionPopover, rect)
> + }
> + onResizingChanged: {
> + if (resizing) {
> + if (actions != null) {
> + actions.destroy()
> + }
> + }
> + }
> + onResized: {
> + var args = {x: rect.x, y: rect.y, width: rect.width, height: rect.height}
> + var msg = _webview.rootFrame.sendMessage("oxide://selection/", "adjustselection", args)
> + msg.onreply = function(response) {
> + internal.currentSelection.mimedata = internal.buildMimedata(response)
> + // Ensure that the bounds are updated
> + internal.currentSelection.bounds = Qt.rect(0, 0, 0, 0)
> + internal.currentSelection.bounds = internal.computeBounds(response)
> + internal.currentSelection.showActions()
> + }
> + msg.onerror = function(error) {
> + internal.dismissCurrentSelection()
> + }
> + }
> + onDismissed: internal.dismissCurrentSelection()
> + }
> + }
> + function copy() {
> + if (internal.currentSelection != null) {
> + Clipboard.push(internal.currentSelection.mimedata)
> + } else {
> + console.warn("No current selection")
> + }
> + }
> +
> QtObject {
> id: internal
> property int lastLoadRequestStatus: -1
> property Item currentContextualMenu: null
> + property Item currentSelection: null
> +
> + function fillContextualData(data) {
> + contextualData.clear()
> + if ('img' in data) {
> + contextualData.img = data.img
> + }
> + if ('href' in data) {
> + contextualData.href = data.href
> + contextualData.title = data.title
> + }
> + }
> +
> + function buildMimedata(data) {
> + var mimedata = Clipboard.newData()
> + if ('html' in data) {
> + mimedata.html = data.html
> + }
> + // FIXME: push the text and image data in the order
> + // they appear in the selected block.
> + if ('text' in data) {
> + mimedata.text = data.text
> + }
> + if ('images' in data) {
> + // TODO: download and cache the images locally
> + // (grab them from the webview’s cache, if possible),
> + // and forward local URLs.
> + mimedata.urls = data.images
> + }
> + return mimedata
> + }
> +
> + function computeBounds(data) {
> + return Qt.rect(data.left * data.scaleX, data.top * data.scaleY,
> + data.width * data.scaleX, data.height * data.scaleY)
> + }
> +
> + function dismissCurrentContextualMenu() {
> + if (currentContextualMenu != null) {
> + PopupUtils.close(currentContextualMenu)
> + }
> + }
> +
> + function dismissCurrentSelection() {
> + if (currentSelection != null) {
> + // For some reason a 0 delay fails to destroy the selection
> + // when it was requested upon a screen orientation change…
> + currentSelection.destroy(1)
> + }
> + }
> }
>
> readonly property bool lastLoadSucceeded: internal.lastLoadRequestStatus === Oxide.LoadEvent.TypeSucceeded
> @@ -157,9 +280,8 @@
>
> readonly property int screenOrientation: Screen.orientation
> onScreenOrientationChanged: {
> - if (internal.currentContextualMenu != null) {
> - PopupUtils.close(internal.currentContextualMenu)
> - }
> + internal.dismissCurrentContextualMenu()
> + internal.dismissCurrentSelection()
> }
>
> onFullscreenRequested: _webview.fullscreen = fullscreen
>
> === renamed directory 'src/Ubuntu/Components/Extras/Browser/assets' => 'src/Ubuntu/Web/assets'
> === modified file 'src/Ubuntu/Web/selection02.js'
> --- src/Ubuntu/Web/selection02.js 2014-05-29 16:45:21 +0000
> +++ src/Ubuntu/Web/selection02.js 2014-06-26 12:56:18 +0000
> @@ -16,6 +16,12 @@
> * along with this program. If not, see <http://www.gnu.org/licenses/>.
> */
>
> +function elementContainedInBox(element, box) {
> + var rect = element.getBoundingClientRect();
> + return ((box.left <= rect.left) && (box.right >= rect.right) &&
> + (box.top <= rect.top) && (box.bottom >= rect.bottom));
> +}
> +
> function getImgFullUri(uri) {
> if ((uri.slice(0, 7) === 'http://') ||
> (uri.slice(0, 8) === 'https://') ||
> @@ -98,15 +104,48 @@
> return data;
> }
>
> +function adjustSelection(selection) {
> + // FIXME: allow selecting two consecutive blocks, instead of
> + // interpolating to the containing block.
> + var centerX = (selection.left + selection.right) / 2;
> + var centerY = (selection.top + selection.bottom) / 2;
> + var element = document.elementFromPoint(centerX, centerY);
> + var parent = element;
> + while (elementContainedInBox(parent, selection)) {
> + parent = parent.parentNode;
> + }
> + element = parent;
> + return getSelectedData(element);
> +}
> +
> document.documentElement.addEventListener('contextmenu', function(event) {
> var element = document.elementFromPoint(event.clientX, event.clientY);
> var data = getSelectedData(element);
> var w = document.defaultView;
> data['scaleX'] = w.outerWidth / w.innerWidth * w.devicePixelRatio;
> data['scaleY'] = w.outerHeight / w.innerHeight * w.devicePixelRatio;
> - oxide.sendMessage('contextmenu', data);
> + if (('img' in data) || ('href' in data)) {
> + oxide.sendMessage('contextmenu', data);
> + } else {
> + oxide.sendMessage('selection', data);
> + }
> });
>
> document.defaultView.addEventListener('scroll', function(event) {
> oxide.sendMessage('scroll', {});
> });
> +
> +oxide.addMessageHandler("adjustselection", function (msg) {
> + var w = document.defaultView;
> + var scaleX = w.outerWidth / w.innerWidth * w.devicePixelRatio;
> + var scaleY = w.outerHeight / w.innerHeight * w.devicePixelRatio;
> + var selection = new Object;
> + selection.left = msg.args.x / scaleX;
> + selection.right = selection.left + msg.args.width / scaleX;
> + selection.top = msg.args.y / scaleY;
> + selection.bottom = selection.top + msg.args.height / scaleY;
> + var adjusted = adjustSelection(selection);
> + adjusted['scaleX'] = scaleX;
> + adjusted['scaleY'] = scaleY;
> + msg.reply(adjusted);
> +});
>
> === modified file 'src/app/WebViewImpl.qml'
> --- src/app/WebViewImpl.qml 2014-06-18 05:55:37 +0000
> +++ src/app/WebViewImpl.qml 2014-06-26 12:56:18 +0000
> @@ -20,7 +20,7 @@
> import Ubuntu.Components 0.1
> import Ubuntu.Components.Popups 0.1
> import Ubuntu.Web 0.2
> -//import "actions" as Actions
> +import "actions" as Actions
>
> WebView {
> id: webview
> @@ -42,11 +42,11 @@
> source: formFactor == "desktop" ? "FilePickerDialog.qml" : "ContentPickerDialog.qml"
> }
>
> - /*selectionActions: ActionList {
> + selectionActions: ActionList {
> Actions.Copy {
> - onTriggered: selection.copy()
> + onTriggered: copy()
> }
> - }*/
> + }
>
> onGeolocationPermissionRequested: {
> if (webview.toolbar) {
>
> === modified file 'tests/autopilot/webbrowser_app/emulators/browser.py'
> --- tests/autopilot/webbrowser_app/emulators/browser.py 2014-06-18 13:57:07 +0000
> +++ tests/autopilot/webbrowser_app/emulators/browser.py 2014-06-26 12:56:18 +0000
> @@ -21,6 +21,15 @@
> pass
>
>
> +class Selection(uitk.UbuntuUIToolkitEmulatorBase):
> +
> + def get_rectangle(self):
> + return self.select_single("QQuickItem", objectName="rectangle")
> +
> + def get_handle(self, name):
> + return self.select_single("SelectionHandle", objectName=name)
> +
> +
> class Browser(uitk.MainView):
>
> """
> @@ -106,3 +115,10 @@
>
> def get_geolocation_dialog(self):
> return self.wait_select_single("GeolocationPermissionRequest")
> +
> + def get_selection(self):
> + return self.wait_select_single(Selection)
> +
> + def get_selection_actions(self):
> + return self.wait_select_single("ActionSelectionPopover",
> + objectName="selectionActions")
>
> === modified file 'tests/autopilot/webbrowser_app/tests/http_server.py'
> --- tests/autopilot/webbrowser_app/tests/http_server.py 2014-06-18 13:57:07 +0000
> +++ tests/autopilot/webbrowser_app/tests/http_server.py 2014-06-26 12:56:18 +0000
> @@ -121,6 +121,12 @@
> html += 'navigator.geolocation.getCurrentPosition('
> html += 'function r(p) {});</script></body></html>'
> self.send_html(html)
> + elif self.path == "/selection":
> + self.send_response(200)
> + html = '<html><body style="margin: 10%">'
> + html += '<div style="position: absolute; width: 50%; height: 50%; '
> + html += 'top: 25%; left: 25%"></div></body></html>'
> + self.send_html(html)
> else:
> self.send_error(404)
>
>
> === added file 'tests/autopilot/webbrowser_app/tests/test_selection.py'
> --- tests/autopilot/webbrowser_app/tests/test_selection.py 1970-01-01 00:00:00 +0000
> +++ tests/autopilot/webbrowser_app/tests/test_selection.py 2014-06-26 12:56:18 +0000
> @@ -0,0 +1,91 @@
> +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
> +#
> +# Copyright 2014 Canonical
> +#
> +# This program is free software: you can redistribute it and/or modify it
> +# under the terms of the GNU General Public License version 3, as published
> +# by the Free Software Foundation.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +import time
> +from autopilot.platform import model
> +from autopilot.matchers import Eventually
> +from testtools.matchers import Equals, GreaterThan, LessThan
> +
> +from webbrowser_app.tests import StartOpenRemotePageTestCaseBase
> +
> +
> +class TestSelection(StartOpenRemotePageTestCaseBase):
> +
> + def setUp(self):
> + super(TestSelection, self).setUp()
> + url = self.base_url + "/selection"
> + self.go_to_url(url)
> + self.assert_page_eventually_loaded(url)
> + webview = self.main_window.get_current_webview()
> + self.pointing_device.move_to_object(webview)
> + if model() == 'Desktop':
> + self.pointing_device.click(button=3)
> + else:
> + self.pointing_device.press()
> + time.sleep(1)
> + self.pointing_device.release()
> + self.selection = self.main_window.get_selection()
> + self.rectangle = self.selection.get_rectangle()
> + self.assertThat(self.rectangle.width, LessThan(webview.width))
> + self.assertThat(self.rectangle.height, LessThan(webview.height))
> + self.actions = self.main_window.get_selection_actions()
> + self.assertThat(len(self.actions.select_many("Empty")), Equals(1))
> +
> + def assert_selection_eventually_dismissed(self):
> + self.actions.wait_until_destroyed()
> + self.selection.wait_until_destroyed()
> +
> + def test_copy_selection(self):
> + copy_action = self.actions.select_single("Empty")
> + self.pointing_device.click_object(copy_action)
> + self.assert_selection_eventually_dismissed()
> +
> + def test_cancel_selection(self):
> + webview = self.main_window.get_current_webview()
> + x = int((webview.globalRect.x + self.rectangle.globalRect.x) / 2)
> + y = int(webview.globalRect.y + webview.globalRect.height / 2)
> + self.pointing_device.move(x, y)
> + self.pointing_device.click()
> + self.assert_selection_eventually_dismissed()
> +
> + def test_resize_selection(self):
> + webview = self.main_window.get_current_webview()
> + rect = self.rectangle.globalRect
> +
> + # Grow selection to the right
> + handle = self.selection.get_handle("rightHandle")
> + x0 = handle.globalRect.x + int(handle.globalRect.width / 2)
> + y0 = handle.globalRect.y + int(handle.globalRect.height / 2)
> + x1 = int((x0 + webview.globalRect.x + webview.globalRect.width) / 2)
> + y1 = y0
> + self.pointing_device.drag(x0, y0, x1, y1)
> + self.assertThat(self.rectangle.width,
> + Eventually(GreaterThan(rect.width)))
> + self.assertThat(self.rectangle.height,
> + Eventually(GreaterThan(rect.height)))
> + self.actions.wait_until_destroyed()
> + self.actions = self.main_window.get_selection_actions()
> +
> + # Shrink selection from the bottom
> + handle = self.selection.get_handle("bottomHandle")
> + x0 = handle.globalRect.x + int(handle.globalRect.width / 2)
> + y0 = handle.globalRect.y + int(handle.globalRect.height / 2)
> + x1 = x0
> + y1 = webview.globalRect.y + int(webview.globalRect.height * 0.6)
> + self.pointing_device.drag(x0, y0, x1, y1)
> + self.assertThat(self.rectangle.globalRect, Eventually(Equals(rect)))
> + self.actions.wait_until_destroyed()
> + self.actions = self.main_window.get_selection_actions()
>
--
https://code.launchpad.net/~osomon/webbrowser-app/contextual-selection/+merge/223760
Your team Ubuntu Phablet Team is subscribed to branch lp:webbrowser-app.
More information about the Ubuntu-reviews
mailing list