diff options
Diffstat (limited to 'src/declarative/qml/v8')
-rw-r--r-- | src/declarative/qml/v8/qv8sequencewrapper.cpp | 21 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8sequencewrapper_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8sequencewrapper_p_p.h | 67 |
3 files changed, 87 insertions, 3 deletions
diff --git a/src/declarative/qml/v8/qv8sequencewrapper.cpp b/src/declarative/qml/v8/qv8sequencewrapper.cpp index f63b5da4ea..267e8ec4e6 100644 --- a/src/declarative/qml/v8/qv8sequencewrapper.cpp +++ b/src/declarative/qml/v8/qv8sequencewrapper.cpp @@ -66,10 +66,10 @@ void QV8SequenceWrapper::init(QV8Engine *engine) m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction()); v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter, 0, 0, IndexedEnumerator); - ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, 0, + ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter, 0, IndexedDeleter, IndexedEnumerator); + ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, LengthSetter, v8::Handle<v8::Value>(), v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum)); + v8::PropertyAttribute(v8::DontDelete | v8::DontEnum)); ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, m_toString, v8::DEFAULT, v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum)); @@ -184,6 +184,13 @@ v8::Handle<v8::Value> QV8SequenceWrapper::IndexedGetter(quint32 index, const v8: return sr->indexedGetter(index); } +v8::Handle<v8::Boolean> QV8SequenceWrapper::IndexedDeleter(quint32 index, const v8::AccessorInfo &info) +{ + QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); + Q_ASSERT(sr); + return sr->indexedDeleter(index); +} + v8::Handle<v8::Array> QV8SequenceWrapper::IndexedEnumerator(const v8::AccessorInfo &info) { QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); @@ -199,6 +206,14 @@ v8::Handle<v8::Value> QV8SequenceWrapper::LengthGetter(v8::Local<v8::String> pro return v8::Integer::NewFromUnsigned(sr->lengthGetter()); } +void QV8SequenceWrapper::LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info) +{ + Q_UNUSED(property); + QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); + Q_ASSERT(sr); + sr->lengthSetter(value); +} + v8::Handle<v8::Value> QV8SequenceWrapper::ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info) { Q_UNUSED(property); diff --git a/src/declarative/qml/v8/qv8sequencewrapper_p.h b/src/declarative/qml/v8/qv8sequencewrapper_p.h index da0f7eacca..0ddeed9eda 100644 --- a/src/declarative/qml/v8/qv8sequencewrapper_p.h +++ b/src/declarative/qml/v8/qv8sequencewrapper_p.h @@ -88,8 +88,10 @@ private: static v8::Handle<v8::Value> IndexedGetter(quint32 index, const v8::AccessorInfo &info); static v8::Handle<v8::Value> IndexedSetter(quint32 index, v8::Local<v8::Value> value, const v8::AccessorInfo &info); + static v8::Handle<v8::Boolean> IndexedDeleter(quint32 index, const v8::AccessorInfo &info); static v8::Handle<v8::Array> IndexedEnumerator(const v8::AccessorInfo &info); static v8::Handle<v8::Value> LengthGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info); + static void LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info); static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info); static v8::Handle<v8::Value> ToString(const v8::Arguments &args); static v8::Handle<v8::Value> ValueOfGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info); diff --git a/src/declarative/qml/v8/qv8sequencewrapper_p_p.h b/src/declarative/qml/v8/qv8sequencewrapper_p_p.h index eea595ed6b..a947d52013 100644 --- a/src/declarative/qml/v8/qv8sequencewrapper_p_p.h +++ b/src/declarative/qml/v8/qv8sequencewrapper_p_p.h @@ -82,8 +82,10 @@ public: virtual bool isEqual(const QV8SequenceResource *v) = 0; virtual quint32 lengthGetter() = 0; + virtual void lengthSetter(v8::Handle<v8::Value> value) = 0; virtual v8::Handle<v8::Value> indexedSetter(quint32 index, v8::Handle<v8::Value> value) = 0; virtual v8::Handle<v8::Value> indexedGetter(quint32 index) = 0; + virtual v8::Handle<v8::Boolean> indexedDeleter(quint32 index) = 0; virtual v8::Handle<v8::Array> indexedEnumerator() = 0; virtual v8::Handle<v8::Value> toString() = 0; @@ -286,6 +288,48 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v) } \ return c.count(); \ } \ + void lengthSetter(v8::Handle<v8::Value> value) \ + { \ + /* Get the new required length */ \ + if (value.IsEmpty() || !value->IsUint32()) \ + return; \ + quint32 newLength = value->Uint32Value(); \ + /* Read the sequence from the QObject property if we're a reference */ \ + if (objectType == QV8SequenceResource::Reference) { \ + if (!object) \ + return; \ + void *a[] = { &c, 0 }; \ + QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \ + } \ + /* Determine whether we need to modify the sequence */ \ + quint32 count = c.count(); \ + if (newLength == count) { \ + return; \ + } else if (newLength > count) { \ + /* according to ECMA262r3 we need to insert */ \ + /* undefined values increasing length to newLength. */ \ + /* We cannot, so we insert default-values instead. */ \ + while (newLength > count++) { \ + c.append(DefaultValue); \ + } \ + } else { \ + /* according to ECMA262r3 we need to remove */ \ + /* elements until the sequence is the required length. */ \ + while (newLength < count) { \ + count--; \ + c.removeAt(count); \ + } \ + } \ + /* write back if required. */ \ + if (objectType == QV8SequenceResource::Reference) { \ + /* write back. already checked that object is non-null, so skip that check here. */ \ + int status = -1; \ + QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::DontRemoveBinding; \ + void *a[] = { &c, 0, &status, &flags }; \ + QMetaObject::metacall(object, QMetaObject::WriteProperty, propertyIndex, a); \ + } \ + return; \ + } \ v8::Handle<v8::Value> indexedSetter(quint32 index, v8::Handle<v8::Value> value) \ { \ if (objectType == QV8SequenceResource::Reference) { \ @@ -331,6 +375,29 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v) return ConversionToV8fn(engine, c.at(index)); \ return v8::Undefined(); \ } \ + v8::Handle<v8::Boolean> indexedDeleter(quint32 index) \ + { \ + if (objectType == QV8SequenceResource::Reference) { \ + if (!object) \ + return v8::Boolean::New(false); \ + void *a[] = { &c, 0 }; \ + QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \ + } \ + if (index < c.count()) { \ + /* according to ECMA262r3 it should be Undefined, */ \ + /* but we cannot, so we insert a default-value instead. */ \ + c.replace(index, DefaultValue); \ + if (objectType == QV8SequenceResource::Reference) { \ + /* write back. already checked that object is non-null, so skip that check here. */ \ + int status = -1; \ + QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::DontRemoveBinding; \ + void *a[] = { &c, 0, &status, &flags }; \ + QMetaObject::metacall(object, QMetaObject::WriteProperty, propertyIndex, a); \ + } \ + return v8::Boolean::New(true); \ + } \ + return v8::Boolean::New(false); \ + } \ v8::Handle<v8::Array> indexedEnumerator() \ { \ if (objectType == QV8SequenceResource::Reference) { \ |