From a8a04cfbbac839bc4189249dbb4c73a314dd88d0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 5 Dec 2016 12:19:49 +1300 Subject: [PATCH] Add script injection to Web 3D overlay --- interface/resources/qml/controls/WebView.qml | 13 ++++++++++- interface/src/ui/overlays/Web3DOverlay.cpp | 23 +++++++++++++++++++- interface/src/ui/overlays/Web3DOverlay.h | 2 ++ scripts/system/libraries/WebTablet.js | 6 ++++- scripts/system/marketplaces/marketplaces.js | 13 +++++++---- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index f388e5c120..ae96590e97 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -6,6 +6,7 @@ import HFWebEngineProfile 1.0 Item { property alias url: root.url + property alias scriptURL: root.userScriptUrl property alias eventBridge: eventBridgeWrapper.eventBridge property bool keyboardEnabled: true // FIXME - Keyboard HMD only: Default to false property bool keyboardRaised: false @@ -38,6 +39,8 @@ Item { storageName: "qmlWebEngine" } + property string userScriptUrl: "" + // creates a global EventBridge object. WebEngineScript { id: createGlobalEventBridge @@ -54,7 +57,15 @@ Item { worldId: WebEngineScript.MainWorld } - userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard ] + // User script. + WebEngineScript { + id: userScript + sourceUrl: root.userScriptUrl + injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. + worldId: WebEngineScript.MainWorld + } + + userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] property string newUrl: "" diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 5bdc429b75..fb8eaf5f5a 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -47,6 +47,7 @@ Web3DOverlay::Web3DOverlay() : _dpi(DPI) { Web3DOverlay::Web3DOverlay(const Web3DOverlay* Web3DOverlay) : Billboard3DOverlay(Web3DOverlay), _url(Web3DOverlay->_url), + _scriptURL(Web3DOverlay->_scriptURL), _dpi(Web3DOverlay->_dpi), _resolution(Web3DOverlay->_resolution) { @@ -112,6 +113,7 @@ void Web3DOverlay::render(RenderArgs* args) { _webSurface->load("WebView.qml"); _webSurface->resume(); _webSurface->getRootItem()->setProperty("url", _url); + _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); _webSurface->resize(QSize(_resolution.x, _resolution.y)); currentContext->makeCurrent(currentSurface); @@ -273,6 +275,14 @@ void Web3DOverlay::setProperties(const QVariantMap& properties) { } } + auto scriptURLValue = properties["scriptURL"]; + if (scriptURLValue.isValid()) { + QString newScriptURL = scriptURLValue.toString(); + if (newScriptURL != _scriptURL) { + setScriptURL(newScriptURL); + } + } + auto resolution = properties["resolution"]; if (resolution.isValid()) { bool valid; @@ -282,7 +292,6 @@ void Web3DOverlay::setProperties(const QVariantMap& properties) { } } - auto dpi = properties["dpi"]; if (dpi.isValid()) { _dpi = dpi.toFloat(); @@ -293,6 +302,9 @@ QVariant Web3DOverlay::getProperty(const QString& property) { if (property == "url") { return _url; } + if (property == "scriptURL") { + return _scriptURL; + } if (property == "dpi") { return _dpi; } @@ -308,6 +320,15 @@ void Web3DOverlay::setURL(const QString& url) { } } +void Web3DOverlay::setScriptURL(const QString& scriptURL) { + _scriptURL = scriptURL; + if (_webSurface) { + AbstractViewStateInterface::instance()->postLambdaEvent([this, scriptURL] { + _webSurface->getRootItem()->setProperty("scriptURL", scriptURL); + }); + } +} + glm::vec2 Web3DOverlay::getSize() { return _resolution / _dpi * INCHES_TO_METERS * getDimensions(); }; diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 474f6bf1da..15ef9701a5 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -39,6 +39,7 @@ public: // setters void setURL(const QString& url); + void setScriptURL(const QString& script); void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -55,6 +56,7 @@ private: QMetaObject::Connection _connection; gpu::TexturePointer _texture; QString _url; + QString _scriptURL; float _dpi; vec2 _resolution{ 640, 480 }; int _geometryId { 0 }; diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index de18d389a7..37eb5df90c 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -85,15 +85,19 @@ WebTablet = function (url, width, dpi, clientOnly) { this.state = "idle"; }; +WebTablet.prototype.setScriptURL = function (scriptURL) { + Overlays.editOverlay(this.webOverlayID, { scriptURL: scriptURL }); +}; + WebTablet.prototype.destroy = function () { Overlays.deleteOverlay(this.webOverlayID); Entities.deleteEntity(this.tabletEntityID); }; - WebTablet.prototype.pickle = function () { return JSON.stringify({ webOverlayID: this.webOverlayID, tabletEntityID: this.tabletEntityID }); }; + WebTablet.unpickle = function (string) { if (!string) { return; diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 5a78e32e6b..8938b7f7b2 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -16,6 +16,10 @@ Script.include("../libraries/WebTablet.js"); var toolIconUrl = Script.resolvePath("../assets/images/tools/"); var MARKETPLACES_URL = Script.resolvePath("../html/marketplaces.html"); +var MARKETPLACES_DIRECTORY_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesDirectory.js"); +var MARKETPLACES_HFIF_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesHiFi.js"); +var MARKETPLACES_CLARA_SCRIPT_URL = Script.resolvePath("../html/js/marketplacesClara.js"); + var marketplaceWindow = new OverlayWebWindow({ title: "Marketplace", source: "about:blank", @@ -23,17 +27,17 @@ var marketplaceWindow = new OverlayWebWindow({ height: 700, visible: false }); -marketplaceWindow.setScriptURL(Script.resolvePath("../html/js/marketplacesDirectory.js")); +marketplaceWindow.setScriptURL(MARKETPLACES_DIRECTORY_SCRIPT_URL); marketplaceWindow.webEventReceived.connect(function (data) { if (data === "INJECT_CLARA") { - marketplaceWindow.setScriptURL(Script.resolvePath("../html/js/marketplacesClara.js")); + marketplaceWindow.setScriptURL(MARKETPLACES_CLARA_SCRIPT_URL); } if (data === "INJECT_HIFI") { - marketplaceWindow.setScriptURL(Script.resolvePath("../html/js/marketplacesHiFi.js")); + marketplaceWindow.setScriptURL(MARKETPLACES_HFIF_SCRIPT_URL); } if (data === "RELOAD_DIRECTORY") { - marketplaceWindow.setScriptURL(Script.resolvePath("../html/js/marketplacesDirectory.js")); + marketplaceWindow.setScriptURL(MARKETPLACES_DIRECTORY_SCRIPT_URL); marketplaceWindow.setURL(MARKETPLACES_URL); } }); @@ -60,6 +64,7 @@ function showMarketplace(marketplaceID) { updateButtonState(true); marketplaceWebTablet = new WebTablet(MARKETPLACES_URL, null, null, true); Settings.setValue(persistenceKey, marketplaceWebTablet.pickle()); + marketplaceWebTablet.setScriptURL(MARKETPLACES_DIRECTORY_SCRIPT_URL); } else { var url = MARKETPLACES_URL; if (marketplaceID) {