diff options
author | Ben Murdoch <benm@google.com> | 2010-07-22 15:37:06 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-07-27 10:20:25 +0100 |
commit | 967717af5423377c967781471ee106e2bb4e11c8 (patch) | |
tree | 1e701dc0a12f7f07cce1df4a7681717de77a211b /JavaScriptCore/qt/api | |
parent | dcc30a9fca45f634b1d3a12b276d3a0ccce99fc3 (diff) | |
download | external_webkit-967717af5423377c967781471ee106e2bb4e11c8.zip external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.gz external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.bz2 |
Merge WebKit at r63859 : Initial merge by git.
Change-Id: Ie8096c63ec7c991c9a9cba8bdd9c3b74a3b8ed62
Diffstat (limited to 'JavaScriptCore/qt/api')
-rw-r--r-- | JavaScriptCore/qt/api/QtScript.pro | 4 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptengine_p.cpp | 22 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptengine_p.h | 28 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h | 186 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalue_p.h | 29 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalueiterator.cpp | 226 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalueiterator.h | 63 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalueiterator_p.h | 172 |
8 files changed, 677 insertions, 53 deletions
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro index 3c2691e..c2c6f83 100644 --- a/JavaScriptCore/qt/api/QtScript.pro +++ b/JavaScriptCore/qt/api/QtScript.pro @@ -24,6 +24,7 @@ INCLUDEPATH += $$PWD/../../API SOURCES += $$PWD/qscriptengine.cpp \ $$PWD/qscriptengine_p.cpp \ $$PWD/qscriptvalue.cpp \ + $$PWD/qscriptvalueiterator.cpp \ $$PWD/qscriptstring.cpp \ $$PWD/qscriptprogram.cpp \ $$PWD/qscriptsyntaxcheckresult.cpp \ @@ -33,12 +34,15 @@ HEADERS += $$PWD/qtscriptglobal.h \ $$PWD/qscriptengine_p.h \ $$PWD/qscriptvalue.h \ $$PWD/qscriptvalue_p.h \ + $$PWD/qscriptvalueiterator.h \ + $$PWD/qscriptvalueiterator_p.h \ $$PWD/qscriptconverter_p.h \ $$PWD/qscriptstring.h \ $$PWD/qscriptstring_p.h \ $$PWD/qscriptprogram.h \ $$PWD/qscriptprogram_p.h \ $$PWD/qscriptsyntaxcheckresult.h \ + $$PWD/qscriptoriginalglobalobject_p.h \ !static: DEFINES += QT_MAKEDLL diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp index 360de29..e3311ed 100644 --- a/JavaScriptCore/qt/api/qscriptengine_p.cpp +++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp @@ -32,32 +32,12 @@ QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine) : q_ptr(const_cast<QScriptEngine*>(engine)) , m_context(JSGlobalContextCreate(0)) , m_exception(0) - , m_arrayConstructor(0) - , m_arrayPrototype(0) + , m_originalGlobalObject(m_context) { - JSObjectRef globalObject = JSContextGetGlobalObject(m_context); - - // Save references to the Array constructor and prototype. - JSRetainPtr<JSStringRef> arrayName(Adopt, JSStringCreateWithUTF8CString("Array")); - JSValueRef arrayConstructor = JSObjectGetProperty(m_context, globalObject, arrayName.get(), /* exception */ 0); - Q_ASSERT(JSValueIsObject(m_context, arrayConstructor)); - m_arrayConstructor = JSValueToObject(m_context, arrayConstructor, /* exception */ 0); - JSValueProtect(m_context, m_arrayConstructor); - - // Note that this is not the [[Prototype]] internal property (which we could - // get via JSObjectGetPrototype), but the Array.prototype, that will be set - // as [[Prototype]] of Array instances. - JSRetainPtr<JSStringRef> prototypeName(Adopt, JSStringCreateWithUTF8CString("prototype")); - JSValueRef arrayPrototype = JSObjectGetProperty(m_context, m_arrayConstructor, prototypeName.get(), /* exception */ 0); - Q_ASSERT(JSValueIsObject(m_context, arrayPrototype)); - m_arrayPrototype = arrayPrototype; - JSValueProtect(m_context, m_arrayPrototype); } QScriptEnginePrivate::~QScriptEnginePrivate() { - JSValueUnprotect(m_context, m_arrayConstructor); - JSValueUnprotect(m_context, m_arrayPrototype); if (m_exception) JSValueUnprotect(m_context, m_exception); JSGlobalContextRelease(m_context); diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h index 401c051..d54cdcc 100644 --- a/JavaScriptCore/qt/api/qscriptengine_p.h +++ b/JavaScriptCore/qt/api/qscriptengine_p.h @@ -22,6 +22,7 @@ #include "qscriptconverter_p.h" #include "qscriptengine.h" +#include "qscriptoriginalglobalobject_p.h" #include "qscriptstring_p.h" #include "qscriptsyntaxcheckresult_p.h" #include "qscriptvalue.h" @@ -79,13 +80,15 @@ public: inline operator JSGlobalContextRef() const; inline bool isArray(JSValueRef value) const; + inline bool isError(JSValueRef value) const; + inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const; + inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const; private: QScriptEngine* q_ptr; JSGlobalContextRef m_context; JSValueRef m_exception; - JSObjectRef m_arrayConstructor; - JSValueRef m_arrayPrototype; + QScriptOriginalGlobalObject m_originalGlobalObject; }; @@ -218,9 +221,24 @@ QScriptEnginePrivate::operator JSGlobalContextRef() const bool QScriptEnginePrivate::isArray(JSValueRef value) const { - // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value - // is an array if it was created with the Array constructor or if it is the Array.prototype. - return JSValueIsInstanceOfConstructor(m_context, value, m_arrayConstructor, /* exception */ 0) || JSValueIsStrictEqual(m_context, value, m_arrayPrototype); + return m_originalGlobalObject.isArray(value); +} + +bool QScriptEnginePrivate::isError(JSValueRef value) const +{ + return m_originalGlobalObject.isError(value); +} + +inline bool QScriptEnginePrivate::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const +{ + // FIXME We need a JSC C API function for this. + return m_originalGlobalObject.objectHasOwnProperty(object, property); +} + +inline QVector<JSStringRef> QScriptEnginePrivate::objectGetOwnPropertyNames(JSObjectRef object) const +{ + // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties. + return m_originalGlobalObject.objectGetOwnPropertyNames(object); } #endif diff --git a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h new file mode 100644 index 0000000..8d080fb --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h @@ -0,0 +1,186 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptoriginalglobalobject_p_h +#define qscriptoriginalglobalobject_p_h + +#include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <QtCore/qvector.h> + +/*! + \internal + This class is a workaround for missing JSC C API functionality. This class keeps all important + properties of an original (default) global object, so we can use it even if the global object was + changed. + + FIXME this class is a container for workarounds :-) it should be replaced by proper JSC C API calls. + + The class have to be created on the QScriptEnginePrivate creation time (before any change got applied to + global object). +*/ +class QScriptOriginalGlobalObject { +public: + inline QScriptOriginalGlobalObject(JSGlobalContextRef context); + inline ~QScriptOriginalGlobalObject(); + + inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const; + inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const; + + inline bool isArray(JSValueRef value) const; + inline bool isError(JSValueRef value) const; +private: + inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const; + inline void initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype); + + // Copy of the global context reference (the same as in QScriptEnginePrivate). + JSGlobalContextRef m_context; + + // Copy of constructors and prototypes used in isType functions. + JSObjectRef m_arrayConstructor; + JSValueRef m_arrayPrototype; + JSObjectRef m_errorConstructor; + JSValueRef m_errorPrototype; + + // Reference to standard JS functions that are not exposed by JSC C API. + JSObjectRef m_hasOwnPropertyFunction; + JSObjectRef m_getOwnPropertyNamesFunction; +}; + +QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef context) + : m_context(JSGlobalContextRetain(context)) +{ + JSObjectRef globalObject = JSContextGetGlobalObject(m_context); + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> propertyName; + + propertyName.adopt(JSStringCreateWithUTF8CString("prototype")); + initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype); + initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype); + + propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty")); + m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception)); + JSValueProtect(m_context, m_hasOwnPropertyFunction); + Q_ASSERT(JSValueIsObject(m_context, m_hasOwnPropertyFunction)); + Q_ASSERT(JSObjectIsFunction(m_context, m_hasOwnPropertyFunction)); + Q_ASSERT(!exception); + + propertyName.adopt(JSStringCreateWithUTF8CString("Object")); + JSObjectRef objectConstructor + = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception)); + propertyName.adopt(JSStringCreateWithUTF8CString("getOwnPropertyNames")); + m_getOwnPropertyNamesFunction + = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, objectConstructor, propertyName.get(), &exception)); + JSValueProtect(m_context, m_getOwnPropertyNamesFunction); + Q_ASSERT(JSValueIsObject(m_context, m_getOwnPropertyNamesFunction)); + Q_ASSERT(JSObjectIsFunction(m_context, m_getOwnPropertyNamesFunction)); + Q_ASSERT(!exception); +} + +inline void QScriptOriginalGlobalObject::initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype) +{ + JSRetainPtr<JSStringRef> typeName(Adopt, JSStringCreateWithUTF8CString(type)); + JSValueRef exception = 0; + + // Save references to the Type constructor and prototype. + JSValueRef typeConstructor = JSObjectGetProperty(m_context, globalObject, typeName.get(), &exception); + Q_ASSERT(JSValueIsObject(m_context, typeConstructor)); + constructor = JSValueToObject(m_context, typeConstructor, &exception); + JSValueProtect(m_context, constructor); + + // Note that this is not the [[Prototype]] internal property (which we could + // get via JSObjectGetPrototype), but the Type.prototype, that will be set + // as [[Prototype]] of Type instances. + prototype = JSObjectGetProperty(m_context, constructor, prototypeName, &exception); + Q_ASSERT(JSValueIsObject(m_context, prototype)); + JSValueProtect(m_context, prototype); + Q_ASSERT(!exception); +} + +QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject() +{ + JSValueUnprotect(m_context, m_arrayConstructor); + JSValueUnprotect(m_context, m_arrayPrototype); + JSValueUnprotect(m_context, m_errorConstructor); + JSValueUnprotect(m_context, m_errorPrototype); + JSValueUnprotect(m_context, m_hasOwnPropertyFunction); + JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction); + JSGlobalContextRelease(m_context); +} + +inline bool QScriptOriginalGlobalObject::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const +{ + // FIXME This function should be replaced by JSC C API. + JSValueRef exception = 0; + JSValueRef propertyName[] = { JSValueMakeString(m_context, property) }; + JSValueRef result = JSObjectCallAsFunction(m_context, m_hasOwnPropertyFunction, object, 1, propertyName, &exception); + return exception ? false : JSValueToBoolean(m_context, result); +} + +/*! + \internal + This method gives ownership of all JSStringRefs. +*/ +inline QVector<JSStringRef> QScriptOriginalGlobalObject::objectGetOwnPropertyNames(JSObjectRef object) const +{ + JSValueRef exception = 0; + JSObjectRef propertyNames + = const_cast<JSObjectRef>(JSObjectCallAsFunction(m_context, + m_getOwnPropertyNamesFunction, + /* thisObject */ 0, + /* argumentCount */ 1, + &object, + &exception)); + Q_ASSERT(JSValueIsObject(m_context, propertyNames)); + Q_ASSERT(!exception); + JSStringRef lengthName = QScriptConverter::toString("length"); + int count = JSValueToNumber(m_context, JSObjectGetProperty(m_context, propertyNames, lengthName, &exception), &exception); + + Q_ASSERT(!exception); + QVector<JSStringRef> names; + names.reserve(count); + for (int i = 0; i < count; ++i) { + JSValueRef tmp = JSObjectGetPropertyAtIndex(m_context, propertyNames, i, &exception); + names.append(JSValueToStringCopy(m_context, tmp, &exception)); + Q_ASSERT(!exception); + } + return names; +} + +inline bool QScriptOriginalGlobalObject::isArray(JSValueRef value) const +{ + return isType(value, m_arrayConstructor, m_arrayPrototype); +} + +inline bool QScriptOriginalGlobalObject::isError(JSValueRef value) const +{ + return isType(value, m_errorConstructor, m_errorPrototype); +} + +inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const +{ + // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value + // is an object of the Type if it was created with the Type constructor or if it is the Type.prototype. + JSValueRef exception = 0; + bool result = JSValueIsInstanceOfConstructor(m_context, value, constructor, &exception) || JSValueIsStrictEqual(m_context, value, prototype); + Q_ASSERT(!exception); + return result; +} + +#endif // qscriptoriginalglobalobject_p_h diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h index 1d319ba..6e93a07 100644 --- a/JavaScriptCore/qt/api/qscriptvalue_p.h +++ b/JavaScriptCore/qt/api/qscriptvalue_p.h @@ -184,7 +184,6 @@ private: Value(QString* string) : m_string(string) {} } u; - inline bool inherits(const char*); inline State refinedJSValue(); inline bool isJSBased() const; @@ -416,7 +415,7 @@ bool QScriptValuePrivate::isError() return false; // Fall-through. case JSObject: - return inherits("Error"); + return m_engine->isError(*this); default: return false; } @@ -868,13 +867,7 @@ inline bool QScriptValuePrivate::hasOwnProperty(quint32 property) inline bool QScriptValuePrivate::hasOwnProperty(JSStringRef property) { Q_ASSERT(isObject()); - // FIXME it could be faster, but JSC C API doesn't expose needed functionality. - JSRetainPtr<JSStringRef> hasOwnPropertyName(Adopt, JSStringCreateWithUTF8CString("hasOwnProperty")); - JSValueRef exception = 0; - JSValueRef hasOwnProperty = JSObjectGetProperty(*m_engine, *this, hasOwnPropertyName.get(), &exception); - JSValueRef propertyName[] = { JSValueMakeString(*m_engine, property) }; - JSValueRef result = JSObjectCallAsFunction(*m_engine, const_cast<JSObjectRef>(hasOwnProperty), *this, 1, propertyName, &exception); - return exception ? false : JSValueToBoolean(*m_engine, result); + return m_engine->objectHasOwnProperty(*this, property); } /*! @@ -1124,24 +1117,6 @@ QScriptValuePrivate::operator JSObjectRef() const /*! \internal - Returns true if QSV is created from constructor with the given \a name, it has to be a - built-in type. -*/ -bool QScriptValuePrivate::inherits(const char* name) -{ - Q_ASSERT(isJSBased()); - JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine); - JSStringRef errorAttrName = QScriptConverter::toString(name); - JSValueRef exception = 0; - JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, &exception); - JSStringRelease(errorAttrName); - bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, &exception), &exception); - m_engine->setException(exception); - return result; -} - -/*! - \internal Refines the state of this QScriptValuePrivate. Returns the new state. */ QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue() diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator.cpp b/JavaScriptCore/qt/api/qscriptvalueiterator.cpp new file mode 100644 index 0000000..f1caa61 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalueiterator.cpp @@ -0,0 +1,226 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptvalueiterator.h" + +#include "qscriptvalue_p.h" +#include "qscriptvalueiterator_p.h" + +/*! + \class QScriptValueIterator + + \brief The QScriptValueIterator class provides a Java-style iterator for QScriptValue. + + \ingroup script + + + The QScriptValueIterator constructor takes a QScriptValue as + argument. After construction, the iterator is located at the very + beginning of the sequence of properties. Here's how to iterate over + all the properties of a QScriptValue: + + \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 0 + + The next() advances the iterator. The name(), value() and flags() + functions return the name, value and flags of the last item that was + jumped over. + + If you want to remove properties as you iterate over the + QScriptValue, use remove(). If you want to modify the value of a + property, use setValue(). + + Note that QScriptValueIterator only iterates over the QScriptValue's + own properties; i.e. it does not follow the prototype chain. You can + use a loop like this to follow the prototype chain: + + \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 1 + + Note that QScriptValueIterator will not automatically skip over + properties that have the QScriptValue::SkipInEnumeration flag set; + that flag only affects iteration in script code. If you want, you + can skip over such properties with code like the following: + + \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 2 + + \sa QScriptValue::property() +*/ + +/*! + Constructs an iterator for traversing \a object. The iterator is + set to be at the front of the sequence of properties (before the + first property). +*/ +QScriptValueIterator::QScriptValueIterator(const QScriptValue& object) + : d_ptr(new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object))) +{} + +/*! + Destroys the iterator. +*/ +QScriptValueIterator::~QScriptValueIterator() +{} + +/*! + Returns true if there is at least one item ahead of the iterator + (i.e. the iterator is \e not at the back of the property sequence); + otherwise returns false. + + \sa next(), hasPrevious() +*/ +bool QScriptValueIterator::hasNext() const +{ + return d_ptr->hasNext(); +} + +/*! + Advances the iterator by one position. + + Calling this function on an iterator located at the back of the + container leads to undefined results. + + \sa hasNext(), previous(), name() +*/ +void QScriptValueIterator::next() +{ + d_ptr->next(); +} + +/*! + Returns true if there is at least one item behind the iterator + (i.e. the iterator is \e not at the front of the property sequence); + otherwise returns false. + + \sa previous(), hasNext() +*/ +bool QScriptValueIterator::hasPrevious() const +{ + return d_ptr->hasPrevious(); +} + +/*! + Moves the iterator back by one position. + + Calling this function on an iterator located at the front of the + container leads to undefined results. + + \sa hasPrevious(), next(), name() +*/ +void QScriptValueIterator::previous() +{ + d_ptr->previous(); +} + +/*! + Moves the iterator to the front of the QScriptValue (before the + first property). + + \sa toBack(), next() +*/ +void QScriptValueIterator::toFront() +{ + d_ptr->toFront(); +} + +/*! + Moves the iterator to the back of the QScriptValue (after the + last property). + + \sa toFront(), previous() +*/ +void QScriptValueIterator::toBack() +{ + d_ptr->toBack(); +} + +/*! + Returns the name of the last property that was jumped over using + next() or previous(). + + \sa value(), flags() +*/ +QString QScriptValueIterator::name() const +{ + return d_ptr->name(); +} + +/*! + Returns the name of the last property that was jumped over using + next() or previous(). +*/ +QScriptString QScriptValueIterator::scriptName() const +{ + return QScriptStringPrivate::get(d_ptr->scriptName()); +} + +/*! + Returns the value of the last property that was jumped over using + next() or previous(). + + \sa setValue(), name() +*/ +QScriptValue QScriptValueIterator::value() const +{ + return QScriptValuePrivate::get(d_ptr->value()); +} + +/*! + Sets the \a value of the last property that was jumped over using + next() or previous(). + + \sa value(), name() +*/ +void QScriptValueIterator::setValue(const QScriptValue& value) +{ + d_ptr->setValue(QScriptValuePrivate::get(value)); +} + +/*! + Removes the last property that was jumped over using next() + or previous(). + + \sa setValue() +*/ +void QScriptValueIterator::remove() +{ + d_ptr->remove(); +} + +/*! + Returns the flags of the last property that was jumped over using + next() or previous(). + + \sa value() +*/ +QScriptValue::PropertyFlags QScriptValueIterator::flags() const +{ + return d_ptr->flags(); +} + +/*! + Makes the iterator operate on \a object. The iterator is set to be + at the front of the sequence of properties (before the first + property). +*/ +QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue& object) +{ + d_ptr = new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object)); + return *this; +} diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator.h b/JavaScriptCore/qt/api/qscriptvalueiterator.h new file mode 100644 index 0000000..0c90661 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalueiterator.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalueiterator_h +#define qscriptvalueiterator_h + +#include "qtscriptglobal.h" +#include "qscriptstring.h" +#include <QtCore/qshareddata.h> +#include "qscriptvalue.h" + +class QScriptValue; +class QScriptValueIteratorPrivate; + + +class Q_JAVASCRIPT_EXPORT QScriptValueIterator { +public: + QScriptValueIterator(const QScriptValue& value); + ~QScriptValueIterator(); + + bool hasNext() const; + void next(); + + bool hasPrevious() const; + void previous(); + + QString name() const; + QScriptString scriptName() const; + + QScriptValue value() const; + void setValue(const QScriptValue& value); + + void remove(); + QScriptValue::PropertyFlags flags() const; + + void toFront(); + void toBack(); + + QScriptValueIterator& operator=(QScriptValue& value); +private: + QExplicitlySharedDataPointer<QScriptValueIteratorPrivate> d_ptr; + + Q_DECLARE_PRIVATE(QScriptValueIterator) + Q_DISABLE_COPY(QScriptValueIterator) +}; + +#endif // qscriptvalueiterator_h diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator_p.h b/JavaScriptCore/qt/api/qscriptvalueiterator_p.h new file mode 100644 index 0000000..b93b518 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalueiterator_p.h @@ -0,0 +1,172 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalueiterator_p_h +#define qscriptvalueiterator_p_h + +#include "qscriptvalue_p.h" +#include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qvector.h> + +class QScriptValueIteratorPrivate: public QSharedData { +public: + inline QScriptValueIteratorPrivate(const QScriptValuePrivate* value); + inline ~QScriptValueIteratorPrivate(); + + inline bool hasNext(); + inline void next(); + + inline bool hasPrevious(); + inline void previous(); + + inline QString name() const; + inline QScriptStringPrivate* scriptName() const; + + inline QScriptValuePrivate* value() const; + inline void setValue(const QScriptValuePrivate* value); + + inline void remove(); + + inline void toFront(); + inline void toBack(); + + QScriptValue::PropertyFlags flags() const; + + inline bool isValid() const; +private: + inline QScriptEnginePrivate* engine() const; + + QExplicitlySharedDataPointer<QScriptValuePrivate> m_object; + QVector<JSStringRef> m_names; + QMutableVectorIterator<JSStringRef> m_idx; +}; + +inline QScriptValueIteratorPrivate::QScriptValueIteratorPrivate(const QScriptValuePrivate* value) + : m_object(const_cast<QScriptValuePrivate*>(value)) + , m_idx(m_names) +{ + if (m_object->isObject()) { + m_names = engine()->objectGetOwnPropertyNames(*m_object); + m_idx = m_names; + } else + m_object = 0; +} + +inline QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate() +{ + QVector<JSStringRef>::const_iterator i = m_names.constBegin(); + for (; i != m_names.constEnd(); ++i) + JSStringRelease(*i); +} + +inline bool QScriptValueIteratorPrivate::hasNext() +{ + return m_idx.hasNext(); +} + +inline void QScriptValueIteratorPrivate::next() +{ + // FIXME (Qt5) This method should return a value (QTBUG-11226). + m_idx.next(); +} + +inline bool QScriptValueIteratorPrivate::hasPrevious() +{ + return m_idx.hasPrevious(); +} + +inline void QScriptValueIteratorPrivate::previous() +{ + m_idx.previous(); +} + +inline QString QScriptValueIteratorPrivate::name() const +{ + if (!isValid()) + return QString(); + return QScriptConverter::toString(m_idx.value()); +} + +inline QScriptStringPrivate* QScriptValueIteratorPrivate::scriptName() const +{ + if (!isValid()) + return new QScriptStringPrivate(); + return new QScriptStringPrivate(QScriptConverter::toString(m_idx.value())); +} + +inline QScriptValuePrivate* QScriptValueIteratorPrivate::value() const +{ + if (!isValid()) + return new QScriptValuePrivate(); + JSValueRef exception = 0; + JSValueRef value = m_object->property(m_idx.value(), &exception); + engine()->setException(exception); + return new QScriptValuePrivate(engine(), value); +} + +inline void QScriptValueIteratorPrivate::setValue(const QScriptValuePrivate* value) +{ + if (!isValid()) + return; + JSValueRef exception = 0; + m_object->setProperty(m_idx.value(), *value, /* flags */ 0, &exception); + engine()->setException(exception); +} + +inline void QScriptValueIteratorPrivate::remove() +{ + if (!isValid()) + return; + JSValueRef exception = 0; + m_object->deleteProperty(m_idx.value(), &exception); + engine()->setException(exception); + m_idx.remove(); +} + +inline void QScriptValueIteratorPrivate::toFront() +{ + m_idx.toFront(); +} + +inline void QScriptValueIteratorPrivate::toBack() +{ + m_idx.toBack(); +} + +QScriptValue::PropertyFlags QScriptValueIteratorPrivate::flags() const +{ + if (!isValid()) + return QScriptValue::PropertyFlags(0); + return m_object->propertyFlags(m_idx.value(), QScriptValue::ResolveLocal); +} + +inline bool QScriptValueIteratorPrivate::isValid() const +{ + return m_object; +} + +inline QScriptEnginePrivate* QScriptValueIteratorPrivate::engine() const +{ + Q_ASSERT(isValid()); + return m_object->engine(); +} + +#endif // qscriptvalueiterator_p_h |