From 23805ae47898a1ae4b5c8d8bb30b8b69d2fc435a Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 18 Jan 2012 10:00:02 +0100 Subject: [PATCH] Add QJSValue::deleteProperty() function MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This makes it possible to delete a property without relying on passing a QJSValue of invalid type to setProperty() (the invalid type is going to be removed). Task-number: QTBUG-23604 Change-Id: I653b3349050ad1aac1cf6ccc8547c753abbb9f1d Reviewed-by: Simon Hausmann Reviewed-by: Jędrzej Nowacki --- src/declarative/qml/v8/qjsvalue.cpp | 29 +++++++++++++++- src/declarative/qml/v8/qjsvalue.h | 2 ++ tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp | 44 ++++++++++++++++++++++++ tests/auto/declarative/qjsvalue/tst_qjsvalue.h | 4 +++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/v8/qjsvalue.cpp b/src/declarative/qml/v8/qjsvalue.cpp index 9980463..9d21a1d 100644 --- a/src/declarative/qml/v8/qjsvalue.cpp +++ b/src/declarative/qml/v8/qjsvalue.cpp @@ -915,7 +915,7 @@ QJSValue QJSValue::property(quint32 arrayIndex) const built-in properties, such as the \c{length} property of Array objects or meta properties of QObject objects. - \sa property() + \sa property(), deleteProperty() */ void QJSValue::setProperty(const QString& name, const QJSValue& value) { @@ -944,6 +944,33 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) } /*! + Attempts to delete this object's property of the given \a name. + Returns true if the property was deleted, otherwise returns false. + + The behavior of this function is consistent with the JavaScript + delete operator. In particular: + + \list + \o Non-configurable properties cannot be deleted. + \o This function will return true even if this object doesn't + have a property of the given \a name (i.e., non-existent + properties are "trivially deletable"). + \o If this object doesn't have an own property of the given + \a name, but an object in the prototype() chain does, the + prototype object's property is not deleted, and this function + returns true. + \endlist + + \sa setProperty(), hasOwnProperty() +*/ +bool QJSValue::deleteProperty(const QString &name) +{ + Q_D(QJSValue); + QScriptIsolate api(d->engine()); + return d->deleteProperty(name); +} + +/*! Returns true if this object has a property of the given \a name, otherwise returns false. diff --git a/src/declarative/qml/v8/qjsvalue.h b/src/declarative/qml/v8/qjsvalue.h index 756081d..280f44e 100644 --- a/src/declarative/qml/v8/qjsvalue.h +++ b/src/declarative/qml/v8/qjsvalue.h @@ -134,6 +134,8 @@ public: QJSValue property(quint32 arrayIndex) const; void setProperty(quint32 arrayIndex, const QJSValue &value); + bool deleteProperty(const QString &name); + QJSValue::PropertyFlags propertyFlags(const QString &name) const; QJSValue call(const QJSValue &thisObject = QJSValue(), diff --git a/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp b/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp index e8073bc..caff7fc 100644 --- a/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/declarative/qjsvalue/tst_qjsvalue.cpp @@ -1843,6 +1843,50 @@ void tst_QJSValue::hasProperty_changePrototype() QVERIFY(obj.hasOwnProperty("foo")); } +void tst_QJSValue::deleteProperty_basic() +{ + QJSEngine eng; + QJSValue obj = eng.newObject(); + // deleteProperty() behavior matches JS delete operator + QVERIFY(obj.deleteProperty("foo")); + + obj.setProperty("foo", 123); + QVERIFY(obj.deleteProperty("foo")); + QVERIFY(!obj.hasOwnProperty("foo")); +} + +void tst_QJSValue::deleteProperty_globalObject() +{ + QJSEngine eng; + QJSValue global = eng.globalObject(); + // deleteProperty() behavior matches JS delete operator + QVERIFY(global.deleteProperty("foo")); + + global.setProperty("foo", 123); + QVERIFY(global.deleteProperty("foo")); + QVERIFY(!global.hasProperty("foo")); + + QVERIFY(global.deleteProperty("Math")); + QVERIFY(!global.hasProperty("Math")); + + QVERIFY(!global.deleteProperty("NaN")); // read-only + QVERIFY(global.hasProperty("NaN")); +} + +void tst_QJSValue::deleteProperty_inPrototype() +{ + QJSEngine eng; + QJSValue obj = eng.newObject(); + QJSValue proto = eng.newObject(); + obj.setPrototype(proto); + + proto.setProperty("foo", 123); + QVERIFY(obj.hasProperty("foo")); + // deleteProperty() behavior matches JS delete operator + QVERIFY(obj.deleteProperty("foo")); + QVERIFY(obj.hasProperty("foo")); +} + void tst_QJSValue::getSetProperty_HooliganTask162051() { QJSEngine eng; diff --git a/tests/auto/declarative/qjsvalue/tst_qjsvalue.h b/tests/auto/declarative/qjsvalue/tst_qjsvalue.h index 7f7c04a..7696f61 100644 --- a/tests/auto/declarative/qjsvalue/tst_qjsvalue.h +++ b/tests/auto/declarative/qjsvalue/tst_qjsvalue.h @@ -117,6 +117,10 @@ private slots: void hasProperty_globalObject(); void hasProperty_changePrototype(); + void deleteProperty_basic(); + void deleteProperty_globalObject(); + void deleteProperty_inPrototype(); + void getSetPrototype_cyclicPrototype(); void getSetPrototype_evalCyclicPrototype(); void getSetPrototype_eval(); -- 2.7.4