diff --git a/interface/resources/qml/TabletBrowser.qml b/interface/resources/qml/TabletBrowser.qml index 0b06a6e2a1..8dbcc8f4f8 100644 --- a/interface/resources/qml/TabletBrowser.qml +++ b/interface/resources/qml/TabletBrowser.qml @@ -1,7 +1,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtWebChannel 1.0 -import QtWebEngine 1.2 +import QtWebEngine 1.5 import "controls" import "controls-uit" as HifiControls @@ -13,11 +13,11 @@ Item { id: root HifiConstants { id: hifi } HifiStyles.HifiConstants { id: hifistyles } - //width: parent.width + height: 600 property variant permissionsBar: {'securityOrigin':'none','feature':'none'} property alias url: webview.url - property WebEngineView webView: webview + property bool canGoBack: webview.canGoBack property bool canGoForward: webview.canGoForward @@ -123,5 +123,4 @@ Item { break; } } - } diff --git a/interface/resources/qml/controls-uit/BaseWebView.qml b/interface/resources/qml/controls-uit/BaseWebView.qml index 3ca57f03bf..660f52d529 100644 --- a/interface/resources/qml/controls-uit/BaseWebView.qml +++ b/interface/resources/qml/controls-uit/BaseWebView.qml @@ -9,7 +9,7 @@ // import QtQuick 2.5 -import QtWebEngine 1.2 +import QtWebEngine 1.5 WebEngineView { id: root diff --git a/interface/resources/qml/controls-uit/WebSpinner.qml b/interface/resources/qml/controls-uit/WebSpinner.qml index 6323bff1a7..e8e01c4865 100644 --- a/interface/resources/qml/controls-uit/WebSpinner.qml +++ b/interface/resources/qml/controls-uit/WebSpinner.qml @@ -9,10 +9,13 @@ // import QtQuick 2.5 +import QtWebEngine 1.5 AnimatedImage { + property WebEngineView webview: parent source: "../../icons/loader-snake-64-w.gif" - visible: parent.loading && /^(http.*|)$/i.test(parent.url.toString()) + visible: webview.loading && /^(http.*|)$/i.test(webview.url.toString()) + playing: visible z: 10000 anchors { horizontalCenter: parent.horizontalCenter diff --git a/interface/resources/qml/controls/FlickableWebViewCore.qml b/interface/resources/qml/controls/FlickableWebViewCore.qml new file mode 100644 index 0000000000..0460b5b16a --- /dev/null +++ b/interface/resources/qml/controls/FlickableWebViewCore.qml @@ -0,0 +1,170 @@ +import QtQuick 2.7 +import QtWebEngine 1.5 +import QtWebChannel 1.0 + +import QtQuick.Controls 2.2 + +import "../styles-uit" as StylesUIt + +Flickable { + id: flick + + property alias url: _webview.url + property alias canGoBack: _webview.canGoBack + property alias webViewCore: _webview + property alias webViewCoreProfile: _webview.profile + + property string userScriptUrl: "" + property string urlTag: "noDownload=false"; + + signal newViewRequestedCallback(var request) + signal loadingChangedCallback(var loadRequest) + + boundsBehavior: Flickable.StopAtBounds + + StylesUIt.HifiConstants { + id: hifi + } + + onHeightChanged: { + if (height > 0) { + //reload page since window dimentions changed, + //so web engine should recalculate page render dimentions + reloadTimer.start() + } + } + + ScrollBar.vertical: ScrollBar { + id: scrollBar + visible: flick.contentHeight > flick.height + + contentItem: Rectangle { + opacity: 0.75 + implicitWidth: hifi.dimensions.scrollbarHandleWidth + radius: height / 2 + color: hifi.colors.tableScrollHandleDark + } + } + + function onLoadingChanged(loadRequest) { + if (WebEngineView.LoadStartedStatus === loadRequest.status) { + flick.contentWidth = flick.width + flick.contentHeight = flick.height + + // Required to support clicking on "hifi://" links + var url = loadRequest.url.toString(); + if (urlHandler.canHandleUrl(url)) { + if (urlHandler.handleUrl(url)) { + _webview.stop(); + } + } + } + + if (WebEngineView.LoadFailedStatus === loadRequest.status) { + console.log(" Tablet WebEngineView failed to load url: " + loadRequest.url.toString()); + } + + if (WebEngineView.LoadSucceededStatus === loadRequest.status) { + //disable Chromium's scroll bars + _webview.runJavaScript("document.body.style.overflow = 'hidden';"); + //calculate page height + _webview.runJavaScript("document.body.scrollHeight;", function (i_actualPageHeight) { + if (i_actualPageHeight !== undefined) { + flick.contentHeight = i_actualPageHeight + } else { + flick.contentHeight = flick.height; + } + }) + flick.contentWidth = flick.width + } + } + + Timer { + id: reloadTimer + interval: 100 + repeat: false + onTriggered: { + _webview.reload() + } + } + + WebEngineView { + id: _webview + + height: parent.height + + profile: HFWebEngineProfile; + + // creates a global EventBridge object. + WebEngineScript { + id: createGlobalEventBridge + sourceCode: eventBridgeJavaScriptToInject + injectionPoint: WebEngineScript.DocumentCreation + worldId: WebEngineScript.MainWorld + } + + // detects when to raise and lower virtual keyboard + WebEngineScript { + id: raiseAndLowerKeyboard + injectionPoint: WebEngineScript.Deferred + sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" + worldId: WebEngineScript.MainWorld + } + + // User script. + WebEngineScript { + id: userScript + sourceUrl: flick.userScriptUrl + injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. + worldId: WebEngineScript.MainWorld + } + + userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] + + property string newUrl: "" + + Component.onCompleted: { + width = Qt.binding(function() { return flick.width; }); + webChannel.registerObject("eventBridge", eventBridge); + webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper); + // Ensure the JS from the web-engine makes it to our logging + _webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { + console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); + }); + _webview.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)"; + + } + + onFeaturePermissionRequested: { + grantFeaturePermission(securityOrigin, feature, true); + } + + onContentsSizeChanged: { + flick.contentHeight = Math.max(contentsSize.height, flick.height); + flick.contentWidth = flick.width + } + //disable popup + onContextMenuRequested: { + request.accepted = true; + } + + onNewViewRequested: { + newViewRequestedCallback(request) + } + + onLoadingChanged: { + flick.onLoadingChanged(loadRequest) + loadingChangedCallback(loadRequest) + } + } + + AnimatedImage { + //anchoring doesnt works here when changing content size + x: flick.width/2 - width/2 + y: flick.height/2 - height/2 + source: "../../icons/loader-snake-64-w.gif" + visible: _webview.loading && /^(http.*|)$/i.test(_webview.url.toString()) + playing: visible + z: 10000 + } +} diff --git a/interface/resources/qml/controls/TabletWebScreen.qml b/interface/resources/qml/controls/TabletWebScreen.qml index 1de31aba41..e06ff51569 100644 --- a/interface/resources/qml/controls/TabletWebScreen.qml +++ b/interface/resources/qml/controls/TabletWebScreen.qml @@ -1,14 +1,13 @@ -import QtQuick 2.5 -import QtWebEngine 1.1 -import QtWebChannel 1.0 +import QtQuick 2.7 import "../controls-uit" as HiFiControls Item { - property alias url: root.url - property alias scriptURL: root.userScriptUrl - property alias canGoBack: root.canGoBack; - property var goBack: root.goBack; - property alias urlTag: root.urlTag + id: root + property alias url: webroot.url + property alias scriptURL: webroot.userScriptUrl + property alias canGoBack: webroot.canGoBack; + property var goBack: webroot.webViewCore.goBack; + property alias urlTag: webroot.urlTag property bool keyboardEnabled: true // FIXME - Keyboard HMD only: Default to false property bool keyboardRaised: false property bool punctuationMode: false @@ -21,84 +20,20 @@ Item { } */ - property alias viewProfile: root.profile + property alias viewProfile: webroot.webViewCoreProfile - WebEngineView { - id: root - objectName: "webEngineView" - x: 0 - y: 0 + FlickableWebViewCore { + id: webroot width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFWebEngineProfile; - - property string userScriptUrl: "" - - // creates a global EventBridge object. - WebEngineScript { - id: createGlobalEventBridge - sourceCode: eventBridgeJavaScriptToInject - injectionPoint: WebEngineScript.DocumentCreation - worldId: WebEngineScript.MainWorld - } - - // detects when to raise and lower virtual keyboard - WebEngineScript { - id: raiseAndLowerKeyboard - injectionPoint: WebEngineScript.Deferred - sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" - worldId: WebEngineScript.MainWorld - } - - // User script. - WebEngineScript { - id: userScript - sourceUrl: root.userScriptUrl - injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. - worldId: WebEngineScript.MainWorld - } - - property string urlTag: "noDownload=false"; - - userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] - - property string newUrl: "" - - - Component.onCompleted: { - webChannel.registerObject("eventBridge", eventBridge); - webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper); - // Ensure the JS from the web-engine makes it to our logging - root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { - console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); - }); - - root.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)"; - } - - onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); - } - - onLoadingChanged: { + onLoadingChangedCallback: { keyboardRaised = false; punctuationMode = false; keyboard.resetShiftMode(false); - - // Required to support clicking on "hifi://" links - if (WebEngineView.LoadStartedStatus == loadRequest.status) { - var url = loadRequest.url.toString(); - url = (url.indexOf("?") >= 0) ? url + urlTag : url + "?" + urlTag; - if (urlHandler.canHandleUrl(url)) { - if (urlHandler.handleUrl(url)) { - root.stop(); - } - } - } } - onNewViewRequested:{ + onNewViewRequestedCallback: { // desktop is not defined for web-entities or tablet if (typeof desktop !== "undefined") { desktop.openBrowserWindow(request, profile); @@ -107,7 +42,6 @@ Item { } } - HiFiControls.WebSpinner { } } HiFiControls.Keyboard { @@ -120,5 +54,4 @@ Item { bottom: parent.bottom } } - } diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index 8547f67468..23143db3ba 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -1,18 +1,14 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtWebEngine 1.2 -import QtWebChannel 1.0 +import QtQuick 2.7 +import QtWebEngine 1.5 import "../controls-uit" as HiFiControls import "../styles" as HifiStyles import "../styles-uit" -import "../" -import "." Item { - id: web + id: root HifiConstants { id: hifi } - width: parent.width - height: parent.height + width: parent !== null ? parent.width : undefined + height: parent !== null ? parent.height : undefined property var parentStackItem: null property int headerHeight: 70 property string url @@ -21,8 +17,8 @@ Item { property bool keyboardRaised: false property bool punctuationMode: false property bool isDesktop: false - property alias webView: webview - property alias profile: webview.profile + property alias webView: web.webViewCore + property alias profile: web.webViewCoreProfile property bool remove: false property bool closeButtonVisible: true @@ -79,7 +75,7 @@ Item { color: hifi.colors.baseGray font.pixelSize: 12 verticalAlignment: Text.AlignLeft - text: webview.url + text: root.url anchors { top: nav.bottom horizontalCenter: parent.horizontalCenter; @@ -104,13 +100,13 @@ Item { function closeWebEngine() { if (remove) { - web.destroy(); + root.destroy(); return; } if (parentStackItem) { parentStackItem.pop(); } else { - web.visible = false; + root.visible = false; } } @@ -128,67 +124,19 @@ Item { } function loadUrl(url) { - webview.url = url - web.url = webview.url; + web.webViewCore.url = url + root.url = web.webViewCore.url; } onUrlChanged: { loadUrl(url); } - WebEngineView { - id: webview - objectName: "webEngineView" - x: 0 - y: 0 + FlickableWebViewCore { + id: web width: parent.width - height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height - web.headerHeight : parent.height - web.headerHeight + height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height - root.headerHeight : parent.height - root.headerHeight anchors.top: buttons.bottom - profile: HFWebEngineProfile; - - property string userScriptUrl: "" - - // creates a global EventBridge object. - WebEngineScript { - id: createGlobalEventBridge - sourceCode: eventBridgeJavaScriptToInject - injectionPoint: WebEngineScript.DocumentCreation - worldId: WebEngineScript.MainWorld - } - - // detects when to raise and lower virtual keyboard - WebEngineScript { - id: raiseAndLowerKeyboard - injectionPoint: WebEngineScript.Deferred - sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" - worldId: WebEngineScript.MainWorld - } - - // User script. - WebEngineScript { - id: userScript - sourceUrl: webview.userScriptUrl - injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. - worldId: WebEngineScript.MainWorld - } - - property string urlTag: "noDownload=false"; - userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] - - property string newUrl: "" - - Component.onCompleted: { - webChannel.registerObject("eventBridge", eventBridge); - webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper); - // Ensure the JS from the web-engine makes it to our logging - webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { - console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); - }); - } - - onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); - } onUrlChanged: { // Record history, skipping null and duplicate items. @@ -201,34 +149,16 @@ Item { } } - onLoadingChanged: { + onLoadingChangedCallback: { keyboardRaised = false; punctuationMode = false; keyboard.resetShiftMode(false); - // Required to support clicking on "hifi://" links - if (WebEngineView.LoadStartedStatus == loadRequest.status) { - var url = loadRequest.url.toString(); - if (urlHandler.canHandleUrl(url)) { - if (urlHandler.handleUrl(url)) { - root.stop(); - } - } - } - - if (WebEngineView.LoadFailedStatus == loadRequest.status) { - console.log(" Tablet WebEngineView failed to load url: " + loadRequest.url.toString()); - } - - if (WebEngineView.LoadSucceededStatus == loadRequest.status) { - webview.forceActiveFocus(); - } - } - - onNewViewRequested: { - request.openIn(webview); + webViewCore.forceActiveFocus(); } - HiFiControls.WebSpinner { } + onNewViewRequestedCallback: { + request.openIn(webViewCore); + } } HiFiControls.Keyboard { @@ -244,7 +174,7 @@ Item { } Component.onCompleted: { - web.isDesktop = (typeof desktop !== "undefined"); + root.isDesktop = (typeof desktop !== "undefined"); keyboardEnabled = HMD.active; } diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index 3f2ac6363b..c38c5df9cf 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -1,17 +1,19 @@ -import QtQuick 2.5 -import QtWebEngine 1.1 -import QtWebChannel 1.0 +import QtQuick 2.7 import "../controls-uit" as HiFiControls Item { - property alias url: root.url - property alias scriptURL: root.userScriptUrl - property alias canGoBack: root.canGoBack; - property var goBack: root.goBack; - property alias urlTag: root.urlTag + width: parent !== null ? parent.width : undefined + height: parent !== null ? parent.height : undefined + + property alias url: webroot.url + property alias scriptURL: webroot.userScriptUrl + property alias canGoBack: webroot.canGoBack; + property var goBack: webroot.webViewCore.goBack; + property alias urlTag: webroot.urlTag property bool keyboardEnabled: true // FIXME - Keyboard HMD only: Default to false property bool keyboardRaised: false property bool punctuationMode: false + property alias flickable: webroot.interactive // FIXME - Keyboard HMD only: Make Interface either set keyboardRaised property directly in OffscreenQmlSurface // or provide HMDinfo object to QML in RenderableWebEntityItem and do the following. @@ -21,82 +23,20 @@ Item { } */ - property alias viewProfile: root.profile + property alias viewProfile: webroot.webViewCoreProfile - WebEngineView { - id: root - objectName: "webEngineView" - x: 0 - y: 0 + FlickableWebViewCore { + id: webroot width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFWebEngineProfile; - - property string userScriptUrl: "" - - // creates a global EventBridge object. - WebEngineScript { - id: createGlobalEventBridge - sourceCode: eventBridgeJavaScriptToInject - injectionPoint: WebEngineScript.DocumentCreation - worldId: WebEngineScript.MainWorld - } - - // detects when to raise and lower virtual keyboard - WebEngineScript { - id: raiseAndLowerKeyboard - injectionPoint: WebEngineScript.Deferred - sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" - worldId: WebEngineScript.MainWorld - } - - // User script. - WebEngineScript { - id: userScript - sourceUrl: root.userScriptUrl - injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. - worldId: WebEngineScript.MainWorld - } - - property string urlTag: "noDownload=false"; - - userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] - - property string newUrl: "" - - Component.onCompleted: { - webChannel.registerObject("eventBridge", eventBridge); - webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper); - // Ensure the JS from the web-engine makes it to our logging - root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { - console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); - }); - - } - - onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); - } - - onLoadingChanged: { + onLoadingChangedCallback: { keyboardRaised = false; punctuationMode = false; keyboard.resetShiftMode(false); - - // Required to support clicking on "hifi://" links - if (WebEngineView.LoadStartedStatus == loadRequest.status) { - var url = loadRequest.url.toString(); - url = (url.indexOf("?") >= 0) ? url + urlTag : url + "?" + urlTag; - if (urlHandler.canHandleUrl(url)) { - if (urlHandler.handleUrl(url)) { - root.stop(); - } - } - } } - onNewViewRequested:{ + onNewViewRequestedCallback: { // desktop is not defined for web-entities or tablet if (typeof desktop !== "undefined") { desktop.openBrowserWindow(request, profile); @@ -104,8 +44,6 @@ Item { tabletRoot.openBrowserWindow(request, profile); } } - - HiFiControls.WebSpinner { } } HiFiControls.Keyboard { @@ -118,5 +56,4 @@ Item { bottom: parent.bottom } } - }