mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 17:10:45 +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 <SoundCacheScriptingInterface.h>
|
||||||
#include <ui/TabletScriptingInterface.h>
|
#include <ui/TabletScriptingInterface.h>
|
||||||
#include <ui/ToolbarScriptingInterface.h>
|
#include <ui/ToolbarScriptingInterface.h>
|
||||||
|
#include <ui/types/ContextAwareProfile.h>
|
||||||
#include <Tooltip.h>
|
#include <Tooltip.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
|
@ -3285,6 +3286,9 @@ void Application::initializeUi() {
|
||||||
}
|
}
|
||||||
return result.toPoint();
|
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();
|
offscreenUi->resume();
|
||||||
#endif
|
#endif
|
||||||
connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){
|
connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){
|
||||||
|
@ -7457,7 +7461,7 @@ void Application::addingEntityWithCertificate(const QString& certificateID, cons
|
||||||
ledger->updateLocation(certificateID, placeName);
|
ledger->updateLocation(certificateID, placeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) {
|
void Application::registerScriptEngineWithApplicationServices(const ScriptEnginePointer& scriptEngine) {
|
||||||
|
|
||||||
scriptEngine->setEmitScriptUpdatesFunction([this]() {
|
scriptEngine->setEmitScriptUpdatesFunction([this]() {
|
||||||
SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer);
|
SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer);
|
||||||
|
@ -7496,9 +7500,19 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
||||||
qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue,
|
qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue,
|
||||||
RayToOverlayIntersectionResultFromScriptValue);
|
RayToOverlayIntersectionResultFromScriptValue);
|
||||||
|
|
||||||
|
bool clientScript = scriptEngine->isClientScript();
|
||||||
|
|
||||||
#if !defined(DISABLE_QML)
|
#if !defined(DISABLE_QML)
|
||||||
scriptEngine->registerGlobalObject("OffscreenFlags", getOffscreenUI()->getFlags());
|
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
|
#endif
|
||||||
|
|
||||||
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<ToolbarProxy>, wrapperFromScriptValue<ToolbarProxy>);
|
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<ToolbarProxy>, wrapperFromScriptValue<ToolbarProxy>);
|
||||||
|
@ -7523,7 +7537,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
||||||
scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
||||||
LocationScriptingInterface::locationSetter);
|
LocationScriptingInterface::locationSetter);
|
||||||
|
|
||||||
bool clientScript = scriptEngine->isClientScript();
|
|
||||||
scriptEngine->registerFunction("OverlayWindow", clientScript ? QmlWindowClass::constructor : QmlWindowClass::restricted_constructor);
|
scriptEngine->registerFunction("OverlayWindow", clientScript ? QmlWindowClass::constructor : QmlWindowClass::restricted_constructor);
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(DISABLE_QML)
|
#if !defined(Q_OS_ANDROID) && !defined(DISABLE_QML)
|
||||||
scriptEngine->registerFunction("OverlayWebWindow", clientScript ? QmlWebWindowClass::constructor : QmlWebWindowClass::restricted_constructor);
|
scriptEngine->registerFunction("OverlayWebWindow", clientScript ? QmlWebWindowClass::constructor : QmlWebWindowClass::restricted_constructor);
|
||||||
|
|
|
@ -252,7 +252,7 @@ public:
|
||||||
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
|
||||||
|
|
||||||
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }
|
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 void copyCurrentViewFrustum(ViewFrustum& viewOut) const override { copyDisplayViewFrustum(viewOut); }
|
||||||
virtual QThread* getMainThread() override { return thread(); }
|
virtual QThread* getMainThread() override { return thread(); }
|
||||||
|
|
|
@ -52,6 +52,9 @@ static const QVariantMap DOCK_AREA {
|
||||||
{ "RIGHT", DockArea::RIGHT }
|
{ "RIGHT", DockArea::RIGHT }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DesktopScriptingInterface::DesktopScriptingInterface(QObject* parent, bool restricted)
|
||||||
|
: QObject(parent), _restricted(restricted) { }
|
||||||
|
|
||||||
int DesktopScriptingInterface::getWidth() {
|
int DesktopScriptingInterface::getWidth() {
|
||||||
QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize();
|
QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize();
|
||||||
return size.width();
|
return size.width();
|
||||||
|
@ -128,7 +131,7 @@ InteractiveWindowPointer DesktopScriptingInterface::createWindow(const QString&
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InteractiveWindow(sourceUrl, properties);
|
return new InteractiveWindow(sourceUrl, properties, _restricted);
|
||||||
}
|
}
|
||||||
|
|
||||||
InteractiveWindowPointer DesktopScriptingInterface::createWindowOnThread(const QString& sourceUrl, const QVariantMap& properties, QThread* targetThread) {
|
InteractiveWindowPointer DesktopScriptingInterface::createWindowOnThread(const QString& sourceUrl, const QVariantMap& properties, QThread* targetThread) {
|
||||||
|
@ -139,7 +142,7 @@ InteractiveWindowPointer DesktopScriptingInterface::createWindowOnThread(const Q
|
||||||
if (!urlValidator(sourceUrl)) {
|
if (!urlValidator(sourceUrl)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
InteractiveWindowPointer window = new InteractiveWindow(sourceUrl, properties);
|
InteractiveWindowPointer window = new InteractiveWindow(sourceUrl, properties, _restricted);
|
||||||
window->moveToThread(targetThread);
|
window->moveToThread(targetThread);
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@ class DesktopScriptingInterface : public QObject, public Dependency {
|
||||||
Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
|
Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
DesktopScriptingInterface(QObject* parent= nullptr, bool restricted = false);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Sets the opacity of the HUD surface.
|
* Sets the opacity of the HUD surface.
|
||||||
* @function Desktop.setHUDAlpha
|
* @function Desktop.setHUDAlpha
|
||||||
|
@ -106,6 +108,7 @@ private:
|
||||||
static QVariantMap getDockArea();
|
static QVariantMap getDockArea();
|
||||||
|
|
||||||
Q_INVOKABLE static QVariantMap getPresentationMode();
|
Q_INVOKABLE static QVariantMap getPresentationMode();
|
||||||
|
const bool _restricted;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
#include <QQuickView>
|
#include <QQuickView>
|
||||||
|
|
||||||
|
#include <ui/types/ContextAwareProfile.h>
|
||||||
|
#include <ui/types/HFWebEngineProfile.h>
|
||||||
|
#include <ui/types/FileTypeProfile.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <DockWidget.h>
|
#include <DockWidget.h>
|
||||||
#include <RegisteredMetaTypes.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}.
|
* 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.
|
* 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;
|
InteractiveWindowPresentationMode presentationMode = InteractiveWindowPresentationMode::Native;
|
||||||
|
|
||||||
if (properties.contains(PRESENTATION_MODE_PROPERTY)) {
|
if (properties.contains(PRESENTATION_MODE_PROPERTY)) {
|
||||||
|
@ -228,9 +231,16 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
_dockWidget->setObjectName("DockedWidget");
|
_dockWidget->setObjectName("DockedWidget");
|
||||||
mainWindow->addDockWidget(dockArea, _dockWidget.get());
|
mainWindow->addDockWidget(dockArea, _dockWidget.get());
|
||||||
} else {
|
} else {
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto contextInitLambda = [&](QQmlContext* context) {
|
||||||
// Build the event bridge and wrapper on the main thread
|
// If the restricted flag is on, the web content will not be able to access local files
|
||||||
offscreenUi->loadInNewContext(CONTENT_WINDOW_QML, [&](QQmlContext* context, QObject* object) {
|
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);
|
_qmlWindowProxy = std::shared_ptr<QmlWindowProxy>(new QmlWindowProxy(object, nullptr), qmlWindowProxyDeleter);
|
||||||
context->setContextProperty(EVENT_BRIDGE_PROPERTY, _interactiveWindowProxy.get());
|
context->setContextProperty(EVENT_BRIDGE_PROPERTY, _interactiveWindowProxy.get());
|
||||||
if (properties.contains(ADDITIONAL_FLAGS_PROPERTY)) {
|
if (properties.contains(ADDITIONAL_FLAGS_PROPERTY)) {
|
||||||
|
@ -286,7 +296,11 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
}
|
}
|
||||||
object->setObjectName("InteractiveWindow");
|
object->setObjectName("InteractiveWindow");
|
||||||
object->setProperty(SOURCE_PROPERTY, sourceURL);
|
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)
|
Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties);
|
InteractiveWindow(const QString& sourceUrl, const QVariantMap& properties, bool restricted);
|
||||||
~InteractiveWindow();
|
~InteractiveWindow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
[request setValue:@USER_AGENT_STRING forHTTPHeaderField:@"User-Agent"];
|
[request setValue:@USER_AGENT_STRING forHTTPHeaderField:@"User-Agent"];
|
||||||
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
|
||||||
|
|
||||||
// We're using an ephermeral session here to ensure the tags api response is never cached.
|
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
|
||||||
NSURLSession* session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.ephemeralSessionConfiguration];
|
NSURLSessionDataTask* dataTask = [NSURLSession.sharedSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||||
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
|
||||||
NSLog(@"Latest Build Request error: %@", error);
|
NSLog(@"Latest Build Request error: %@", error);
|
||||||
NSLog(@"Latest Build Request Data: %@", data);
|
NSLog(@"Latest Build Request Data: %@", data);
|
||||||
NSHTTPURLResponse* ne = (NSHTTPURLResponse *)response;
|
NSHTTPURLResponse* ne = (NSHTTPURLResponse *)response;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
class AbstractScriptingServicesInterface {
|
class AbstractScriptingServicesInterface {
|
||||||
public:
|
public:
|
||||||
/// Registers application specific services with a script engine.
|
/// 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);
|
Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Starts running another script in Interface.
|
* Starts running another script in Interface, if it isn't already running. The script is not automatically loaded next
|
||||||
* <table><tr><th>Available in:</th><td>Interface Scripts</td><td>Avatar Scripts</td></tr></table>
|
* 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
|
* @function Script.load
|
||||||
* @param {string} filename - The URL of the script to load. This can be relative to the current script's URL.
|
* @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>
|
* @example <caption>Load a script from another script.</caption>
|
||||||
|
@ -754,8 +756,8 @@ signals:
|
||||||
void cleanupMenuItem(const QString& menuItemString);
|
void cleanupMenuItem(const QString& menuItemString);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when a script prints a message to the program log via {@link Script.print}, {@link print},
|
* Triggered when the script prints a message to the program log via {@link print}, {@link Script.print},
|
||||||
* {@link console.log}, {@link console.info}, {@link console.warn}, {@link console.error}, or {@link console.debug}.
|
* {@link console.log}, or {@link console.debug}.
|
||||||
* @function Script.printedMessage
|
* @function Script.printedMessage
|
||||||
* @param {string} message - The message.
|
* @param {string} message - The message.
|
||||||
* @param {string} scriptName - The name of the script that generated 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);
|
void printedMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function Script.errorMessage
|
||||||
* @param {string} message - The error message.
|
* @param {string} message - The error message.
|
||||||
* @param {string} scriptName - The name of the script that generated 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);
|
void errorMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function Script.warningMessage
|
||||||
* @param {string} message - The warning message.
|
* @param {string} message - The warning message.
|
||||||
* @param {string} scriptName - The name of the script that generated 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);
|
void warningMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function Script.infoMessage
|
||||||
* @param {string} message - The information message.
|
* @param {string} message - The information message.
|
||||||
* @param {string} scriptName - The name of the script that generated 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.
|
* @param {Uuid} entityID - The ID of the entity that the script is running in.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
|
* @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;
|
* this.entityID = Uuid.NULL;
|
||||||
|
* };
|
||||||
*
|
*
|
||||||
* Script.entityScriptPreloadFinished.connect(function (entityID) {
|
* Script.entityScriptPreloadFinished.connect(function (entityID) {
|
||||||
* this.entityID = entityID;
|
* this.entityID = entityID;
|
||||||
|
|
|
@ -209,6 +209,18 @@ void ScriptEngines::shutdownScripting() {
|
||||||
qCDebug(scriptengine) << "DONE Stopping all scripts....";
|
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 getPublicChildNodes(TreeNodeFolder* parent) {
|
||||||
QVariantList result;
|
QVariantList result;
|
||||||
QList<TreeNodeBase*> treeNodes = getScriptsModel().getFolderNodes(parent);
|
QList<TreeNodeBase*> treeNodes = getScriptsModel().getFolderNodes(parent);
|
||||||
|
@ -240,6 +252,13 @@ QVariantList ScriptEngines::getPublic() {
|
||||||
return getPublicChildNodes(NULL);
|
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 ScriptEngines::getLocal() {
|
||||||
QVariantList result;
|
QVariantList result;
|
||||||
QList<TreeNodeBase*> treeNodes = getScriptsModel().getFolderNodes(NULL);
|
QList<TreeNodeBase*> treeNodes = getScriptsModel().getFolderNodes(NULL);
|
||||||
|
@ -260,6 +279,15 @@ QVariantList ScriptEngines::getLocal() {
|
||||||
return result;
|
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 ScriptEngines::getRunning() {
|
||||||
QVariantList result;
|
QVariantList result;
|
||||||
auto runningScripts = getRunningScripts();
|
auto runningScripts = getRunningScripts();
|
||||||
|
|
|
@ -28,18 +28,26 @@
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* The <code>ScriptDiscoveryService</code> API provides facilities to work with Interface scripts.
|
||||||
|
*
|
||||||
* @namespace ScriptDiscoveryService
|
* @namespace ScriptDiscoveryService
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
|
||||||
* @hifi-avatar
|
* @hifi-avatar
|
||||||
|
* @hifi-client-entity
|
||||||
*
|
*
|
||||||
* @property {string} debugScriptUrl
|
* @property {string} debugScriptUrl="" - The path and name of a script to debug using the "API Debugger" developer tool
|
||||||
* @property {string} defaultScriptsPath
|
* (currentAPI.js). If set, the API Debugger dialog displays the objects and values exposed by the script using
|
||||||
* @property {ScriptsModel} scriptsModel
|
* {@link Script.registerValue} and similar.
|
||||||
* @property {ScriptsModelFilter} scriptsModelFilter
|
* @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 {
|
class NativeScriptInitializers : public ScriptInitializerMixin {
|
||||||
public:
|
public:
|
||||||
bool registerNativeScriptInitializer(NativeScriptInitializer initializer) override;
|
bool registerNativeScriptInitializer(NativeScriptInitializer initializer) override;
|
||||||
|
@ -77,61 +85,92 @@ public:
|
||||||
QString getDefaultScriptsLocation() const;
|
QString getDefaultScriptsLocation() const;
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @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);
|
Q_INVOKABLE void loadOneScript(const QString& scriptFilename);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function ScriptDiscoveryService.loadScript
|
||||||
* @param {string} [filename=""]
|
* @param {string} [url=""] - The path and name of the script. If a local file, including the <code>"file:///"</code>
|
||||||
* @param {boolean} [isUserLoaded=true]
|
* scheme is optional.
|
||||||
* @param {boolean} [loadScriptFromEditor=false]
|
* @param {boolean} [isUserLoaded=true] - <code>true</code> if the user specifically loaded it, <code>false</code> if not
|
||||||
* @param {boolean} [activateMainWindow=false]
|
* (e.g., a script loaded it). If <code>false</code>, the script is not automatically loaded next time Interface starts.
|
||||||
* @param {boolean} [reload=false]
|
* @param {boolean} [loadScriptFromEditor=false] - <em>Not used.</em>
|
||||||
* @param {boolean} [quitWhenFinished=false]
|
* @param {boolean} [activateMainWindow=false] - <em>Not used.</em>
|
||||||
* @returns {boolean}
|
* @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(),
|
Q_INVOKABLE ScriptEnginePointer loadScript(const QUrl& scriptFilename = QString(),
|
||||||
bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false, bool quitWhenFinished = false);
|
bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false, bool quitWhenFinished = false);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Stops or restarts an Interface script.
|
||||||
* @function ScriptDiscoveryService.stopScript
|
* @function ScriptDiscoveryService.stopScript
|
||||||
* @param {string} scriptHash
|
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
||||||
* @param {boolean} [restart=false]
|
* optional.
|
||||||
* @returns {boolean}
|
* @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);
|
Q_INVOKABLE bool stopScript(const QString& scriptHash, bool restart = false);
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.reloadAllScripts
|
* Restarts all Interface, avatar, and client entity scripts after clearing the scripts cache.
|
||||||
*/
|
* @function ScriptDiscoveryService.reloadAllScripts
|
||||||
|
*/
|
||||||
Q_INVOKABLE void reloadAllScripts();
|
Q_INVOKABLE void reloadAllScripts();
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @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);
|
Q_INVOKABLE void stopAllScripts(bool restart = false);
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Gets a list of all Interface scripts that are currently running.
|
||||||
* @function ScriptDiscoveryService.getRunning
|
* @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();
|
Q_INVOKABLE QVariantList getRunning();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Gets a list of all script files that are in the default scripts directory of the Interface installation.
|
||||||
* @function ScriptDiscoveryService.getPublic
|
* @function ScriptDiscoveryService.getPublic
|
||||||
* @returns {object[]}
|
* @returns {ScriptDiscoveryService.PublicScript[]} All scripts in the "scripts" directory of the Interface
|
||||||
|
* installation.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QVariantList getPublic();
|
Q_INVOKABLE QVariantList getPublic();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.getLocal
|
* @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();
|
Q_INVOKABLE QVariantList getLocal();
|
||||||
|
|
||||||
// FIXME: Move to other Q_PROPERTY declarations.
|
// FIXME: Move to other Q_PROPERTY declarations.
|
||||||
|
@ -148,65 +187,82 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Triggered when the number of Interface scripts running changes.
|
||||||
* @function ScriptDiscoveryService.scriptCountChanged
|
* @function ScriptDiscoveryService.scriptCountChanged
|
||||||
* @returns {Signal}
|
* @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();
|
void scriptCountChanged();
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function ScriptDiscoveryService.scriptsReloading
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void scriptsReloading();
|
void scriptsReloading();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Triggered when a script could not be loaded.
|
||||||
* @function ScriptDiscoveryService.scriptLoadError
|
* @function ScriptDiscoveryService.scriptLoadError
|
||||||
* @param {string} filename
|
* @param {string} url - The path and name of the script that could not be loaded.
|
||||||
* @param {string} error
|
* @param {string} error - <code>""</code> always.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void scriptLoadError(const QString& filename, const QString& error);
|
void scriptLoadError(const QString& filename, const QString& error);
|
||||||
|
|
||||||
/**jsdoc
|
/**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
|
* @function ScriptDiscoveryService.printedMessage
|
||||||
* @param {string} message
|
* @param {string} message - The message.
|
||||||
* @param {string} engineName
|
* @param {string} scriptName - The name of the script that generated the message.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void printedMessage(const QString& message, const QString& engineName);
|
void printedMessage(const QString& message, const QString& engineName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Triggered when any script generates an error or {@link console.error} is called.
|
||||||
* @function ScriptDiscoveryService.errorMessage
|
* @function ScriptDiscoveryService.errorMessage
|
||||||
* @param {string} message
|
* @param {string} message - The error message.
|
||||||
* @param {string} engineName
|
* @param {string} scriptName - The name of the script that generated the error message.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void errorMessage(const QString& message, const QString& engineName);
|
void errorMessage(const QString& message, const QString& engineName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Triggered when any script generates a warning or {@link console.warn} is called.
|
||||||
* @function ScriptDiscoveryService.warningMessage
|
* @function ScriptDiscoveryService.warningMessage
|
||||||
* @param {string} message
|
* @param {string} message - The warning message.
|
||||||
* @param {string} engineName
|
* @param {string} scriptName - The name of the script that generated the warning message.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void warningMessage(const QString& message, const QString& engineName);
|
void warningMessage(const QString& message, const QString& engineName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Triggered when any script generates an information message or {@link console.info} is called.
|
||||||
* @function ScriptDiscoveryService.infoMessage
|
* @function ScriptDiscoveryService.infoMessage
|
||||||
* @param {string} message
|
* @param {string} message - The information message.
|
||||||
* @param {string} engineName
|
* @param {string} scriptName - The name of the script that generated the informaton message.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void infoMessage(const QString& message, const QString& engineName);
|
void infoMessage(const QString& message, const QString& engineName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.errorLoadingScript
|
* @function ScriptDiscoveryService.errorLoadingScript
|
||||||
* @param {string} url
|
* @param {string} url - URL.
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
|
* @deprecated This signal is deprecated and will be removed.
|
||||||
*/
|
*/
|
||||||
|
// Deprecated because never emitted.
|
||||||
void errorLoadingScript(const QString& url);
|
void errorLoadingScript(const QString& url);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Triggered when the Debug Window is cleared.
|
||||||
* @function ScriptDiscoveryService.clearDebugWindow
|
* @function ScriptDiscoveryService.clearDebugWindow
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
|
@ -216,50 +272,64 @@ public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onPrintedMessage
|
* @function ScriptDiscoveryService.onPrintedMessage
|
||||||
* @param {string} message
|
* @param {string} message - Message.
|
||||||
* @param {string} scriptName
|
* @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);
|
void onPrintedMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onErrorMessage
|
* @function ScriptDiscoveryService.onErrorMessage
|
||||||
* @param {string} message
|
* @param {string} message - Message.
|
||||||
* @param {string} scriptName
|
* @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);
|
void onErrorMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onWarningMessage
|
* @function ScriptDiscoveryService.onWarningMessage
|
||||||
* @param {string} message
|
* @param {string} message - Message.
|
||||||
* @param {string} scriptName
|
* @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);
|
void onWarningMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onInfoMessage
|
* @function ScriptDiscoveryService.onInfoMessage
|
||||||
* @param {string} message
|
* @param {string} message - Message.
|
||||||
* @param {string} scriptName
|
* @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);
|
void onInfoMessage(const QString& message, const QString& scriptName);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onErrorLoadingScript
|
* @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);
|
void onErrorLoadingScript(const QString& url);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onClearDebugWindow
|
* @function ScriptDiscoveryService.onClearDebugWindow
|
||||||
|
* @deprecated This function is deprecated and will be removed.
|
||||||
*/
|
*/
|
||||||
|
// Deprecated because only use is to emit a signal.
|
||||||
void onClearDebugWindow();
|
void onClearDebugWindow();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function ScriptDiscoveryService.onScriptFinished
|
* @function ScriptDiscoveryService.onScriptFinished
|
||||||
* @param {string} filename
|
* @param {string} scriptName - Script name.
|
||||||
* @param {object} engine
|
* @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);
|
void onScriptFinished(const QString& fileNameString, ScriptEnginePointer engine);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -64,14 +64,60 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* <p>Provided as a property of {@link ScriptDiscoveryService}.</p>
|
* Information on the scripts that are in the default scripts directory of the Interface installation. This is provided as a
|
||||||
* <p>Has properties and functions below in addition to those of <a href="http://doc.qt.io/qt-5/qabstractitemmodel.html">
|
* property of {@link ScriptDiscoveryService}.
|
||||||
* http://doc.qt.io/qt-5/qabstractitemmodel.html</a>.</p>
|
*
|
||||||
|
* <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
|
* @class ScriptsModel
|
||||||
|
|
||||||
|
* @hideconstructor
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
* @hifi-avatar
|
* @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 {
|
class ScriptsModel : public QAbstractItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -79,56 +125,25 @@ public:
|
||||||
ScriptsModel(QObject* parent = NULL);
|
ScriptsModel(QObject* parent = NULL);
|
||||||
~ScriptsModel();
|
~ScriptsModel();
|
||||||
|
|
||||||
/**jsdoc
|
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||||
* @function ScriptsModel.index
|
|
||||||
* @param {number} row
|
|
||||||
* @param {number} column
|
|
||||||
* @param {QModelIndex} parent
|
|
||||||
* @returns {QModelIndex}
|
|
||||||
*/
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex& parent) const override;
|
QModelIndex index(int row, int column, const QModelIndex& parent) const override;
|
||||||
|
|
||||||
/**jsdoc
|
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||||
* @function ScriptsModel.parent
|
|
||||||
* @param {QModelIndex} child
|
|
||||||
* @returns {QModelIndex}
|
|
||||||
*/
|
|
||||||
QModelIndex parent(const QModelIndex& child) const override;
|
QModelIndex parent(const QModelIndex& child) const override;
|
||||||
|
|
||||||
/**jsdoc
|
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||||
* @function ScriptsModel.data
|
|
||||||
* @param {QModelIndex} index
|
|
||||||
* @param {number} [role=0]
|
|
||||||
* returns {string}
|
|
||||||
*/
|
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
/**jsdoc
|
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||||
* @function ScriptsModel.rowCount
|
|
||||||
* @param {QmodelIndex} [parent=null]
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
|
||||||
/**jsdoc
|
// No JSDoc because the particulars of the parent class is provided in the @class description.
|
||||||
* @function ScriptsModel.columnCount
|
|
||||||
* @param {QmodelIndex} [parent=null]
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
|
||||||
/**jsdoc
|
// Not exposed in the API because no conversion between TreeNodeBase and QScriptValue is provided.
|
||||||
* @function ScriptsModel.getTreeNodeFromIndex
|
|
||||||
* @param {QmodelIndex} index
|
|
||||||
* @returns {TreeNodeBase}
|
|
||||||
*/
|
|
||||||
TreeNodeBase* getTreeNodeFromIndex(const QModelIndex& index) const;
|
TreeNodeBase* getTreeNodeFromIndex(const QModelIndex& index) const;
|
||||||
|
|
||||||
/**jsdoc
|
// Not exposed in the API because no conversion between TreeNodeBase and QScriptValue is provided.
|
||||||
* @function ScriptsModel.getFolderNodes
|
|
||||||
* @param {TreeNodeFolder} parent
|
|
||||||
* @returns {TreeNodeBase[]}
|
|
||||||
*/
|
|
||||||
QList<TreeNodeBase*> getFolderNodes(TreeNodeFolder* parent) const;
|
QList<TreeNodeBase*> getFolderNodes(TreeNodeFolder* parent) const;
|
||||||
|
|
||||||
enum Role {
|
enum Role {
|
||||||
|
@ -136,9 +151,30 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
protected slots:
|
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);
|
void updateScriptsLocation(const QString& newPath);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function ScriptsModel.downloadFinished
|
||||||
|
* @deprecated This method is deprecated and will be removed from the API.
|
||||||
|
*/
|
||||||
void downloadFinished();
|
void downloadFinished();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function ScriptsModel.reloadLocalFiles
|
||||||
|
* @deprecated This method is deprecated and will be removed from the API.
|
||||||
|
*/
|
||||||
void reloadLocalFiles();
|
void reloadLocalFiles();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function ScriptsModel.reloadDefaultFiles
|
||||||
|
* @deprecated This method is deprecated and will be removed from the API.
|
||||||
|
*/
|
||||||
void reloadDefaultFiles();
|
void reloadDefaultFiles();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -16,14 +16,60 @@
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* <p>Provided as a property of {@link ScriptDiscoveryService}.</p>
|
* Sorted and filtered information on the scripts that are in the default scripts directory of the Interface installation. This
|
||||||
* <p>Has properties and functions per <a href="http://doc.qt.io/qt-5/qsortfilterproxymodel.html">
|
* is provided as a property of {@link ScriptDiscoveryService}.
|
||||||
* http://doc.qt.io/qt-5/qsortfilterproxymodel.html</a>.</p>
|
*
|
||||||
|
* <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
|
* @class ScriptsModelFilter
|
||||||
|
* @hideconstructor
|
||||||
*
|
*
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
* @hifi-avatar
|
* @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 {
|
class ScriptsModelFilter : public QSortFilterProxyModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -136,13 +136,9 @@ void QmlWindowClass::initQml(QVariantMap properties) {
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
// If the restricted flag is on, override the FileTypeProfile and HFWebEngineProfile objects in the
|
// If the restricted flag is on, override the FileTypeProfile and HFWebEngineProfile objects in the
|
||||||
// QML surface root context with local ones
|
// QML surface root context with local ones
|
||||||
qDebug() << "Context initialization lambda";
|
ContextAwareProfile::restrictContext(context, _restricted);
|
||||||
if (_restricted) {
|
FileTypeProfile::registerWithContext(context);
|
||||||
qDebug() << "Restricting web content";
|
HFWebEngineProfile::registerWithContext(context);
|
||||||
ContextAwareProfile::restrictContext(context);
|
|
||||||
FileTypeProfile::registerWithContext(context);
|
|
||||||
HFWebEngineProfile::registerWithContext(context);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,22 +11,47 @@
|
||||||
|
|
||||||
#include "ContextAwareProfile.h"
|
#include "ContextAwareProfile.h"
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
#include <cassert>
|
||||||
|
#include <QtCore/QThread>
|
||||||
#include <QtQml/QQmlContext>
|
#include <QtQml/QQmlContext>
|
||||||
|
|
||||||
|
#include <shared/QtHelpers.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
|
||||||
|
|
||||||
ContextAwareProfile::ContextAwareProfile(QQmlContext* parent) :
|
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) :
|
||||||
QQuickWebEngineProfile(parent), _context(parent) { }
|
ContextAwareProfileParent(context), _context(context) {
|
||||||
|
assert(context);
|
||||||
|
|
||||||
void ContextAwareProfile::restrictContext(QQmlContext* context) {
|
|
||||||
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 <QtWebEngine/QQuickWebEngineProfile>
|
||||||
#include <QtWebEngineCore/QWebEngineUrlRequestInterceptor>
|
#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 QQmlContext;
|
||||||
|
|
||||||
class ContextAwareProfile : public QQuickWebEngineProfile {
|
class ContextAwareProfile : public ContextAwareProfileParent {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static void restrictContext(QQmlContext* context);
|
static void restrictContext(QQmlContext* context, bool restrict = true);
|
||||||
static bool isRestricted(QQmlContext* context);
|
bool isRestricted();
|
||||||
QQmlContext* getContext() const { return _context; }
|
Q_INVOKABLE bool isRestrictedInternal();
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class RequestInterceptor : public QWebEngineUrlRequestInterceptor {
|
class RequestInterceptor : public RequestInterceptorParent {
|
||||||
public:
|
public:
|
||||||
RequestInterceptor(ContextAwareProfile* parent) : QWebEngineUrlRequestInterceptor(parent), _profile(parent) {}
|
RequestInterceptor(ContextAwareProfile* parent) : RequestInterceptorParent(parent), _profile(parent) { }
|
||||||
QQmlContext* getContext() const { return _profile->getContext(); }
|
bool isRestricted() { return _profile->isRestricted(); }
|
||||||
protected:
|
protected:
|
||||||
ContextAwareProfile* _profile;
|
ContextAwareProfile* _profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
ContextAwareProfile(QQmlContext* parent);
|
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
|
#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