mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-14 11:46:34 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
fe3879db4d
108 changed files with 504 additions and 150 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
11
interface/resources/qml/hifi/tablet/DynamicWebview.qml
Normal file
11
interface/resources/qml/hifi/tablet/DynamicWebview.qml
Normal file
|
@ -0,0 +1,11 @@
|
|||
import QtQuick 2.0
|
||||
import "../../controls" as Controls
|
||||
|
||||
Controls.WebView {
|
||||
id: root
|
||||
function fromScript(message) {
|
||||
root.url = message.url;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +139,7 @@
|
|||
#include <SoundCacheScriptingInterface.h>
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
#include <ui/ToolbarScriptingInterface.h>
|
||||
#include <ui/types/ContextAwareProfile.h>
|
||||
#include <Tooltip.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <UserActivityLogger.h>
|
||||
|
@ -3285,6 +3286,9 @@ void Application::initializeUi() {
|
|||
}
|
||||
return result.toPoint();
|
||||
});
|
||||
|
||||
// BUGZ-1365 - the root context should explicitly default to being unable to load local HTML content
|
||||
ContextAwareProfile::restrictContext(offscreenUi->getSurfaceContext(), true);
|
||||
offscreenUi->resume();
|
||||
#endif
|
||||
connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){
|
||||
|
@ -7457,7 +7461,7 @@ void Application::addingEntityWithCertificate(const QString& certificateID, cons
|
|||
ledger->updateLocation(certificateID, placeName);
|
||||
}
|
||||
|
||||
void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) {
|
||||
void Application::registerScriptEngineWithApplicationServices(const ScriptEnginePointer& scriptEngine) {
|
||||
|
||||
scriptEngine->setEmitScriptUpdatesFunction([this]() {
|
||||
SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer);
|
||||
|
@ -7496,9 +7500,19 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue,
|
||||
RayToOverlayIntersectionResultFromScriptValue);
|
||||
|
||||
bool clientScript = scriptEngine->isClientScript();
|
||||
|
||||
#if !defined(DISABLE_QML)
|
||||
scriptEngine->registerGlobalObject("OffscreenFlags", getOffscreenUI()->getFlags());
|
||||
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
|
||||
if (clientScript) {
|
||||
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
|
||||
} else {
|
||||
auto desktopScriptingInterface = new DesktopScriptingInterface(nullptr, true);
|
||||
scriptEngine->registerGlobalObject("Desktop", desktopScriptingInterface);
|
||||
if (QThread::currentThread() != thread()) {
|
||||
desktopScriptingInterface->moveToThread(thread());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<ToolbarProxy>, wrapperFromScriptValue<ToolbarProxy>);
|
||||
|
@ -7523,7 +7537,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
||||
LocationScriptingInterface::locationSetter);
|
||||
|
||||
bool clientScript = scriptEngine->isClientScript();
|
||||
scriptEngine->registerFunction("OverlayWindow", clientScript ? QmlWindowClass::constructor : QmlWindowClass::restricted_constructor);
|
||||
#if !defined(Q_OS_ANDROID) && !defined(DISABLE_QML)
|
||||
scriptEngine->registerFunction("OverlayWebWindow", clientScript ? QmlWebWindowClass::constructor : QmlWebWindowClass::restricted_constructor);
|
||||
|
|
|
@ -252,7 +252,7 @@ public:
|
|||
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
||||
|
||||
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
||||
virtual void registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) override;
|
||||
virtual void registerScriptEngineWithApplicationServices(const ScriptEnginePointer& scriptEngine) override;
|
||||
|
||||
virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const override { copyDisplayViewFrustum(viewOut); }
|
||||
virtual QThread* getMainThread() override { return thread(); }
|
||||
|
|
|
@ -52,6 +52,9 @@ static const QVariantMap DOCK_AREA {
|
|||
{ "RIGHT", DockArea::RIGHT }
|
||||
};
|
||||
|
||||
DesktopScriptingInterface::DesktopScriptingInterface(QObject* parent, bool restricted)
|
||||
: QObject(parent), _restricted(restricted) { }
|
||||
|
||||
int DesktopScriptingInterface::getWidth() {
|
||||
QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize();
|
||||
return size.width();
|
||||
|
@ -128,7 +131,7 @@ InteractiveWindowPointer DesktopScriptingInterface::createWindow(const QString&
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return new InteractiveWindow(sourceUrl, properties);
|
||||
return new InteractiveWindow(sourceUrl, properties, _restricted);
|
||||
}
|
||||
|
||||
InteractiveWindowPointer DesktopScriptingInterface::createWindowOnThread(const QString& sourceUrl, const QVariantMap& properties, QThread* targetThread) {
|
||||
|
@ -139,7 +142,7 @@ InteractiveWindowPointer DesktopScriptingInterface::createWindowOnThread(const Q
|
|||
if (!urlValidator(sourceUrl)) {
|
||||
return nullptr;
|
||||
}
|
||||
InteractiveWindowPointer window = new InteractiveWindow(sourceUrl, properties);
|
||||
InteractiveWindowPointer window = new InteractiveWindow(sourceUrl, properties, _restricted);
|
||||
window->moveToThread(targetThread);
|
||||
return window;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ class DesktopScriptingInterface : public QObject, public Dependency {
|
|||
Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
|
||||
|
||||
public:
|
||||
DesktopScriptingInterface(QObject* parent= nullptr, bool restricted = false);
|
||||
|
||||
/**jsdoc
|
||||
* Sets the opacity of the HUD surface.
|
||||
* @function Desktop.setHUDAlpha
|
||||
|
@ -106,6 +108,7 @@ private:
|
|||
static QVariantMap getDockArea();
|
||||
|
||||
Q_INVOKABLE static QVariantMap getPresentationMode();
|
||||
const bool _restricted;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <QtQuick/QQuickWindow>
|
||||
#include <QQuickView>
|
||||
|
||||
#include <ui/types/ContextAwareProfile.h>
|
||||
#include <ui/types/HFWebEngineProfile.h>
|
||||
#include <ui/types/FileTypeProfile.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <DockWidget.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
@ -134,7 +137,7 @@ void InteractiveWindow::emitMainWindowResizeEvent() {
|
|||
* Set at window creation. Possible flag values are provided as {@link Desktop|Desktop.ALWAYS_ON_TOP} and {@link Desktop|Desktop.CLOSE_BUTTON_HIDES}.
|
||||
* Additional flag values can be found on Qt's website at https://doc.qt.io/qt-5/qt.html#WindowType-enum.
|
||||
*/
|
||||
InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties) {
|
||||
InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties, bool restricted) {
|
||||
InteractiveWindowPresentationMode presentationMode = InteractiveWindowPresentationMode::Native;
|
||||
|
||||
if (properties.contains(PRESENTATION_MODE_PROPERTY)) {
|
||||
|
@ -228,9 +231,16 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
|||
_dockWidget->setObjectName("DockedWidget");
|
||||
mainWindow->addDockWidget(dockArea, _dockWidget.get());
|
||||
} else {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
// Build the event bridge and wrapper on the main thread
|
||||
offscreenUi->loadInNewContext(CONTENT_WINDOW_QML, [&](QQmlContext* context, QObject* object) {
|
||||
auto contextInitLambda = [&](QQmlContext* context) {
|
||||
// If the restricted flag is on, the web content will not be able to access local files
|
||||
ContextAwareProfile::restrictContext(context, restricted);
|
||||
#if !defined(Q_OS_ANDROID)
|
||||
FileTypeProfile::registerWithContext(context);
|
||||
HFWebEngineProfile::registerWithContext(context);
|
||||
#endif
|
||||
};
|
||||
|
||||
auto objectInitLambda = [&](QQmlContext* context, QObject* object) {
|
||||
_qmlWindowProxy = std::shared_ptr<QmlWindowProxy>(new QmlWindowProxy(object, nullptr), qmlWindowProxyDeleter);
|
||||
context->setContextProperty(EVENT_BRIDGE_PROPERTY, _interactiveWindowProxy.get());
|
||||
if (properties.contains(ADDITIONAL_FLAGS_PROPERTY)) {
|
||||
|
@ -286,7 +296,11 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
|||
}
|
||||
object->setObjectName("InteractiveWindow");
|
||||
object->setProperty(SOURCE_PROPERTY, sourceURL);
|
||||
});
|
||||
};
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
||||
// Build the event bridge and wrapper on the main thread
|
||||
offscreenUi->loadInNewContext(CONTENT_WINDOW_QML, objectInitLambda, contextInitLambda);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ class InteractiveWindow : public QObject {
|
|||
Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
|
||||
|
||||
public:
|
||||
InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties);
|
||||
InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties, bool restricted);
|
||||
~InteractiveWindow();
|
||||
|
||||
private:
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
[request setValue:@USER_AGENT_STRING forHTTPHeaderField:@"User-Agent"];
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||
|
||||
// We're using an ephermeral session here to ensure the tags api response is never cached.
|
||||
NSURLSession* session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.ephemeralSessionConfiguration];
|
||||
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
|
||||
NSURLSessionDataTask* dataTask = [NSURLSession.sharedSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
NSLog(@"Latest Build Request error: %@", error);
|
||||
NSLog(@"Latest Build Request Data: %@", data);
|
||||
NSHTTPURLResponse* ne = (NSHTTPURLResponse *)response;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
class AbstractScriptingServicesInterface {
|
||||
public:
|
||||
/// Registers application specific services with a script engine.
|
||||
virtual void registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) = 0;
|
||||
virtual void registerScriptEngineWithApplicationServices(const ScriptEnginePointer& scriptEngine) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -351,8 +351,10 @@ public:
|
|||
Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler);
|
||||
|
||||
/**jsdoc
|
||||
* Starts running another script in Interface.
|
||||
* <table><tr><th>Available in:</th><td>Interface Scripts</td><td>Avatar Scripts</td></tr></table>
|
||||
* Starts running another script in Interface, if it isn't already running. The script is not automatically loaded next
|
||||
* time Interface starts.
|
||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
||||
* <p>See also, {@link ScriptDiscoveryService.loadScript}.</p>
|
||||
* @function Script.load
|
||||
* @param {string} filename - The URL of the script to load. This can be relative to the current script's URL.
|
||||
* @example <caption>Load a script from another script.</caption>
|
||||
|
@ -754,8 +756,8 @@ signals:
|
|||
void cleanupMenuItem(const QString& menuItemString);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a script prints a message to the program log via {@link Script.print}, {@link print},
|
||||
* {@link console.log}, {@link console.info}, {@link console.warn}, {@link console.error}, or {@link console.debug}.
|
||||
* Triggered when the script prints a message to the program log via {@link print}, {@link Script.print},
|
||||
* {@link console.log}, or {@link console.debug}.
|
||||
* @function Script.printedMessage
|
||||
* @param {string} message - The message.
|
||||
* @param {string} scriptName - The name of the script that generated the message.
|
||||
|
@ -764,7 +766,7 @@ signals:
|
|||
void printedMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a script generates an error or {@link console.error} is called.
|
||||
* Triggered when the script generates an error or {@link console.error} is called.
|
||||
* @function Script.errorMessage
|
||||
* @param {string} message - The error message.
|
||||
* @param {string} scriptName - The name of the script that generated the error message.
|
||||
|
@ -773,7 +775,7 @@ signals:
|
|||
void errorMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a script generates a warning or {@link console.warn} is called.
|
||||
* Triggered when the script generates a warning or {@link console.warn} is called.
|
||||
* @function Script.warningMessage
|
||||
* @param {string} message - The warning message.
|
||||
* @param {string} scriptName - The name of the script that generated the warning message.
|
||||
|
@ -782,7 +784,7 @@ signals:
|
|||
void warningMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a script generates an information message or {@link console.info} is called.
|
||||
* Triggered when the script generates an information message or {@link console.info} is called.
|
||||
* @function Script.infoMessage
|
||||
* @param {string} message - The information message.
|
||||
* @param {string} scriptName - The name of the script that generated the information message.
|
||||
|
@ -845,8 +847,9 @@ signals:
|
|||
* @param {Uuid} entityID - The ID of the entity that the script is running in.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
|
||||
* var entityScript = (function () {
|
||||
* var entityScript = function () {
|
||||
* this.entityID = Uuid.NULL;
|
||||
* };
|
||||
*
|
||||
* Script.entityScriptPreloadFinished.connect(function (entityID) {
|
||||
* this.entityID = entityID;
|
||||
|
|
|
@ -209,6 +209,18 @@ void ScriptEngines::shutdownScripting() {
|
|||
qCDebug(scriptengine) << "DONE Stopping all scripts....";
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Information on a public script, i.e., a script that's included in the Interface installation.
|
||||
* @typedef {object} ScriptDiscoveryService.PublicScript
|
||||
* @property {string} name - The script's file name.
|
||||
* @property {string} type - <code>"script"</code> or <code>"folder"</code>.
|
||||
* <p class="important">Deprecated: This property is deprecated and will be removed. It currently always has the value,
|
||||
* <code>"script"</code>.</p>
|
||||
* @property {ScriptDiscoveryService.PublicScript[]} [children] - Only present if <code>type == "folder"</code>.
|
||||
* <p class="important">Deprecated: This property is deprecated and will be removed. It currently is never present.
|
||||
* @property {string} [url] - The full URL of the script — including the <code>"file:///"</code> scheme at the start.
|
||||
* <p>Only present if <code>type == "script"</code>.</p>
|
||||
*/
|
||||
QVariantList getPublicChildNodes(TreeNodeFolder* parent) {
|
||||
QVariantList result;
|
||||
QList<TreeNodeBase*> treeNodes = getScriptsModel().getFolderNodes(parent);
|
||||
|
@ -240,6 +252,13 @@ QVariantList ScriptEngines::getPublic() {
|
|||
return getPublicChildNodes(NULL);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Information on a local script.
|
||||
* @typedef {object} ScriptDiscoveryService.LocalScript
|
||||
* @property {string} name - The script's file name.
|
||||
* @property {string} path - The script's path.
|
||||
* @deprecated This type is deprecated and will be removed.
|
||||
*/
|
||||
QVariantList ScriptEngines::getLocal() {
|
||||
QVariantList result;
|
||||
QList<TreeNodeBase*> treeNodes = getScriptsModel().getFolderNodes(NULL);
|
||||
|
@ -260,6 +279,15 @@ QVariantList ScriptEngines::getLocal() {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Information on a running script.
|
||||
* @typedef {object} ScriptDiscoveryService.RunningScript
|
||||
* @property {boolean} local - <code>true</code> if the script is a local file (i.e., the scheme is "file"), <code>false</code>
|
||||
* if it isn't (e.g., the scheme is "http").
|
||||
* @property {string} name - The script's file name.
|
||||
* @property {string} path - The script's path and file name — excluding the scheme if a local file.
|
||||
* @property {string} url - The full URL of the script — including the scheme if a local file.
|
||||
*/
|
||||
QVariantList ScriptEngines::getRunning() {
|
||||
QVariantList result;
|
||||
auto runningScripts = getRunningScripts();
|
||||
|
|
|
@ -28,18 +28,26 @@
|
|||
class ScriptEngine;
|
||||
|
||||
/**jsdoc
|
||||
* The <code>ScriptDiscoveryService</code> API provides facilities to work with Interface scripts.
|
||||
*
|
||||
* @namespace ScriptDiscoveryService
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-client-entity
|
||||
*
|
||||
* @property {string} debugScriptUrl
|
||||
* @property {string} defaultScriptsPath
|
||||
* @property {ScriptsModel} scriptsModel
|
||||
* @property {ScriptsModelFilter} scriptsModelFilter
|
||||
* @property {string} debugScriptUrl="" - The path and name of a script to debug using the "API Debugger" developer tool
|
||||
* (currentAPI.js). If set, the API Debugger dialog displays the objects and values exposed by the script using
|
||||
* {@link Script.registerValue} and similar.
|
||||
* @property {string} defaultScriptsPath - The path where the default scripts are located in the Interface installation.
|
||||
* <em>Read-only.</em>
|
||||
* @property {ScriptsModel} scriptsModel - Information on the scripts that are in the default scripts directory of the
|
||||
* Interface installation.
|
||||
* <em>Read-only.</em>
|
||||
* @property {ScriptsModelFilter} scriptsModelFilter - Sorted and filtered information on the scripts that are in the default
|
||||
* scripts directory of the Interface installation.
|
||||
* <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
class NativeScriptInitializers : public ScriptInitializerMixin {
|
||||
public:
|
||||
bool registerNativeScriptInitializer(NativeScriptInitializer initializer) override;
|
||||
|
@ -77,61 +85,92 @@ public:
|
|||
QString getDefaultScriptsLocation() const;
|
||||
|
||||
/**jsdoc
|
||||
* Starts running an Interface script, if it isn't already running. The script is automatically loaded next time Interface
|
||||
* starts.
|
||||
* <p>This is a synonym for calling {@link ScriptDiscoveryService.loadScript|loadScript} with just the script URL.</p>
|
||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
||||
* <p>See also, {@link Script.load}.</p>
|
||||
* @function ScriptDiscoveryService.loadOneScript
|
||||
* @param {string} filename
|
||||
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
||||
* optional.
|
||||
*/
|
||||
Q_INVOKABLE void loadOneScript(const QString& scriptFilename);
|
||||
|
||||
/**jsdoc
|
||||
* Starts running an Interface script, if it isn't already running.
|
||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
||||
* <p>See also, {@link Script.load}.</p>
|
||||
* @function ScriptDiscoveryService.loadScript
|
||||
* @param {string} [filename=""]
|
||||
* @param {boolean} [isUserLoaded=true]
|
||||
* @param {boolean} [loadScriptFromEditor=false]
|
||||
* @param {boolean} [activateMainWindow=false]
|
||||
* @param {boolean} [reload=false]
|
||||
* @param {boolean} [quitWhenFinished=false]
|
||||
* @returns {boolean}
|
||||
* @param {string} [url=""] - The path and name of the script. If a local file, including the <code>"file:///"</code>
|
||||
* scheme is optional.
|
||||
* @param {boolean} [isUserLoaded=true] - <code>true</code> if the user specifically loaded it, <code>false</code> if not
|
||||
* (e.g., a script loaded it). If <code>false</code>, the script is not automatically loaded next time Interface starts.
|
||||
* @param {boolean} [loadScriptFromEditor=false] - <em>Not used.</em>
|
||||
* @param {boolean} [activateMainWindow=false] - <em>Not used.</em>
|
||||
* @param {boolean} [reload=false] - <code>true</code> to redownload the script, <code>false</code> to use the copy from
|
||||
* the cache if available.
|
||||
* @param {boolean} [quitWhenFinished=false] - <code>true</code> to close Interface when the script finishes,
|
||||
* <code>false</code> to not close Interface.
|
||||
* @returns {object} An empty object, <code>{}</code>.
|
||||
*/
|
||||
Q_INVOKABLE ScriptEnginePointer loadScript(const QUrl& scriptFilename = QString(),
|
||||
bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false, bool quitWhenFinished = false);
|
||||
|
||||
/**jsdoc
|
||||
* Stops or restarts an Interface script.
|
||||
* @function ScriptDiscoveryService.stopScript
|
||||
* @param {string} scriptHash
|
||||
* @param {boolean} [restart=false]
|
||||
* @returns {boolean}
|
||||
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
||||
* optional.
|
||||
* @param {boolean} [restart=false] - <code>true</code> to redownload and restart the script, <code>false</code> to stop
|
||||
* it.
|
||||
* @returns {boolean} <code>true</code> if the script was successfully stopped or restarted, <code>false</code> if it
|
||||
* wasn't (e.g., the script couldn't be found).
|
||||
*/
|
||||
Q_INVOKABLE bool stopScript(const QString& scriptHash, bool restart = false);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.reloadAllScripts
|
||||
*/
|
||||
* Restarts all Interface, avatar, and client entity scripts after clearing the scripts cache.
|
||||
* @function ScriptDiscoveryService.reloadAllScripts
|
||||
*/
|
||||
Q_INVOKABLE void reloadAllScripts();
|
||||
|
||||
/**jsdoc
|
||||
* Stops or restarts all Interface scripts. The scripts cache is not cleared. If restarting, avatar and client entity
|
||||
* scripts are also restarted.
|
||||
* @function ScriptDiscoveryService.stopAllScripts
|
||||
* @param {boolean} [restart=false]
|
||||
* @param {boolean} [restart=false] - <code>true</code> to restart the scripts, <code>false</code> to stop them.
|
||||
*/
|
||||
Q_INVOKABLE void stopAllScripts(bool restart = false);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Gets a list of all Interface scripts that are currently running.
|
||||
* @function ScriptDiscoveryService.getRunning
|
||||
* @returns {object[]}
|
||||
* @returns {ScriptDiscoveryService.RunningScript[]} All Interface scripts that are currently running.
|
||||
* @example <caption>Report all running scripts.</caption>
|
||||
* var runningScripts = ScriptDiscoveryService.getRunning();
|
||||
* print("Running scripts:");
|
||||
* for (var i = 0; i < runningScripts.length; i++) {
|
||||
* print(JSON.stringify(runningScripts[i]));
|
||||
* }
|
||||
*/
|
||||
Q_INVOKABLE QVariantList getRunning();
|
||||
|
||||
/**jsdoc
|
||||
* Gets a list of all script files that are in the default scripts directory of the Interface installation.
|
||||
* @function ScriptDiscoveryService.getPublic
|
||||
* @returns {object[]}
|
||||
* @returns {ScriptDiscoveryService.PublicScript[]} All scripts in the "scripts" directory of the Interface
|
||||
* installation.
|
||||
*/
|
||||
Q_INVOKABLE QVariantList getPublic();
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.getLocal
|
||||
* @returns {object[]}
|
||||
* @returns {ScriptDiscoveryService.LocalScript[]} Local scripts.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because there is no longer a notion of a "local" scripts folder where you would put your personal scripts.
|
||||
Q_INVOKABLE QVariantList getLocal();
|
||||
|
||||
// FIXME: Move to other Q_PROPERTY declarations.
|
||||
|
@ -148,65 +187,82 @@ public:
|
|||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the number of Interface scripts running changes.
|
||||
* @function ScriptDiscoveryService.scriptCountChanged
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when the number of running scripts changes.</caption>
|
||||
* ScriptDiscoveryService.scriptCountChanged.connect(function () {
|
||||
* print("Scripts count changed: " + ScriptDiscoveryService.getRunning().length);
|
||||
* });
|
||||
*/
|
||||
void scriptCountChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when Interface, avatar, and client entity scripts are restarting as a result of
|
||||
* {@link ScriptDiscoveryService.reloadAllScripts|reloadAllScripts} or
|
||||
* {@link ScriptDiscoveryService.stopAllScripts|stopAllScripts}.
|
||||
* @function ScriptDiscoveryService.scriptsReloading
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void scriptsReloading();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a script could not be loaded.
|
||||
* @function ScriptDiscoveryService.scriptLoadError
|
||||
* @param {string} filename
|
||||
* @param {string} error
|
||||
* @param {string} url - The path and name of the script that could not be loaded.
|
||||
* @param {string} error - <code>""</code> always.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void scriptLoadError(const QString& filename, const QString& error);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when any script prints a message to the program log via {@link print}, {@link Script.print},
|
||||
* {@link console.log}, or {@link console.debug}.
|
||||
* @function ScriptDiscoveryService.printedMessage
|
||||
* @param {string} message
|
||||
* @param {string} engineName
|
||||
* @param {string} message - The message.
|
||||
* @param {string} scriptName - The name of the script that generated the message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void printedMessage(const QString& message, const QString& engineName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when any script generates an error or {@link console.error} is called.
|
||||
* @function ScriptDiscoveryService.errorMessage
|
||||
* @param {string} message
|
||||
* @param {string} engineName
|
||||
* @param {string} message - The error message.
|
||||
* @param {string} scriptName - The name of the script that generated the error message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void errorMessage(const QString& message, const QString& engineName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when any script generates a warning or {@link console.warn} is called.
|
||||
* @function ScriptDiscoveryService.warningMessage
|
||||
* @param {string} message
|
||||
* @param {string} engineName
|
||||
* @param {string} message - The warning message.
|
||||
* @param {string} scriptName - The name of the script that generated the warning message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void warningMessage(const QString& message, const QString& engineName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when any script generates an information message or {@link console.info} is called.
|
||||
* @function ScriptDiscoveryService.infoMessage
|
||||
* @param {string} message
|
||||
* @param {string} engineName
|
||||
* @param {string} message - The information message.
|
||||
* @param {string} scriptName - The name of the script that generated the informaton message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void infoMessage(const QString& message, const QString& engineName);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.errorLoadingScript
|
||||
* @param {string} url
|
||||
* @param {string} url - URL.
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because never emitted.
|
||||
void errorLoadingScript(const QString& url);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the Debug Window is cleared.
|
||||
* @function ScriptDiscoveryService.clearDebugWindow
|
||||
* @returns {Signal}
|
||||
*/
|
||||
|
@ -216,50 +272,64 @@ public slots:
|
|||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onPrintedMessage
|
||||
* @param {string} message
|
||||
* @param {string} scriptName
|
||||
* @param {string} message - Message.
|
||||
* @param {string} scriptName - Script name.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because only use is to emit a signal.
|
||||
void onPrintedMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onErrorMessage
|
||||
* @param {string} message
|
||||
* @param {string} scriptName
|
||||
* @param {string} message - Message.
|
||||
* @param {string} scriptName - Script name.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because only use is to emit a signal.
|
||||
void onErrorMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onWarningMessage
|
||||
* @param {string} message
|
||||
* @param {string} scriptName
|
||||
* @param {string} message - Message.
|
||||
* @param {string} scriptName - Script name.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because only use is to emit a signal.
|
||||
void onWarningMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onInfoMessage
|
||||
* @param {string} message
|
||||
* @param {string} scriptName
|
||||
* @param {string} message - Message.
|
||||
* @param {string} scriptName - Script name.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because only use is to emit a signal.
|
||||
void onInfoMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onErrorLoadingScript
|
||||
* @param {string} url
|
||||
* @param {string} url - URL.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because only use is to emit a signal. And it isn't used.
|
||||
void onErrorLoadingScript(const QString& url);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onClearDebugWindow
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because only use is to emit a signal.
|
||||
void onClearDebugWindow();
|
||||
|
||||
protected slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptDiscoveryService.onScriptFinished
|
||||
* @param {string} filename
|
||||
* @param {object} engine
|
||||
* @param {string} scriptName - Script name.
|
||||
* @param {object} engine - Engine.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Deprecated because it wasn't intended to be in the API.
|
||||
void onScriptFinished(const QString& fileNameString, ScriptEnginePointer engine);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -64,14 +64,60 @@ public:
|
|||
};
|
||||
|
||||
/**jsdoc
|
||||
* <p>Provided as a property of {@link ScriptDiscoveryService}.</p>
|
||||
* <p>Has properties and functions below in addition to those of <a href="http://doc.qt.io/qt-5/qabstractitemmodel.html">
|
||||
* http://doc.qt.io/qt-5/qabstractitemmodel.html</a>.</p>
|
||||
* Information on the scripts that are in the default scripts directory of the Interface installation. This is provided as a
|
||||
* property of {@link ScriptDiscoveryService}.
|
||||
*
|
||||
* <p>The information provided reflects the subdirectory structure. Methods and signals are per QT's
|
||||
* <a href="http://doc.qt.io/qt-5/qabstractitemmodel.html">QAbstractItemModel</a> class, with the following details:</p>
|
||||
* <ul>
|
||||
* <li>A single column of data: <code>columnCount(index)</code> returns <code>1</code>. </li>
|
||||
* <li>Data is provided for the following roles:
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Role</th><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td>Display</td><td><code>0</code></td><td>The directory or script file name.</td></tr>
|
||||
* <tr><td>Path</td><td><code>256</code></td><td>The path and filename of the data item if it is a script,
|
||||
* <code>undefined</code> if it is a directory.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* </li>
|
||||
* <li>Use <code>null</code> for the root directory's index.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @class ScriptsModel
|
||||
|
||||
* @hideconstructor
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @example <caption>List the first 2 levels of the scripts directory.</caption>
|
||||
* var MAX_DIRECTORY_LEVEL = 1;
|
||||
* var DISPLAY_ROLE = 0;
|
||||
* var PATH_ROLE = 256;
|
||||
*
|
||||
* function printDirectory(parentIndex, directoryLevel, indent) {
|
||||
* var numRows = ScriptDiscoveryService.scriptsModel.rowCount(parentIndex);
|
||||
* for (var i = 0; i < numRows; i++) {
|
||||
* var rowIndex = ScriptDiscoveryService.scriptsModel.index(i, 0, parentIndex);
|
||||
*
|
||||
* var name = ScriptDiscoveryService.scriptsModel.data(rowIndex, DISPLAY_ROLE);
|
||||
* var hasChildren = ScriptDiscoveryService.scriptsModel.hasChildren(rowIndex);
|
||||
* var path = hasChildren ? "" : ScriptDiscoveryService.scriptsModel.data(rowIndex, PATH_ROLE);
|
||||
*
|
||||
* print(indent + "- " + name + (hasChildren ? "" : " - " + path));
|
||||
*
|
||||
* if (hasChildren && directoryLevel < MAX_DIRECTORY_LEVEL) {
|
||||
* printDirectory(rowIndex, directoryLevel + 1, indent + " ");
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* print("Scripts:");
|
||||
* printDirectory(null, 0, ""); // null index for the root directory.
|
||||
*/
|
||||
class ScriptsModel : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
|
@ -79,56 +125,25 @@ public:
|
|||
ScriptsModel(QObject* parent = NULL);
|
||||
~ScriptsModel();
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.index
|
||||
* @param {number} row
|
||||
* @param {number} column
|
||||
* @param {QModelIndex} parent
|
||||
* @returns {QModelIndex}
|
||||
*/
|
||||
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.parent
|
||||
* @param {QModelIndex} child
|
||||
* @returns {QModelIndex}
|
||||
*/
|
||||
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||
QModelIndex parent(const QModelIndex& child) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.data
|
||||
* @param {QModelIndex} index
|
||||
* @param {number} [role=0]
|
||||
* returns {string}
|
||||
*/
|
||||
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.rowCount
|
||||
* @param {QmodelIndex} [parent=null]
|
||||
* @returns {number}
|
||||
*/
|
||||
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.columnCount
|
||||
* @param {QmodelIndex} [parent=null]
|
||||
* @returns {number}
|
||||
*/
|
||||
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.getTreeNodeFromIndex
|
||||
* @param {QmodelIndex} index
|
||||
* @returns {TreeNodeBase}
|
||||
*/
|
||||
// Not exposed in the API because no conversion between TreeNodeBase and QScriptValue is provided.
|
||||
TreeNodeBase* getTreeNodeFromIndex(const QModelIndex& index) const;
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.getFolderNodes
|
||||
* @param {TreeNodeFolder} parent
|
||||
* @returns {TreeNodeBase[]}
|
||||
*/
|
||||
// Not exposed in the API because no conversion between TreeNodeBase and QScriptValue is provided.
|
||||
QList<TreeNodeBase*> getFolderNodes(TreeNodeFolder* parent) const;
|
||||
|
||||
enum Role {
|
||||
|
@ -136,9 +151,30 @@ public:
|
|||
};
|
||||
|
||||
protected slots:
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.updateScriptsLocation
|
||||
* @param {string} newPath - New path.
|
||||
* @deprecated This method is deprecated and will be removed from the API.
|
||||
*/
|
||||
void updateScriptsLocation(const QString& newPath);
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.downloadFinished
|
||||
* @deprecated This method is deprecated and will be removed from the API.
|
||||
*/
|
||||
void downloadFinished();
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.reloadLocalFiles
|
||||
* @deprecated This method is deprecated and will be removed from the API.
|
||||
*/
|
||||
void reloadLocalFiles();
|
||||
|
||||
/**jsdoc
|
||||
* @function ScriptsModel.reloadDefaultFiles
|
||||
* @deprecated This method is deprecated and will be removed from the API.
|
||||
*/
|
||||
void reloadDefaultFiles();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -16,14 +16,60 @@
|
|||
#include <QSortFilterProxyModel>
|
||||
|
||||
/**jsdoc
|
||||
* <p>Provided as a property of {@link ScriptDiscoveryService}.</p>
|
||||
* <p>Has properties and functions per <a href="http://doc.qt.io/qt-5/qsortfilterproxymodel.html">
|
||||
* http://doc.qt.io/qt-5/qsortfilterproxymodel.html</a>.</p>
|
||||
* Sorted and filtered information on the scripts that are in the default scripts directory of the Interface installation. This
|
||||
* is provided as a property of {@link ScriptDiscoveryService}.
|
||||
*
|
||||
* <p>The information provided reflects the subdirectory structure. Properties, methods, and signals are per QT's
|
||||
* <a href="https://doc.qt.io/qt-5/qsortfilterproxymodel.html">QSortFilterProxyModel</a> class, with the following details:</p>
|
||||
* <ul>
|
||||
* <li>The rows are sorted per directory and file names.</li>
|
||||
* <li>A single column of data: <code>columnCount(index)</code> returns <code>1</code>. </li>
|
||||
* <li>Data is provided for the following roles:
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Role</th><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td>Display</td><td><code>0</code></td><td>The directory or script file name.</td></tr>
|
||||
* <tr><td>Path</td><td><code>256</code></td><td>The path and filename of the data item if it is a script,
|
||||
* <code>undefined</code> if it is a directory.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* </li>
|
||||
* <li>Use <code>null</code> for the root directory's index.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @class ScriptsModelFilter
|
||||
* @hideconstructor
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @example <caption>List all scripts that include "edit" in their name.</caption>
|
||||
* var DISPLAY_ROLE = 0;
|
||||
* var PATH_ROLE = 256;
|
||||
*
|
||||
* function printDirectory(parentIndex, directoryLevel, indent) {
|
||||
* var numRows = ScriptDiscoveryService.scriptsModelFilter.rowCount(parentIndex);
|
||||
* for (var i = 0; i < numRows; i++) {
|
||||
* var rowIndex = ScriptDiscoveryService.scriptsModelFilter.index(i, 0, parentIndex);
|
||||
*
|
||||
* var name = ScriptDiscoveryService.scriptsModelFilter.data(rowIndex, DISPLAY_ROLE);
|
||||
* var hasChildren = ScriptDiscoveryService.scriptsModelFilter.hasChildren(rowIndex);
|
||||
* var path = hasChildren ? "" : ScriptDiscoveryService.scriptsModelFilter.data(rowIndex, PATH_ROLE);
|
||||
*
|
||||
* print(indent + "- " + name + (hasChildren ? "" : " - " + path));
|
||||
*
|
||||
* if (hasChildren) {
|
||||
* printDirectory(rowIndex, directoryLevel + 1, indent + " ");
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*edit.*$", "i"); // Set the filter.
|
||||
* print("Edit scripts:");
|
||||
* printDirectory(null, 0, ""); // null index for the root directory.
|
||||
*/
|
||||
class ScriptsModelFilter : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -136,13 +136,9 @@ void QmlWindowClass::initQml(QVariantMap properties) {
|
|||
#if !defined(Q_OS_ANDROID)
|
||||
// If the restricted flag is on, override the FileTypeProfile and HFWebEngineProfile objects in the
|
||||
// QML surface root context with local ones
|
||||
qDebug() << "Context initialization lambda";
|
||||
if (_restricted) {
|
||||
qDebug() << "Restricting web content";
|
||||
ContextAwareProfile::restrictContext(context);
|
||||
FileTypeProfile::registerWithContext(context);
|
||||
HFWebEngineProfile::registerWithContext(context);
|
||||
}
|
||||
ContextAwareProfile::restrictContext(context, _restricted);
|
||||
FileTypeProfile::registerWithContext(context);
|
||||
HFWebEngineProfile::registerWithContext(context);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -11,22 +11,47 @@
|
|||
|
||||
#include "ContextAwareProfile.h"
|
||||
|
||||
#if !defined(Q_OS_ANDROID)
|
||||
|
||||
#include <cassert>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtQml/QQmlContext>
|
||||
|
||||
#include <shared/QtHelpers.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
||||
|
||||
ContextAwareProfile::ContextAwareProfile(QQmlContext* parent) :
|
||||
QQuickWebEngineProfile(parent), _context(parent) { }
|
||||
|
||||
|
||||
void ContextAwareProfile::restrictContext(QQmlContext* context) {
|
||||
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, true);
|
||||
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) :
|
||||
ContextAwareProfileParent(context), _context(context) {
|
||||
assert(context);
|
||||
}
|
||||
|
||||
bool ContextAwareProfile::isRestricted(QQmlContext* context) {
|
||||
return context->contextProperty(RESTRICTED_FLAG_PROPERTY).toBool();
|
||||
|
||||
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
|
||||
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
|
||||
}
|
||||
|
||||
#endif
|
||||
bool ContextAwareProfile::isRestrictedInternal() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
bool restrictedResult = false;
|
||||
BLOCKING_INVOKE_METHOD(this, "isRestrictedInternal", Q_RETURN_ARG(bool, restrictedResult));
|
||||
return restrictedResult;
|
||||
}
|
||||
|
||||
QVariant variant = _context->contextProperty(RESTRICTED_FLAG_PROPERTY);
|
||||
if (variant.isValid()) {
|
||||
return variant.toBool();
|
||||
}
|
||||
|
||||
// BUGZ-1365 - we MUST defalut to restricted mode in the absence of a flag, or it's too easy for someone to make
|
||||
// a new mechanism for loading web content that fails to restrict access to local files
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextAwareProfile::isRestricted() {
|
||||
auto now = usecTimestampNow();
|
||||
if (now > _cacheExpiry) {
|
||||
_cachedValue = isRestrictedInternal();
|
||||
_cacheExpiry = now + MAX_CACHE_AGE;
|
||||
}
|
||||
return _cachedValue;
|
||||
}
|
||||
|
|
|
@ -17,26 +17,40 @@
|
|||
#include <QtWebEngine/QQuickWebEngineProfile>
|
||||
#include <QtWebEngineCore/QWebEngineUrlRequestInterceptor>
|
||||
|
||||
using ContextAwareProfileParent = QQuickWebEngineProfile;
|
||||
using RequestInterceptorParent = QWebEngineUrlRequestInterceptor;
|
||||
#else
|
||||
#include <QtCore/QObject>
|
||||
|
||||
using ContextAwareProfileParent = QObject;
|
||||
using RequestInterceptorParent = QObject;
|
||||
#endif
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
class QQmlContext;
|
||||
|
||||
class ContextAwareProfile : public QQuickWebEngineProfile {
|
||||
class ContextAwareProfile : public ContextAwareProfileParent {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static void restrictContext(QQmlContext* context);
|
||||
static bool isRestricted(QQmlContext* context);
|
||||
QQmlContext* getContext() const { return _context; }
|
||||
static void restrictContext(QQmlContext* context, bool restrict = true);
|
||||
bool isRestricted();
|
||||
Q_INVOKABLE bool isRestrictedInternal();
|
||||
protected:
|
||||
|
||||
class RequestInterceptor : public QWebEngineUrlRequestInterceptor {
|
||||
class RequestInterceptor : public RequestInterceptorParent {
|
||||
public:
|
||||
RequestInterceptor(ContextAwareProfile* parent) : QWebEngineUrlRequestInterceptor(parent), _profile(parent) {}
|
||||
QQmlContext* getContext() const { return _profile->getContext(); }
|
||||
RequestInterceptor(ContextAwareProfile* parent) : RequestInterceptorParent(parent), _profile(parent) { }
|
||||
bool isRestricted() { return _profile->isRestricted(); }
|
||||
protected:
|
||||
ContextAwareProfile* _profile;
|
||||
};
|
||||
|
||||
ContextAwareProfile(QQmlContext* parent);
|
||||
QQmlContext* _context;
|
||||
QQmlContext* _context{ nullptr };
|
||||
bool _cachedValue{ false };
|
||||
quint64 _cacheExpiry{ 0 };
|
||||
constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // hifi_FileTypeProfile_h
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue