diff --git a/libraries/script-engine/src/ScriptValue.cpp b/libraries/script-engine/src/ScriptValue.cpp index 5f0a2cfe39..4e00e905ef 100644 --- a/libraries/script-engine/src/ScriptValue.cpp +++ b/libraries/script-engine/src/ScriptValue.cpp @@ -55,6 +55,7 @@ public: const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override; virtual void setPrototype(const ScriptValue& prototype) override; virtual bool strictlyEquals(const ScriptValue& other) const override; + virtual inline QList getPropertyNames() const; virtual bool toBool() const override; virtual qint32 toInt32() const override; @@ -209,6 +210,10 @@ bool ScriptValueProxyNull::strictlyEquals(const ScriptValue& other) const { return !other.isValid(); } +QList ScriptValueProxyNull::getPropertyNames() const { + return QList(); +} + bool ScriptValueProxyNull::toBool() const { return false; } diff --git a/libraries/script-engine/src/ScriptValue.h b/libraries/script-engine/src/ScriptValue.h index 2c1145df6a..55ed804ccf 100644 --- a/libraries/script-engine/src/ScriptValue.h +++ b/libraries/script-engine/src/ScriptValue.h @@ -106,6 +106,7 @@ public: const PropertyFlags& flags = KeepExistingFlags); inline void setPrototype(const ScriptValue& prototype); inline bool strictlyEquals(const ScriptValue& other) const; + inline QList getPropertyNames() const; inline bool toBool() const; inline qint32 toInt32() const; @@ -165,6 +166,7 @@ public: const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) = 0; virtual void setPrototype(const ScriptValue& prototype) = 0; virtual bool strictlyEquals(const ScriptValue& other) const = 0; + virtual QList getPropertyNames() const = 0; virtual bool toBool() const = 0; virtual qint32 toInt32() const = 0; @@ -349,6 +351,11 @@ bool ScriptValue::strictlyEquals(const ScriptValue& other) const { return _proxy->strictlyEquals(other); } +inline QList ScriptValue::getPropertyNames() const { + Q_ASSERT(_proxy != nullptr); + return _proxy->getPropertyNames(); +}; + bool ScriptValue::toBool() const { Q_ASSERT(_proxy != nullptr); return _proxy->toBool(); diff --git a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp index 40a36b2e66..9ed236de09 100644 --- a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp +++ b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp @@ -454,6 +454,33 @@ bool ScriptValueV8Wrapper::strictlyEquals(const ScriptValue& other) const { return unwrappedOther ? _value.constGet()->StrictEquals(unwrappedOther->toV8Value().constGet()) : false; } +inline QList ScriptValueV8Wrapper::getPropertyNames() const { + auto isolate = _engine->getIsolate(); + v8::Locker locker(isolate); + v8::Isolate::Scope isolateScope(isolate); + v8::HandleScope handleScope(isolate); + auto context = _engine->getContext(); + v8::Context::Scope contextScope(context); + v8::Local value = _value.constGet(); + if (value->IsNullOrUndefined()) { + return QList(); + } + if (!value->IsObject()) { + return QList(); + } + v8::Local object = v8::Local::Cast(value); + v8::Local array; + if (!object->GetPropertyNames(context).ToLocal(&array)) { + return QList(); + } + QList names; + for (uint32_t n = 0; n < array->Length(); n++) { + v8::Local name = array->Get(context, n).ToLocalChecked()->ToString(context).ToLocalChecked(); + names.append(*v8::String::Utf8Value(isolate, name)); + } + return names; +} + bool ScriptValueV8Wrapper::toBool() const { auto isolate = _engine->getIsolate(); v8::Locker locker(isolate); diff --git a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.h b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.h index d174d91703..233e5c62a1 100644 --- a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.h +++ b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.h @@ -67,6 +67,7 @@ public: // ScriptValue implementation const ScriptValue::PropertyFlags& flags = ScriptValue::KeepExistingFlags) override; virtual void setPrototype(const ScriptValue& prototype) override; virtual bool strictlyEquals(const ScriptValue& other) const override; + virtual QList getPropertyNames() const; virtual bool equals(const ScriptValue& other) const override; virtual bool isArray() const override;